patterntypescriptnextjsMajor
Middleware patterns: matcher config and early returns
Viewed 0 times
Next.js 12+ for middleware
middlewarematcheredge runtimeauth middlewareJWTNextResponse redirect
Error Messages
Problem
Running middleware on every request (including static assets, _next, and API routes) wastes cycles and can break things. Auth middleware that fetches from a database causes timeouts due to edge runtime constraints.
Solution
Configure matcher to narrow middleware scope, and use lightweight checks:
// middleware.ts (at project root or src/)
import { NextRequest, NextResponse } from 'next/server';
import { verifyJWT } from './lib/auth';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
try {
const payload = verifyJWT(token);
const response = NextResponse.next();
response.headers.set('x-user-id', payload.sub);
return response;
} catch {
return NextResponse.redirect(new URL('/login', request.url));
}
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|login|register).*)',
'/api/:path*',
],
};
// middleware.ts (at project root or src/)
import { NextRequest, NextResponse } from 'next/server';
import { verifyJWT } from './lib/auth';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
try {
const payload = verifyJWT(token);
const response = NextResponse.next();
response.headers.set('x-user-id', payload.sub);
return response;
} catch {
return NextResponse.redirect(new URL('/login', request.url));
}
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|login|register).*)',
'/api/:path*',
],
};
Why
Middleware runs on every matched request before it reaches the page or API handler. Without matcher config, it runs on static files and Next.js internals — wasteful and potentially breaking. Edge runtime has no Node.js APIs so database clients that use TCP sockets won't work.
Gotchas
- Middleware runs in Edge Runtime by default — no Node.js built-ins (fs, net, etc.)
- Never put database queries in middleware — use JWT/session token verification instead
- NextResponse.rewrite() changes the URL internally; NextResponse.redirect() changes it externally (301/307)
- The matcher array supports regex negation with (?!...) to exclude paths
Code Snippets
Middleware matcher to skip static assets
export const config = {
matcher: [
// Skip static files, run on everything else
'/((?!_next/static|_next/image|favicon.ico).*)',
],
};Context
When adding authentication or request transformation middleware to a Next.js app
Revisions (0)
No revisions yet.