-
Notifications
You must be signed in to change notification settings - Fork 26.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add the middleware.ts API reference file convention (#61037)
This PR adds a new docs page under the File Conventions section for the`middleware.ts` file. It includes: - Explanation of `middleware.ts` usage in Next.js. - Code examples in TypeScript and JavaScript. - Information on `matcher` function, `NextResponse`, and middleware runtime environment. - Version history of middleware feature updates. --------- Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Co-authored-by: Michael Novotny <manovotny@gmail.com>
- Loading branch information
1 parent
1eecfc7
commit bc22b21
Showing
1 changed file
with
145 additions
and
0 deletions.
There are no files selected for viewing
145 changes: 145 additions & 0 deletions
145
docs/02-app/02-api-reference/02-file-conventions/middleware.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
--- | ||
title: middleware.js | ||
description: API reference for the middleware.js file. | ||
related: | ||
title: Learn more about Middleware | ||
links: | ||
- app/building-your-application/routing/middleware | ||
--- | ||
|
||
The `middleware.js|ts` file is used to write [Middleware](/docs/app/building-your-application/routing/middleware) and run code on the server 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. | ||
|
||
Middleware executes before routes are rendered. It's particularly useful for implementing custom server-side logic like authentication, logging, or handling redirects. | ||
|
||
Use the file `middleware.ts` (or .js) in the root of your project to define Middleware. For example, at the same level as `app` or `pages`, or inside `src` if applicable. | ||
|
||
```tsx filename="middleware.ts" switcher | ||
import { NextResponse, 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)) | ||
} | ||
|
||
export const config = { | ||
matcher: '/about/:path*', | ||
} | ||
``` | ||
|
||
```js filename="middleware.js" switcher | ||
import { NextResponse } from 'next/server' | ||
|
||
// This function can be marked `async` if using `await` inside | ||
export function middleware(request) { | ||
return NextResponse.redirect(new URL('/home', request.url)) | ||
} | ||
|
||
export const config = { | ||
matcher: '/about/:path*', | ||
} | ||
``` | ||
|
||
## Exports | ||
|
||
### Middleware function | ||
|
||
The file must export a single function, either as a default export or named `middleware`. Note that multiple middleware from the same file are not supported. | ||
|
||
```js filename="middleware.js" | ||
// Example of default export | ||
export default function middleware(request) { | ||
// Middleware logic | ||
} | ||
``` | ||
|
||
### Config object (optional) | ||
|
||
Optionally, a config object can be exported alongside the Middleware function. This object includes the [matcher](#matcher) to specify paths where the Middleware applies as well as the `regions` option. | ||
|
||
#### Matcher | ||
|
||
The `matcher` option allows you to target specific paths for the Middleware to run on. You can specify these paths in several ways: | ||
|
||
- For a single path: Directly use a string to define the path, like `'/about'`. | ||
- For multiple paths: Use an array to list multiple paths, such as `matcher: ['/about', '/contact']`, which applies the Middleware to both `/about` and `/contact`. | ||
|
||
Additionally, `matcher` supports complex path specifications through regular expressions, such as `matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)']`, enabling precise control over which paths to include or exclude. | ||
|
||
The `matcher` option also accepts an array of objects with the following keys: | ||
|
||
- `source`: The path or pattern used to match the request paths. It can be a string for direct path matching or a pattern for more complex matching. | ||
- `regexp` (optional): A regular expression string that fine-tunes the matching based on the source. It provides additional control over which paths are included or excluded. | ||
- `locale` (optional): A boolean that, when set to `false`, ignores locale-based routing in path matching. | ||
- `has` (optional): Specifies conditions based on the presence of specific request elements such as headers, query parameters, or cookies. | ||
- `missing` (optional): Focuses on conditions where certain request elements are absent, like missing headers or cookies. | ||
|
||
```js filename="middleware.js" | ||
export const config = { | ||
matcher: [ | ||
{ | ||
source: '/api/*', | ||
regexp: '^/api/(.*)', | ||
locale: false, | ||
has: [ | ||
{ type: 'header', key: 'Authorization', value: 'Bearer Token' }, | ||
{ type: 'query', key: 'userId', value: '123' }, | ||
], | ||
missing: [{ type: 'cookie', key: 'session', value: 'active' }], | ||
}, | ||
], | ||
} | ||
``` | ||
|
||
#### Regions | ||
|
||
The `regions` option allows you to specify the geographic locations where the Middleware runs. By default, Middleware runs in all regions. | ||
|
||
```js filename="middleware.js" | ||
export const config = { | ||
regions: ['us-east-1', 'us-west-1'], | ||
} | ||
``` | ||
|
||
## Params | ||
|
||
### `request` | ||
|
||
When defining Middleware, the default export function accepts a single parameter, `request`. This parameter is an instance of `NextRequest`, which represents the incoming HTTP request. | ||
|
||
```tsx filename="middleware.ts" switcher | ||
import type { NextRequest } from 'next/server' | ||
|
||
export function middleware(request: NextRequest) { | ||
// Middleware logic goes here | ||
} | ||
``` | ||
|
||
```js filename="middleware.js" switcher | ||
export function middleware(request) { | ||
// Middleware logic goes here | ||
} | ||
``` | ||
|
||
> **Good to know**: | ||
> | ||
> - `NextRequest` is a type that represents incoming HTTP requests in Next.js Middleware, whereas [`NextResponse`](#nextresponse) is a class used to manipulate and send back HTTP responses. | ||
## NextResponse | ||
|
||
Middleware can use the [`NextResponse`](/docs/app/building-your-application/routing/middleware#nextresponse) object which extends the [Web Response API](https://developer.mozilla.org/en-US/docs/Web/API/Response). By returning a `NextResponse` object, you can directly manipulate cookies, set headers, implement redirects, and rewrite paths. | ||
|
||
> **Good to know**: For redirects, you can also use `Response.redirect` instead of `NextResponse.redirect`. | ||
## Runtime | ||
|
||
Middleware only supports the [Edge runtime](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes). The Node.js runtime cannot be used. | ||
|
||
## Version History | ||
|
||
| Version | Changes | | ||
| --------- | --------------------------------------------------------------------------------------------- | | ||
| `v13.1.0` | Advanced Middleware flags added | | ||
| `v13.0.0` | Middleware can modify request headers, response headers, and send responses | | ||
| `v12.2.0` | Middleware is stable, please see the [upgrade guide](/docs/messages/middleware-upgrade-guide) | | ||
| `v12.0.9` | Enforce absolute URLs in Edge Runtime ([PR](https://github.com/vercel/next.js/pull/33410)) | | ||
| `v12.0.0` | Middleware (Beta) added | |
bc22b21
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stats from current release
Default Build (Increase detected⚠️ )
General Overall increase⚠️
Client Bundles (main, webpack) Overall increase⚠️
Legacy Client Bundles (polyfills)
Client Pages
Client Build Manifests
Rendered Page Sizes
Edge SSR bundle Size Overall increase⚠️
Middleware size Overall increase⚠️
Next Runtimes Overall increase⚠️
Diff details
Diff for page.js
Diff too large to display
Diff for middleware.js
Diff too large to display
Diff for edge-ssr.js
Diff too large to display
Diff for 433-HASH.js
Diff too large to display
Diff for main-HASH.js
Diff too large to display
Diff for polyfills-HASH.js
Diff too large to display
Diff for webpack-HASH.js
Diff for app-page-exp..ntime.dev.js
Diff for app-page-exp..time.prod.js
Diff too large to display
Diff for app-page-tur..time.prod.js
Diff too large to display
Diff for app-page-tur..time.prod.js
Diff too large to display
Diff for app-page.runtime.dev.js
Diff for app-page.runtime.prod.js
Diff too large to display
Diff for app-route-ex..ntime.dev.js
Diff too large to display
Diff for app-route-ex..time.prod.js
Diff too large to display
Diff for app-route-tu..time.prod.js
Diff too large to display
Diff for app-route-tu..time.prod.js
Diff too large to display
Diff for app-route.runtime.dev.js
Diff too large to display
Diff for app-route.ru..time.prod.js
Diff too large to display
Diff for pages-api-tu..time.prod.js
Diff too large to display
Diff for pages-api.runtime.dev.js
Diff too large to display
Diff for pages-api.ru..time.prod.js
Diff too large to display
Diff for pages-turbo...time.prod.js
Diff too large to display
Diff for pages.runtime.dev.js
Diff too large to display
Diff for pages.runtime.prod.js
Diff too large to display
Diff for server.runtime.prod.js
Diff too large to display