Movatterモバイル変換


[0]ホーム

URL:


Skip to content
API ReferenceFile-system conventionsmiddleware.js

middleware.js

Themiddleware.js|ts file is used to writeMiddleware 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 filemiddleware.ts (or .js) in the root of your project to define Middleware. For example, at the same level asapp orpages, or insidesrc if applicable.

middleware.ts
import { NextResponse, NextRequest }from'next/server'// This function can be marked `async` if using `await` insideexportfunctionmiddleware(request:NextRequest) {returnNextResponse.redirect(newURL('/home',request.url))}exportconstconfig= {  matcher:'/about/:path*',}

Exports

Middleware function

The file must export a single function, either as a default export or namedmiddleware. Note that multiple middleware from the same file are not supported.

middleware.js
// Example of default exportexportdefaultfunctionmiddleware(request) {// Middleware logic}

Config object (optional)

Optionally, a config object can be exported alongside the Middleware function. This object includes thematcher to specify paths where the Middleware applies.

Matcher

Thematcher 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 asmatcher: ['/about', '/contact'], which applies the Middleware to both/about and/contact.
middleware.js
exportconstconfig= {  matcher: ['/about/:path*','/dashboard/:path*'],}

Additionally, thematcher option supports complex path specifications through regular expressions, such asmatcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'], enabling precise control over which paths to include or exclude.

Thematcher option 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 tofalse, 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.
middleware.js
exportconstconfig= {  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' }],    },  ],}

Configured matchers:

  1. MUST start with/
  2. Can include named parameters:/about/:path matches/about/a and/about/b but not/about/a/c
  3. Can have modifiers on named parameters (starting with:):/about/:path* matches/about/a/b/c because* iszero or more.? iszero or one and+one or more
  4. Can use regular expression enclosed in parenthesis:/about/(.*) is the same as/about/:path*

Read more details onpath-to-regexp documentation.

Good to know:

  • Thematcher values need to be constants so they can be statically analyzed at build-time. Dynamic values such as variables will be ignored.
  • For backward compatibility, Next.js always considers/public as/public/index. Therefore, a matcher of/public/:path will match.

Params

request

When defining Middleware, the default export function accepts a single parameter,request. This parameter is an instance ofNextRequest, which represents the incoming HTTP request.

middleware.ts
importtype { NextRequest }from'next/server'exportfunctionmiddleware(request:NextRequest) {// Middleware logic goes here}

Good to know:

  • NextRequest is a type that represents incoming HTTP requests in Next.js Middleware, whereasNextResponse is a class used to manipulate and send back HTTP responses.

NextResponse

TheNextResponse API allows you to:

  • redirect the incoming request to a different URL
  • rewrite the response by displaying a given URL
  • Set request headers for API Routes,getServerSideProps, andrewrite destinations
  • Set response cookies
  • Set response headers

To produce a response from Middleware, you can:

  1. rewrite to a route (Page orRoute Handler) that produces a response
  2. return aNextResponse directly. SeeProducing a Response

Good to know: For redirects, you can also useResponse.redirect instead ofNextResponse.redirect.

Execution order

Middleware will be invoked forevery route in your project. Given this, it's crucial to usematchers to precisely target or exclude specific routes. The following is the execution order:

  1. headers fromnext.config.js
  2. redirects fromnext.config.js
  3. Middleware (rewrites,redirects, etc.)
  4. beforeFiles (rewrites) fromnext.config.js
  5. Filesystem routes (public/,_next/static/,pages/,app/, etc.)
  6. afterFiles (rewrites) fromnext.config.js
  7. Dynamic Routes (/blog/[slug])
  8. fallback (rewrites) fromnext.config.js

Runtime

Middleware defaults to using the Edge runtime. As of v15.2 (canary), we have experimental support for using the Node.js runtime. To enable, add the flag to yournext.config file:

next.config.ts
importtype { NextConfig }from'next'constnextConfig:NextConfig= {  experimental: {    nodeMiddleware:true,  },}exportdefault nextConfig

Then in your middleware file, set the runtime tonodejs in theconfig object:

middleware.ts
exportconstconfig= {  runtime:'nodejs',}

Note: This feature is not yet recommended for production use. Therefore, Next.js will throw an error unless you are using the next@canary release instead of the stable release.

Advanced Middleware flags

Inv13.1 of Next.js two additional flags were introduced for middleware,skipMiddlewareUrlNormalize andskipTrailingSlashRedirect to handle advanced use cases.

skipTrailingSlashRedirect disables Next.js redirects for adding or removing trailing slashes. This allows custom handling inside middleware to maintain the trailing slash for some paths but not others, which can make incremental migrations easier.

next.config.js
module.exports= {  skipTrailingSlashRedirect:true,}
middleware.js
constlegacyPrefixes= ['/docs','/blog']exportdefaultasyncfunctionmiddleware(req) {const {pathname }=req.nextUrlif (legacyPrefixes.some((prefix)=>pathname.startsWith(prefix))) {returnNextResponse.next()  }// apply trailing slash handlingif (!pathname.endsWith('/')&&!pathname.match(/((?!\.well-known(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+)/)  ) {returnNextResponse.redirect(newURL(`${req.nextUrl.pathname}/`,req.nextUrl)    )  }}

skipMiddlewareUrlNormalize allows for disabling the URL normalization in Next.js to make handling direct visits and client-transitions the same. In some advanced cases, this option provides full control by using the original URL.

next.config.js
module.exports= {  skipMiddlewareUrlNormalize:true,}
middleware.js
exportdefaultasyncfunctionmiddleware(req) {const {pathname }=req.nextUrl// GET /_next/data/build-id/hello.jsonconsole.log(pathname)// with the flag this now /_next/data/build-id/hello.json// without the flag this would be normalized to /hello}

Examples

Conditional Statements

middleware.ts
import { NextResponse }from'next/server'importtype { NextRequest }from'next/server'exportfunctionmiddleware(request:NextRequest) {if (request.nextUrl.pathname.startsWith('/about')) {returnNextResponse.rewrite(newURL('/about-2',request.url))  }if (request.nextUrl.pathname.startsWith('/dashboard')) {returnNextResponse.rewrite(newURL('/dashboard/user',request.url))  }}

Using Cookies

Cookies are regular headers. On aRequest, they are stored in theCookie header. On aResponse they are in theSet-Cookie header. Next.js provides a convenient way to access and manipulate these cookies through thecookies extension onNextRequest andNextResponse.

  1. For incoming requests,cookies comes with the following methods:get,getAll,set, anddelete cookies. You can check for the existence of a cookie withhas or remove all cookies withclear.
  2. For outgoing responses,cookies have the following methodsget,getAll,set, anddelete.
middleware.ts
import { NextResponse }from'next/server'importtype { NextRequest }from'next/server'exportfunctionmiddleware(request:NextRequest) {// Assume a "Cookie:nextjs=fast" header to be present on the incoming request// Getting cookies from the request using the `RequestCookies` APIlet cookie=request.cookies.get('nextjs')console.log(cookie)// => { name: 'nextjs', value: 'fast', Path: '/' }constallCookies=request.cookies.getAll()console.log(allCookies)// => [{ name: 'nextjs', value: 'fast' }]request.cookies.has('nextjs')// => truerequest.cookies.delete('nextjs')request.cookies.has('nextjs')// => false// Setting cookies on the response using the `ResponseCookies` APIconstresponse=NextResponse.next()response.cookies.set('vercel','fast')response.cookies.set({    name:'vercel',    value:'fast',    path:'/',  })  cookie=response.cookies.get('vercel')console.log(cookie)// => { name: 'vercel', value: 'fast', Path: '/' }// The outgoing response will have a `Set-Cookie:vercel=fast;path=/` header.return response}

Setting Headers

You can set request and response headers using theNextResponse API (settingrequest headers is available since Next.js v13.0.0).

middleware.ts
import { NextResponse }from'next/server'importtype { NextRequest }from'next/server'exportfunctionmiddleware(request:NextRequest) {// Clone the request headers and set a new header `x-hello-from-middleware1`constrequestHeaders=newHeaders(request.headers)requestHeaders.set('x-hello-from-middleware1','hello')// You can also set request headers in NextResponse.nextconstresponse=NextResponse.next({    request: {// New request headers      headers: requestHeaders,    },  })// Set a new response header `x-hello-from-middleware2`response.headers.set('x-hello-from-middleware2','hello')return response}

Good to know: Avoid setting large headers as it might cause431 Request Header Fields Too Large error depending on your backend web server configuration.

CORS

You can set CORS headers in Middleware to allow cross-origin requests, includingsimple andpreflighted requests.

middleware.ts
import { NextRequest, NextResponse }from'next/server'constallowedOrigins= ['https://acme.com','https://my-app.org']constcorsOptions= {'Access-Control-Allow-Methods':'GET, POST, PUT, DELETE, OPTIONS','Access-Control-Allow-Headers':'Content-Type, Authorization',}exportfunctionmiddleware(request:NextRequest) {// Check the origin from the requestconstorigin=request.headers.get('origin')??''constisAllowedOrigin=allowedOrigins.includes(origin)// Handle preflighted requestsconstisPreflight=request.method==='OPTIONS'if (isPreflight) {constpreflightHeaders= {...(isAllowedOrigin&& {'Access-Control-Allow-Origin': origin }),...corsOptions,    }returnNextResponse.json({}, { headers: preflightHeaders })  }// Handle simple requestsconstresponse=NextResponse.next()if (isAllowedOrigin) {response.headers.set('Access-Control-Allow-Origin', origin)  }Object.entries(corsOptions).forEach(([key, value])=> {response.headers.set(key, value)  })return response}exportconstconfig= {  matcher:'/api/:path*',}

Good to know: You can configure CORS headers for individual routes inRoute Handlers.

Producing a response

You can respond from Middleware directly by returning aResponse orNextResponse instance. (This is available sinceNext.js v13.1.0)

middleware.ts
importtype { NextRequest }from'next/server'import { isAuthenticated }from'@lib/auth'// Limit the middleware to paths starting with `/api/`exportconstconfig= {  matcher:'/api/:function*',}exportfunctionmiddleware(request:NextRequest) {// Call our authentication function to check the requestif (!isAuthenticated(request)) {// Respond with JSON indicating an error messagereturnResponse.json(      { success:false, message:'authentication failed' },      { status:401 }    )  }}

Negative matching

Thematcher config allows full regex so matching like negative lookaheads or character matching is supported. An example of a negative lookahead to match all except specific paths can be seen here:

middleware.js
exportconstconfig= {  matcher: [/*     * Match all request paths except for the ones starting with:     * - api (API routes)     * - _next/static (static files)     * - _next/image (image optimization files)     * - favicon.ico, sitemap.xml, robots.txt (metadata files)     */'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',  ],}

You can also bypass Middleware for certain requests by using themissing orhas arrays, or a combination of both:

middleware.js
exportconstconfig= {  matcher: [/*     * Match all request paths except for the ones starting with:     * - api (API routes)     * - _next/static (static files)     * - _next/image (image optimization files)     * - favicon.ico, sitemap.xml, robots.txt (metadata files)     */    {      source:'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',      missing: [        { type:'header', key:'next-router-prefetch' },        { type:'header', key:'purpose', value:'prefetch' },      ],    },    {      source:'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',      has: [        { type:'header', key:'next-router-prefetch' },        { type:'header', key:'purpose', value:'prefetch' },      ],    },    {      source:'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',      has: [{ type:'header', key:'x-present' }],      missing: [{ type:'header', key:'x-missing', value:'prefetch' }],    },  ],}

waitUntil andNextFetchEvent

TheNextFetchEvent object extends the nativeFetchEvent object, and includes thewaitUntil() method.

ThewaitUntil() method takes a promise as an argument, and extends the lifetime of the Middleware until the promise settles. This is useful for performing work in the background.

middleware.ts
import { NextResponse }from'next/server'importtype { NextFetchEvent, NextRequest }from'next/server'exportfunctionmiddleware(req:NextRequest, event:NextFetchEvent) {event.waitUntil(fetch('https://my-analytics-platform.com', {      method:'POST',      body:JSON.stringify({ pathname:req.nextUrl.pathname }),    })  )returnNextResponse.next()}

Unit testing (experimental)

Starting in Next.js 15.1, thenext/experimental/testing/server package contains utilities to help unit test middleware files. Unit testing middleware can help ensure that it's only run on desired paths and that custom routing logic works as intended before code reaches production.

Theunstable_doesMiddlewareMatch function can be used to assert whether middleware will run for the provided URL, headers, and cookies.

import { unstable_doesMiddlewareMatch }from'next/experimental/testing/server'expect(unstable_doesMiddlewareMatch({    config,    nextConfig,    url:'/test',  })).toEqual(false)

The entire middleware function can also be tested.

import { isRewrite, getRewrittenUrl }from'next/experimental/testing/server'constrequest=newNextRequest('https://nextjs.org/docs')constresponse=awaitmiddleware(request)expect(isRewrite(response)).toEqual(true)expect(getRewrittenUrl(response)).toEqual('https://other-domain.com/docs')// getRedirectUrl could also be used if the response were a redirect

Platform support

Deployment OptionSupported
Node.js serverYes
Docker containerYes
Static exportNo
AdaptersPlatform-specific

Learn how toconfigure Middleware when self-hosting Next.js.

Version history

VersionChanges
v15.2.0Middleware can now use the Node.js runtime (experimental)
v13.1.0Advanced Middleware flags added
v13.0.0Middleware can modify request headers, response headers, and send responses
v12.2.0Middleware is stable, please see theupgrade guide
v12.0.9Enforce absolute URLs in Edge Runtime (PR)
v12.0.0Middleware (Beta) added

Learn more about Middleware

NextRequest

API Reference for NextRequest.

NextResponse

API Reference for NextResponse.

Was this helpful?

supported.

[8]ページ先頭

©2009-2025 Movatter.jp