Next.js Edge Middleware: What It Is and When to Use It
#nextjs
#edge
#middleware
#webdev
Introduction
Next.js Edge Middleware lets you run code at the edge, in the Edge Runtime, before a request reaches your Next.js serverless functions or pages. It’s ideal for small, fast decisions like redirects, rewrites, header manipulation, and lightweight access checks that benefit from minimized latency.
What is Next.js Edge Middleware?
Edge Middleware is code that executes as requests arrive at the edge network, close to the user. It runs before a route is resolved, allowing you to influence routing, headers, or responses without hitting your origin server. Typical use cases include redirects, locale or device-aware content, and basic access controls.
How Edge Middleware differs from standard Middleware
- Runtime environment: Edge Middleware runs in the Edge Runtime, a lighter, serverless environment with a smaller API surface than a full Node.js server.
- Timing: It executes at the edge before the application route resolution, which can save round-trips to origin.
- Capabilities: You can modify requests and responses, set cookies, and perform redirects or rewrites. You cannot depend on full Node.js APIs (e.g., no direct filesystem access).
- Configuration: You control when it runs via a matcher configuration, targeting specific routes.
Getting started
- Create a middleware file at the project root to define edge logic.
- Use NextRequest and NextResponse to inspect the incoming request and shape the outgoing response.
- Configure a matcher to limit where the middleware runs.
Code example:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
// Example: enforce HTTPS
if (req.nextUrl.protocol === 'http:') {
const url = req.nextUrl.clone();
url.protocol = 'https:';
return NextResponse.redirect(url);
}
// Example: add a custom header
const res = NextResponse.next();
res.headers.set('X-From-Edge', 'true');
return res;
}
export const config = {
// Run on all pages except Next.js internals
matcher: '/((?!_next|favicon.ico).*)'
};
When to use Edge Middleware
- Edge redirects and rewrites: Move routing decisions closer to the user to reduce latency.
- Personalization and localization: Make quick decisions based on locale, country, or device without waiting for server-side data.
- Lightweight authentication checks: Validate tokens or headers without engaging your backend for every request.
- Bot protection and rate limiting: Filter suspicious traffic at the edge before it reaches your origin.
- Feature flag or A/B test routing: Route traffic differently based on lightweight, fast checks.
When not to use Edge Middleware
- Very heavy or stateful logic: Complex authentication flows that rely on server sessions or databases.
- Direct access to the filesystem or certain Node.js APIs: The Edge Runtime omits many Node.js features.
- Operations that require persistent storage or long-lived connections at the edge.
Best practices
- Keep middleware small and fast: Avoid network calls or heavy computation inside the edge.
- Narrow the matcher: Only apply middleware to routes that truly need edge decisions.
- Prefer stateless checks: Use tokens, headers, and lightweight context rather than server-side state.
- Log judiciously: Observe traffic patterns and performance impact without overloading edge logs.
- Combine with server-side logic: Use edge middleware for initial routing and defer complex decisions to your backend when needed.
Conclusion
Edge Middleware in Next.js offers a powerful way to optimize routing, personalization, and security by moving decisions closer to users. Use it to handle simple, latency-sensitive tasks at the edge, and reserve heavier processing for your origin or backend services.