Middleware pipeline
Apply access checks, redirects, rewrites, and cancellation in the core transition pipeline.
Middleware runs before a navigation commits. It can allow, redirect, rewrite, cancel, or return a Response.
Use middleware when the decision belongs to the transition, not to view rendering.
Register middleware when creating the router
import {
createRouter,
defineRoutes,
type Middleware,
} from '@cookbook/router';
const routes = defineRoutes([
{
id: 'home',
path: '/',
view: 'home',
},
{
id: 'admin',
path: '/admin',
meta: {
requiresAuth: true,
},
view: 'admin',
},
] as const);
const requireAuth: Middleware = (context) => {
if (
context.route.route.meta?.requiresAuth === true &&
!session.isSignedIn()
) {
return context.redirect('/login');
}
};
const router = createRouter({
routes,
middleware: [requireAuth],
});
await router.start();The transition does not commit to /admin when the middleware redirects to /login.
Add runtime middleware
Use router.useMiddleware() when middleware is owned by runtime setup rather than router creation.
const removeAuditMiddleware = router.useMiddleware([
(context) => {
analytics.track('route_attempt', {
href: context.location.href,
routeId: context.route.id,
});
},
]);
removeAuditMiddleware();The cleanup removes the registered middleware.
Redirect, rewrite, and cancel
const canonicalize: Middleware = (context) => {
if (context.location.pathname === '/docs/latest') {
return context.rewrite('/docs/current');
}
};
const blockCheckout: Middleware = (context) => {
if (
context.route.id === 'checkout' &&
cart.isEmpty()
) {
return context.cancel();
}
};A redirect changes the destination and writes the redirected URL. A rewrite resolves another route without committing the original URL. Cancellation keeps the previous committed state.
Return a Response
const requireApiSession: Middleware = () => {
if (!session.isSignedIn()) {
return new Response('Unauthorized', {
status: 401,
});
}
};The host decides how to map response-like middleware results to transport.
Where this bites
Middleware is not component rendering
Do not wait until a view renders to enforce a route transition policy. The route may already be committed by then.
Provider middleware after startup is late
When a framework adapter registers middleware after the router starts, it only affects future navigations. Core setup can register middleware before router.start().
Rewrite targets must be internal
Middleware cannot rewrite to an external URL. Use redirect semantics for external destinations, and make sure the active history implementation supports external redirects.