Middleware
Run code before a request completes — for redirects, authentication checks, and header rewrites — using middleware.ts.
What Is Middleware?
Middleware runs on every matching request, before it reaches a route's page or Route Handler. It sits between the incoming request and your application code, and can redirect, rewrite, or modify the request or response before your route ever runs.
Creating Middleware
Middleware lives in a single middleware.ts file at the project root (or inside src/, if you used that option).
// middleware.tsimport { NextResponse } from 'next/server';
export function middleware(request) { const isLoggedIn = request.cookies.has('session');
if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); }
return NextResponse.next();}The matcher Config
By default, middleware runs on every request. Export a config with a matcher to limit it to specific paths, avoiding unnecessary work on routes that don't need it.
export const config = { matcher: ['/dashboard/:path*', '/account/:path*'],};Middleware runs on the Edge Runtime, a lighter, faster execution environment than a full Node.js server — it does not support every Node.js API, so keep logic focused on things like cookies, headers, and redirects rather than heavy computation or direct database calls.
Common Use Cases
Authentication Gates
Redirect unauthenticated visitors away from protected routes before the page even renders.
Geolocation / A-B Routing
Rewrite requests to a locale-specific or experiment-specific path based on request headers.
Logging & Headers
Attach custom headers or logging metadata to every request passing through.
Rate Limiting Checks
Reject requests early, before they reach more expensive route logic.
Common Beginner Mistakes
Middleware runs on every matched request, on the Edge Runtime — keep it to lightweight checks like the presence of a token, and verify the token's full validity in the actual route.
Without explicitly returning next() (or a redirect/rewrite), the request may not proceed as expected — always return a response from the middleware function.
FAQs
No — there is exactly one middleware.ts per project, at the root; use the matcher config and conditional logic inside it to handle different sections differently.
By default it can — this is exactly why the matcher config exists, to exclude paths like /_next/static or images that don't need middleware logic.
Summary
Middleware gives you a single, request-level checkpoint for redirects, lightweight auth checks, and header manipulation. With data and actions covered, the next section moves into optimizing assets — starting with images.