Middleware And Proxy Patterns
Shape requests early with middleware for auth, redirects, rewrites, and geolocation routing.
Request Gatekeeping
Middleware intercepts requests before they reach routes. Use for authentication redirects, A/B test bucketing, bot detection, and maintenance mode toggles. Return NextResponse.next() to continue, redirect(), rewrite(), or new Response to block.
Runs in Edge Runtime by default — limited Node.js API surface. Avoid heavy computation; target sub-10ms execution for matched routes.
- Runs before route handlers
- Edge Runtime constraints
- Keep execution fast
export function middleware(request) {
const country = request.geo?.country;
if (country === 'DE') {
return NextResponse.rewrite(new URL('/de' + request.nextUrl.pathname, request.url));
}
return NextResponse.next();
}Rewrites and Redirects
NextResponse.rewrite serves different internal path while URL stays same — locale prefixes, legacy URL compatibility. redirect sends 307/308 to new URL — use for canonical URL enforcement and HTTP→HTTPS.
Configure static redirects in next.config.js for permanent moves known at build time. Middleware redirects for dynamic logic based on cookies, headers, or geolocation.
- rewrite: internal path, same URL
- redirect: client sees new URL
- Static redirects in next.config
Headers and Cookies
Set request headers before passing to routes: `NextResponse.next({ request: { headers: new Headers() } })`. Set response headers on NextResponse for security policies, cache control, and CSP.
Read cookies for session tokens. Set cookies on redirect responses for auth flows. Cookie options: HttpOnly, Secure, SameSite=Strict, Path, Max-Age.
- Modify request/response headers
- Cookie read/write in middleware
- Security flags on auth cookies
Matcher Configuration
Export config.matcher as array of path patterns — exclude static files, _next, and public assets. Over-broad matchers run middleware on every request including images, wasting edge compute.
Negative lookahead regex excludes paths: `'/((?!_next/static|favicon.ico).*)'`. Test matcher against your asset paths in development.
- Exclude static assets from matcher
- Precise patterns save edge compute
- Test matcher coverage
Middleware vs Route Handlers
Middleware for cross-cutting request shaping affecting many routes. Route Handlers for specific endpoint logic returning data. Do not put business logic in middleware — auth gate yes, order processing no.
When middleware grows complex, extract pure functions testable in Node.js unit tests, keeping middleware file thin.
- Middleware for cross-cutting concerns
- Route Handlers for endpoint logic
- Extract testable pure functions