Movatterモバイル変換


[0]ホーム

URL:


Skip to content

redirects

Last updated November 12, 2025

Redirects allow you to redirect an incoming request path to a different destination path.

To use redirects you can use theredirects key innext.config.js:

next.config.js
module.exports= {asyncredirects() {return [      {        source:'/about',        destination:'/',        permanent:true,      },    ]  },}

redirects is an async function that expects an array to be returned holding objects withsource,destination, andpermanent properties:

  • source is the incoming request path pattern.
  • destination is the path you want to route to.
  • permanenttrue orfalse - iftrue will use the 308 status code which instructs clients/search engines to cache the redirect forever, iffalse will use the 307 status code which is temporary and is not cached.

Why does Next.js use 307 and 308? Traditionally a 302 was used for a temporary redirect, and a 301 for a permanent redirect, but many browsers changed the request method of the redirect toGET, regardless of the original method. For example, if the browser made a request toPOST /v1/users which returned status code302 with location/v2/users, the subsequent request might beGET /v2/users instead of the expectedPOST /v2/users. Next.js uses the 307 temporary redirect, and 308 permanent redirect status codes to explicitly preserve the request method used.

  • basePath:false orundefined - if false thebasePath won't be included when matching, can be used for external redirects only.
  • locale:false orundefined - whether the locale should not be included when matching.
  • has is an array ofhas objects with thetype,key andvalue properties.
  • missing is an array ofmissing objects with thetype,key andvalue properties.

Redirects are checked before the filesystem which includes pages and/public files.

When using the Pages Router, redirects are not applied to client-side routing (Link,router.push) unlessProxy is present and matches the path.

When a redirect is applied, any query values provided in the request will be passed through to the redirect destination. For example, see the following redirect configuration:

{  source:'/old-blog/:path*',  destination:'/blog/:path*',  permanent:false}

Good to know: Remember to include the forward slash/ before the colon: in path parameters of thesource anddestination paths, otherwise the path will be treated as a literal string and you run the risk of causing infinite redirects.

When/old-blog/post-1?hello=world is requested, the client will be redirected to/blog/post-1?hello=world.

Path Matching

Path matches are allowed, for example/old-blog/:slug will match/old-blog/first-post (no nested paths):

next.config.js
module.exports= {asyncredirects() {return [      {        source:'/old-blog/:slug',        destination:'/news/:slug',// Matched parameters can be used in the destination        permanent:true,      },    ]  },}

The pattern/old-blog/:slug matches/old-blog/first-post and/old-blog/post-1 but not/old-blog/a/b (no nested paths). Patterns are anchored to the start:/old-blog/:slug will not match/archive/old-blog/first-post.

You can use modifiers on parameters:* (zero or more),+ (one or more),? (zero or one). For example,/blog/:slug* matches/blog,/blog/a, and/blog/a/b/c.

Read more details onpath-to-regexp documentation.

Wildcard Path Matching

To match a wildcard path you can use* after a parameter, for example/blog/:slug* will match/blog/a/b/c/d/hello-world:

next.config.js
module.exports= {asyncredirects() {return [      {        source:'/blog/:slug*',        destination:'/news/:slug*',// Matched parameters can be used in the destination        permanent:true,      },    ]  },}

Regex Path Matching

To match a regex path you can wrap the regex in parentheses after a parameter, for example/post/:slug(\\d{1,}) will match/post/123 but not/post/abc:

next.config.js
module.exports= {asyncredirects() {return [      {        source:'/post/:slug(\\d{1,})',        destination:'/news/:slug',// Matched parameters can be used in the destination        permanent:false,      },    ]  },}

The following characters(,),{,},:,*,+,? are used for regex path matching, so when used in thesource as non-special values they must be escaped by adding\\ before them:

next.config.js
module.exports= {asyncredirects() {return [      {// this will match `/english(default)/something` being requested        source:'/english\\(default\\)/:slug',        destination:'/en-us/:slug',        permanent:false,      },    ]  },}

Header, Cookie, and Query Matching

To only match a redirect when header, cookie, or query values also match thehas field or don't match themissing field can be used. Both thesource and allhas items must match and allmissing items must not match for the redirect to be applied.

has andmissing items can have the following fields:

  • type:String - must be eitherheader,cookie,host, orquery.
  • key:String - the key from the selected type to match against.
  • value:String orundefined - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the valuefirst-(?<paramName>.*) is used forfirst-second thensecond will be usable in the destination with:paramName.
next.config.js
module.exports= {asyncredirects() {return [// if the header `x-redirect-me` is present,// this redirect will be applied      {        source:'/:path((?!another-page$).*)',        has: [          {            type:'header',            key:'x-redirect-me',          },        ],        permanent:false,        destination:'/another-page',      },// if the header `x-do-not-redirect` is present,// this redirect will NOT be applied      {        source:'/:path((?!another-page$).*)',        missing: [          {            type:'header',            key:'x-do-not-redirect',          },        ],        permanent:false,        destination:'/another-page',      },// if the source, query, and cookie are matched,// this redirect will be applied      {        source:'/specific/:path*',        has: [          {            type:'query',            key:'page',// the page value will not be available in the// destination since value is provided and doesn't// use a named capture group e.g. (?<page>home)            value:'home',          },          {            type:'cookie',            key:'authorized',            value:'true',          },        ],        permanent:false,        destination:'/another/:path*',      },// if the header `x-authorized` is present and// contains a matching value, this redirect will be applied      {        source:'/',        has: [          {            type:'header',            key:'x-authorized',            value:'(?<authorized>yes|true)',          },        ],        permanent:false,        destination:'/home?authorized=:authorized',      },// if the host is `example.com`,// this redirect will be applied      {        source:'/:path((?!another-page$).*)',        has: [          {            type:'host',            value:'example.com',          },        ],        permanent:false,        destination:'/another-page',      },    ]  },}

Redirects with basePath support

When leveragingbasePath support with redirects eachsource anddestination is automatically prefixed with thebasePath unless you addbasePath: false to the redirect:

next.config.js
module.exports= {  basePath:'/docs',asyncredirects() {return [      {        source:'/with-basePath',// automatically becomes /docs/with-basePath        destination:'/another',// automatically becomes /docs/another        permanent:false,      },      {// does not add /docs since basePath: false is set        source:'/without-basePath',        destination:'https://example.com',        basePath:false,        permanent:false,      },    ]  },}

Redirects with i18n support

When implementing redirects with internationalization in the App Router, you can include locales innext.config.js redirects, but only as hardcoded paths.

For dynamic or per-request locale handling, usedynamic route segments and proxy, which can redirect based on the user's preferred language.

next.config.js
module.exports= {asyncredirects() {return [      {// Manually handle locale prefixes for App Router        source:'/en/old-path',        destination:'/en/new-path',        permanent:false,      },      {// Redirect for all locales using a parameter        source:'/:locale/old-path',        destination:'/:locale/new-path',        permanent:false,      },      {// Redirect from one locale to another        source:'/de/old-path',        destination:'/en/new-path',        permanent:false,      },      {// Catch-all redirect for multiple locales        source:'/:locale(en|fr|de)/:path*',        destination:'/:locale/new-section/:path*',        permanent:false,      },    ]  },}

In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use thestatusCode property instead of thepermanent property, but not both. To ensure IE11 compatibility, aRefresh header is automatically added for the 308 status code.

Other Redirects

Version History

VersionChanges
v13.3.0missing added.
v10.2.0has added.
v9.5.0redirects added.

Was this helpful?

supported.

[8]ページ先頭

©2009-2026 Movatter.jp