* Add `async` to middleware docs. I was reading the docs and got nervous. It looked like middleware didn't support async/await. After digging into the examples I found out it is possible. Not 100% sure if this is the docs change yahs want, but I thought I'd open a PR just incase. * Add middleware API note Co-authored-by: JJ Kasper <jj@jjsweb.site>
4.4 KiB
description |
---|
Learn how to use Middleware in Next.js to run code before a request is completed. |
Middleware
Middleware enables you to use code over configuration. This gives you full flexibility in Next.js, because you can run code before a request is completed. Based on the user's incoming request, you can modify the response by rewriting, redirecting, adding headers, or even streaming HTML.
Usage
- Install the latest version of Next.js:
npm install next@latest
-
Then, create a
_middleware.ts
file under your/pages
directory. -
Finally, export a middleware function from the
_middleware.ts
file.
// pages/_middleware.ts
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, ev: NextFetchEvent) {
return new Response('Hello, world!')
}
In this example, we use the standard Web API Response (MDN).
API
Middleware is created by using a middleware
function that lives inside a _middleware
file. Its API is based upon the native FetchEvent
, Response
, and Request
objects.
These native Web API objects are extended to give you more control over how you manipulate and configure a response, based on the incoming requests.
The function signature:
import type { NextFetchEvent } from 'next/server'
import type { NextRequest } from 'next/server'
export type Middleware = (
request: NextRequest,
event: NextFetchEvent
) => Promise<Response | undefined> | Response | undefined
The function can be a default export and as such, does not have to be named middleware
. Though this is a convention. Also note that you only need to make the function async
if you are running asynchronous code.
Note: Edge Functions are currently in Beta. The API might change as we look to continually make improvements.
Examples
Middleware can be used for anything that shares logic for a set of pages, including:
- Authentication
- Bot protection
- Redirects and rewrites
- Handling unsupported browsers
- Feature flags and A/B tests
- Server-side analytics
- Advanced i18n routing requirements
- Logging
Execution Order
If your Middleware is created in /pages/_middleware.ts
, it will run on all routes within the /pages
directory. The below example assumes you have about.tsx
and teams.tsx
routes.
- package.json
- /pages
_middleware.ts # Will run on all routes under /pages
index.tsx
about.tsx
teams.tsx
If you do have sub-directories with nested routes, Middleware will run from the top down. For example, if you have /pages/about/_middleware.ts
and /pages/about/team/_middleware.ts
, /about
will run first and then /about/team
. The below example shows how this works with a nested routing structure.
- package.json
- /pages
index.tsx
- /about
_middleware.ts # Will run first
about.tsx
- /teams
_middleware.ts # Will run second
teams.tsx
Middleware runs directly after redirects
and headers
, before the first filesystem lookup. This excludes /_next
files.
Deployment
Middleware uses a strict runtime that supports standard Web APIs like fetch
. This works out of the box using next start
, as well as on Edge platforms like Vercel, which use Edge Functions.