Перенаправления (redirects)
Перенаправления позволяют перенаправить входящий путь запроса на другой целевой путь.
Для использования перенаправлений вы можете использовать ключ redirects
в next.config.js
:
module.exports = {
async redirects() {
return [
{
source: '/about',
destination: '/',
permanent: true,
},
]
},
}
redirects
— это асинхронная функция, которая ожидает возврата массива объектов со свойствами source
, destination
и permanent
:
source
— шаблон пути входящего запроса.destination
— путь, на который нужно перенаправить.permanent
—true
илиfalse
. Еслиtrue
, будет использоваться код состояния 308, который указывает клиентам/поисковым системам кэшировать перенаправление навсегда. Еслиfalse
, будет использоваться код 307, который является временным и не кэшируется.
Почему Next.js использует 307 и 308? Традиционно 302 использовался для временных перенаправлений, а 301 — для постоянных, но многие браузеры изменяли метод запроса перенаправления на
GET
, независимо от исходного метода. Например, если браузер делал запросPOST /v1/users
, который возвращал код состояния302
с местоположением/v2/users
, последующий запрос мог бытьGET /v2/users
вместо ожидаемогоPOST /v2/users
. Next.js использует коды состояния 307 для временных и 308 для постоянных перенаправлений, чтобы явно сохранить используемый метод запроса.
basePath
:false
илиundefined
— еслиfalse
,basePath
не будет включаться при сопоставлении, может использоваться только для внешних перенаправлений.locale
:false
илиundefined
— указывает, следует ли исключать локаль при сопоставлении.has
— массив объектов has со свойствамиtype
,key
иvalue
.missing
— массив объектов missing со свойствамиtype
,key
иvalue
.
Перенаправления проверяются перед файловой системой, которая включает страницы и файлы /public
.
При использовании маршрутизатора Pages перенаправления не применяются к клиентской маршрутизации (Link
, router.push
), если не присутствует Middleware и соответствует пути.
При применении перенаправления любые значения запроса, предоставленные в запросе, будут переданы в целевой путь перенаправления. Например, рассмотрим следующую конфигурацию перенаправления:
{
source: '/old-blog/:path*',
destination: '/blog/:path*',
permanent: false
}
Важно: Не забудьте включить прямой слеш
/
перед двоеточием:
в параметрах путиsource
иdestination
, иначе путь будет обработан как строковый литерал, и вы рискуете вызвать бесконечные перенаправления.
Когда запрашивается /old-blog/post-1?hello=world
, клиент будет перенаправлен на /blog/post-1?hello=world
.
Сопоставление путей
Разрешено сопоставление путей, например /old-blog/:slug
будет соответствовать /old-blog/hello-world
(без вложенных путей):
module.exports = {
async redirects() {
return [
{
source: '/old-blog/:slug',
destination: '/news/:slug', // Сопоставленные параметры могут использоваться в destination
permanent: true,
},
]
},
}
Сопоставление путей с подстановочными знаками
Для сопоставления пути с подстановочным знаком можно использовать *
после параметра, например /blog/:slug*
будет соответствовать /blog/a/b/c/d/hello-world
:
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Сопоставленные параметры могут использоваться в destination
permanent: true,
},
]
},
}
Сопоставление путей с регулярными выражениями
Для сопоставления пути с регулярным выражением можно обернуть regex в скобки после параметра, например /post/:slug(\\d{1,})
будет соответствовать /post/123
, но не /post/abc
:
module.exports = {
async redirects() {
return [
{
source: '/post/:slug(\\d{1,})',
destination: '/news/:slug', // Сопоставленные параметры могут использоваться в destination
permanent: false,
},
]
},
}
Следующие символы (
, )
, {
, }
, :
, *
, +
, ?
используются для сопоставления путей с регулярными выражениями, поэтому при использовании в source
как обычные значения они должны быть экранированы добавлением \\
перед ними:
module.exports = {
async redirects() {
return [
{
// это будет соответствовать запросу `/english(default)/something`
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
Сопоставление заголовков, куки и запросов
Чтобы перенаправление применялось только при совпадении значений заголовков, куки или запросов, можно использовать поле has
или missing
. И source
, и все элементы has
должны совпадать, а все элементы missing
не должны совпадать для применения перенаправления.
Элементы has
и missing
могут иметь следующие поля:
type
:String
— должно бытьheader
,cookie
,host
илиquery
.key
:String
— ключ из выбранного типа для сопоставления.value
:String
илиundefined
— значение для проверки. Еслиundefined
, будет соответствовать любое значение. Можно использовать строку, подобную regex, для захвата определенной части значения, например, если значениеfirst-(?<paramName>.*)
используется дляfirst-second
, тоsecond
можно будет использовать в destination как:paramName
.
module.exports = {
async redirects() {
return [
// если присутствует заголовок `x-redirect-me`,
// это перенаправление будет применено
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
key: 'x-redirect-me',
},
],
permanent: false,
destination: '/another-page',
},
// если присутствует заголовок `x-dont-redirect`,
// это перенаправление НЕ будет применено
{
source: '/:path((?!another-page$).*)',
missing: [
{
type: 'header',
key: 'x-do-not-redirect',
},
],
permanent: false,
destination: '/another-page',
},
// если совпадают source, query и cookie,
// это перенаправление будет применено
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// значение page не будет доступно в destination,
// так как value предоставлено и не использует именованную группу захвата, например (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
permanent: false,
destination: '/another/:path*',
},
// если присутствует заголовок `x-authorized` и
// содержит соответствующее значение, это перенаправление будет применено
{
source: '/',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
permanent: false,
destination: '/home?authorized=:authorized',
},
// если хост `example.com`,
// это перенаправление будет применено
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'host',
value: 'example.com',
},
],
permanent: false,
destination: '/another-page',
},
]
},
}
Перенаправления с поддержкой basePath
При использовании поддержки basePath
с перенаправлениями каждый source
и destination
автоматически дополняется basePath
, если вы не добавите basePath: false
к перенаправлению:
module.exports = {
basePath: '/docs',
async redirects() {
return [
{
source: '/with-basePath', // автоматически становится /docs/with-basePath
destination: '/another', // автоматически становится /docs/another
permanent: false,
},
{
// не добавляет /docs, так как установлено basePath: false
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
permanent: false,
},
]
},
}
Перенаправления с поддержкой i18n
При использовании поддержки i18n
с перенаправлениями каждый source
и destination
автоматически дополняется для обработки настроенных locales
, если вы не добавите locale: false
к перенаправлению. Если используется locale: false
, вы должны добавить локаль к source
и destination
для правильного сопоставления.
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async redirects() {
return [
{
source: '/with-locale', // автоматически обрабатывает все локали
destination: '/another', // автоматически передает локаль
permanent: false,
},
{
// не обрабатывает локали автоматически, так как установлено locale: false
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
permanent: false,
},
{
// соответствует '/', так как `en` — defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
permanent: false,
},
// возможно сопоставить все локали, даже если установлено locale: false
{
source: '/:locale/page',
destination: '/en/newpage',
permanent: false,
locale: false,
},
{
// преобразуется в /(en|fr|de)/(.*), поэтому не будет соответствовать
// корневому `/` или `/fr`, как это сделал бы /:path*
source: '/(.*)',
destination: '/another',
permanent: false,
},
]
},
}
В некоторых редких случаях может потребоваться назначить пользовательский код состояния для правильного перенаправления старых HTTP-клиентов. В таких случаях можно использовать свойство statusCode
вместо permanent
, но не оба одновременно. Для обеспечения совместимости с IE11 автоматически добавляется заголовок Refresh
для кода состояния 308.
Другие перенаправления
- Внутри API Routes и Route Handlers вы можете выполнять перенаправления на основе входящего запроса.
- Внутри
getStaticProps
иgetServerSideProps
вы можете перенаправлять определенные страницы во время запроса.
История версий
Версия | Изменения |
---|---|
v13.3.0 | Добавлено missing . |
v10.2.0 | Добавлено has . |
v9.5.0 | Добавлено redirects . |