Route middleware
A middleware is defined in a _middleware.ts file. It will intercept the
request in order for you to perform custom logic before or after the route
handler. This allows modifying or checking requests and responses. Common
use-cases for this are logging, authentication, and performance monitoring.
Each middleware gets passed a next function in the context argument that is
used trigger child handlers. The ctx also has a state property that can be
used to pass arbituary data to downstream (or upstream) handlers.
// routes/_middleware.ts
import { MiddlewareHandlerContext } from "../server_deps.ts";
interface State {
data: string;
}
export async function handler(
req: Request,
ctx: MiddlewareHandlerContext<State>,
) {
ctx.state.data = "myData";
const resp = await ctx.next();
resp.headers.set("server", "fresh server");
return resp;
}// routes/myHandler.ts
export const handler: Handlers<any, { data: string }> = {
GET(_req, ctx) {
return new Response(`middleware data is ${ctx.state.data}`);
},
};Middlewares are scoped and can be layered. This means a project can have multiple middlewares, each covering a different set of routes. If multiple middlewares cover a route, they will all be run, in order of specificity (least specific first).
For example, take a project with the following routes:
routes/_middlware.tsroutes/index.tsroutes/admin/_middleware.tsroutes/admin/index.tsroutes/admin/signin.ts
For a request to / the request will flow like this:
- The
routes/_middlware.tsmiddlware is invoked. - Calling
ctx.next()will invoke theroutes/index.tshandler.
For a request to /admin the request flow like this:
- The
routes/_middlware.tsmiddlware is invoked. - Calling
ctx.next()will invoke theroutes/admin/_middleware.tsmiddlware. - Calling
ctx.next()will invoke theroutes/admin/index.tshandler.
For a request to /admin/signin the request flow like this:
- The
routes/_middlware.tsmiddlware is invoked. - Calling
ctx.next()will invoke theroutes/admin/_middleware.tsmiddlware. - Calling
ctx.next()will invoke theroutes/admin/signin.tshandler.