Middleware
Middleware allows you to run code before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.
Use Cases
Some common scenarios where Middleware is effective include:
- Quick redirects after reading parts of the incoming request
- Rewriting to different pages based on A/B tests or experiments
- Modifying headers for all pages or a subset of pages
Middleware is not a good fit for:
- Slow data fetching
- Session management
Using fetch with options.cache
, options.next.revalidate
, or options.next.tags
, has no effect in Middleware.
Convention
Use the file middleware.ts
(or .js
) in the root of your project to define Middleware. For example, at the same level as pages
or app
, or inside src
if applicable.
Note: While only one
middleware.ts
file is supported per project, you can still organize your middleware logic modularly. Break out middleware functionalities into separate.ts
or.js
files and import them into your mainmiddleware.ts
file. This allows for cleaner management of route-specific middleware, aggregated in themiddleware.ts
for centralized control. By enforcing a single middleware file, it simplifies configuration, prevents potential conflicts, and optimizes performance by avoiding multiple middleware layers.
Example
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*',
}
Was this helpful?