MENU
middleware.js
Middleware allows you to run code before a request is completed.
Located at the project root (not inside /app! or inside /src if you use it. ) , the middleware runs before cached content and routes are matched.
Use Cases
Integrating Middleware into your application can significantly enhance performance, security, and user experience. Middleware is particularly effective in the following scenarios:- Authentication and Authorization: Verify user identities and check session cookies to control access to specific pages or API routes.
- Server-Side Redirects: Redirect users at the server level based on conditions such as locale or user role.
- Path Rewriting: Dynamically rewrite paths to support A/B testing, feature rollouts, or accommodate legacy paths based on request properties.
- Bot Detection: Safeguard your resources by detecting and blocking bot traffic.
- Logging and Analytics: Capture and analyze request data for insights before it reaches the page or API.
- Feature Flagging: Dynamically enable or disable features for seamless rollouts or testing.
Execution Order
Middleware will be invoked for every route. It's crucial to precisely set the targets. The following is the execution order:- headers from next.config.js
- redirects from next.config.js
- Middleware
- beforeFiles (rewrites) from next.config.js
- Filesystem routes (public/, _next/static/, pages/, app/, etc.)
- afterFiles (rewrites) from next.config.js
- Dynamic Routes (/blog/[slug])
- fallback (rewrites) from next.config.js
The waitUntil() method extends the lifetime of the Middleware until a promise settles.
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, event: NextFetchEvent) {
event.waitUntil(
fetch('https://my-analytics-platform.com', {
method: 'POST',
body: JSON.stringify({ pathname: req.nextUrl.pathname }),
});
);
return NextResponse.next();
}
You can redirect or rewrite the incoming request to a different URL.
You can set CORS headers in Middleware to allow cross-origin requests.
import { NextRequest, NextResponse } from 'next/server'
const allowedOrigins = ['https://acme.com', 'https://my-app.org']
const corsOptions = {
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
export function middleware(request: NextRequest) {
const origin = request.headers.get('origin') ?? ''; // Check the origin from the request
if (request.method === 'OPTIONS') {
const preflightHeaders = {
...(isAllowedOrigin && { 'Access-Control-Allow-Origin': origin }),
...corsOptions,
}
return NextResponse.json({}, { headers: preflightHeaders })
}
const response = NextResponse.next(); // Handle simple requests
if (allowedOrigins.includes(origin)) response.headers.set('Access-Control-Allow-Origin', origin)
Object.entries(corsOptions).forEach(([key, value]) => {
response.headers.set(key, value)
})
return response;
}
export const config = {
matcher: '/api/:path*',
}Refer to the section on Authorization for another important use case of theMiddleware. Notice how cookies can be set in the Middleware.
Two configuration flags, skipMiddlewareUrlNormalize and skipTrailingSlashRedirect, are associated with the middleware.