middleware.ts file at your project root.matcher config to specify which routes trigger middleware.1import { NextResponse } from 'next/server';2import type { NextRequest } from 'next/server';34export function middleware(request: NextRequest) {5// Check authentication6const token = request.cookies.get('session');78if (!token) {9return NextResponse.redirect(new URL('/login', request.url));10}1112// Add custom header13const response = NextResponse.next();14response.headers.set('x-user-id', token.value);15return response;16}1718export const config = { matcher: ['/dashboard/:path*', '/api/:path*'] };
| Use Case | Implementation |
|---|---|
| Authentication | Check tokens, redirect to login |
| Redirects | Permanent or temporary URL changes |
| Rewrites | Serve different content at same URL |
| A/B Testing | Route users to different variants |
| Geolocation | Personalize based on user location |
Middleware runs at the Edge for low-latency decisions.
| Topic | Guidance |
|---|---|
| Performance | Keep middleware lean; avoid heavy I/O |
| Security | Validate auth tokens before routing |
| Scope | Use matchers to limit which paths run middleware |
| Runtime | Edge runtime only — no Node.js-specific APIs |
fs or crypto.randomBytes.NextResponse — either next(), redirect(), or rewrite().project/ ├── middleware.ts ← runs on matched routes ├── app/ │ └── ...
Redirect unauthenticated users to login
Route users to country-specific pages
Rewrite to different page variants
Add security or custom headers