Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/neurosnap/remix-middleware
express-like middleware system for your remix loaders and actions
https://github.com/neurosnap/remix-middleware
remix remix-run
Last synced: 2 months ago
JSON representation
express-like middleware system for your remix loaders and actions
- Host: GitHub
- URL: https://github.com/neurosnap/remix-middleware
- Owner: neurosnap
- Created: 2022-01-20T02:50:08.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2022-02-13T21:02:04.000Z (almost 3 years ago)
- Last Synced: 2024-11-02T03:23:16.869Z (2 months ago)
- Topics: remix, remix-run
- Language: TypeScript
- Homepage:
- Size: 52.7 KB
- Stars: 37
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-remix - remix-middleware - An express-like middleware system for remix loaders and actions. (Utility)
- Awesome-Remix - remix-middleware - like middleware system for your remix loaders and actions` (miscellaneous)
- awesome-remix - remix-middleware - An express-like middleware system for remix loaders and actions. (Utility)
README
# remix-middleware
Add an express-like middleware stack to your remix loaders and actions!
```bash
yarn add remix-middleware
``````ts
// ./app/middleware.server.ts
export const mdw = createMiddleware();mdw.use(async (ctx, next) => {
console.log("middleware activated for", ctx.request.url);
await next();
console.log("middleware completed for", ctx.request.url);
});mdw.use(mdw.routes());
``````tsx
// ./app/routes/posts/index.tsx
import { ActionFunction, LoaderFunction, Form, useLoaderData } from "remix";import { mdw } from "~/middleware.server";
interface Post {
id: string;
title: string;
}export const loader: LoaderFunction = (props) =>
mdw.run(props, (ctx) => {
// ctx.response is where the response object goes
ctx.response = [
{
id: "1",
title: "My First Post",
},
{
id: "2",
title: "A Mixtape I Made Just For You",
},
];
});export const action: ActionFunction = (props) =>
mdw.run(props, async (ctx) => {
const body = await ctx.request.formData();
const post = { id: "3", title: body.get("title") };
ctx.response = post;
});export default function Posts() {
const posts = useLoaderData();
return (
Posts
{posts.map((post) => (
{post.title}
))}
Title:
Create
);
}
```Just have simple JSON that you are returning in a loader like in the example
above?```tsx
export const loader: LoaderFunction = (props) =>
mdw.run(
props,
mdw.response([
{
id: "1",
title: "My First Post",
},
{
id: "2",
title: "A Mixtape I Made Just For You",
},
])
);
```## remix-auth
We built a middleware that will help interacting with [remix-auth](https://github.com/sergiodxa/remix-auth)
more streamlined.- isAuthenticated - activates `authenticator.isAuthenticated`
Setting up `remix-auth`
```tsx
// ./app/user.ts
export interface User {
id: string;
email: string;
}
``````ts
// ./app/authenticator.ts
import { Authenticator } from 'remix-auth';
import { sessionStorage } from "./session";
import type { User } from './user';export const authenticator = new Authenticator(sessionStorage);
```Create middleware for your needs
```ts
// ./app/middleware.server.ts
import { createMiddleware, AuthCtx, isAuthenticated } from 'remix-middleware';
import { authenticator } from './authenticator';
import type { User } from './user';// use this middleware for routes that do *not* require authentication
// but you want the user to automatically redirect somewhere
export const unauthed = createMiddleware>();
unauthed.use(isAuthenticated(authenticator, { successRedirect: '/dashboard' }));
unauthed.use(unauthed.routes());// use this middleware for routes that *require* authentication
export const authed = createMiddleware>();
authed.use(isAuthenticated(authenticator, { failureRedirect: '/login' }));
authed.use(authed.routes());// use this middleware if the route allows both authenticated and
// non-authenticated users
export const mdw = createMiddleware>();
mdw.use(isAuthenticated(authenticator));
mdw.use(async (ctx, next) => {
if (ctx.user) {
// ... do something with the user
} else {
// ... do something with a non-user
}
await next();
});
```Now in your routes that require authentication
```ts
// in a route that requires auth
import { authed } from '~/middleware.server';export const loader: LoaderFunction = (props) =>
authed.run(props, (ctx) => {
// no user can make it to this point without being authenticated
// and as a result we now have access to ctx.user which is `User`
// in this example
console.log(ctx.user); // { id: '123', email: '[email protected]' }ctx.response = { text: `Hi ${ctx.user.email}!` };
});
```Now in your routes that do *not* require authentication
```ts
// in a route that does *not* require auth
import { unauthed } from '~/middleware.server';// `.run()` doesn't need any middleware, it'll run without it
export const loader = (props) => unauthed.run(props);
```