Run Code Before Every Request
Middleware
`src/middleware.ts` exports an `onRequest` that runs before every page or endpoint. Useful for auth, logging, and request shaping.
What you'll learn
- Author a middleware
- Read/modify locals
- Short-circuit with a custom response
src/middleware.ts defines a function that runs before every
page or endpoint render. Perfect for authentication, logging, and
adding shared data to Astro.locals.
The Shape
// src/middleware.ts
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async (context, next) => {
// before request
console.log("→", context.request.method, context.url.pathname);
const response = await next();
// after request
response.headers.set("x-powered-by", "astro");
return response;
}); context is the same context pages get — request, url,
cookies, locals, etc. next() invokes the matched route and
returns its Response.
Auth Middleware Example
export const onRequest = defineMiddleware(async ({ url, cookies, locals }, next) => {
const session = cookies.get("session")?.value;
const user = session ? await getUser(session) : null;
// make user available everywhere via Astro.locals
locals.user = user;
// protect routes under /dashboard
if (url.pathname.startsWith("/dashboard") && !user) {
return new Response(null, { status: 302, headers: { Location: "/login" } });
}
return next();
}); In any page:
---
const user = Astro.locals.user; // typed if you augmented Astro.Locals
---
<p>Signed in as {user?.email ?? "guest"}.</p> Typing Astro.locals
Augment the global types so Astro.locals.user is typed:
// src/env.d.ts
declare namespace App {
interface Locals {
user?: { id: string; email: string } | null;
}
} Chaining Multiple Middlewares
Export sequence for ordered composition:
import { defineMiddleware, sequence } from "astro:middleware";
const logger = defineMiddleware(async (ctx, next) => { /* ... */ });
const auth = defineMiddleware(async (ctx, next) => { /* ... */ });
export const onRequest = sequence(logger, auth); Each middleware can short-circuit by returning a response without
calling next().
Up Next
Reading and writing cookies / sessions.
Cookies →