Перенаправления (redirects)

Перенаправления позволяют перенаправить входящий путь запроса на другой целевой путь.

Для использования перенаправлений вы можете использовать ключ redirects в next.config.js:

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

redirects — это асинхронная функция, которая ожидает возврата массива объектов со свойствами source, destination и permanent:

  • source — шаблон пути входящего запроса.
  • destination — путь, на который нужно перенаправить.
  • permanenttrue или 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 (без вложенных путей):

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug', // Сопоставленные параметры могут использоваться в destination
        permanent: true,
      },
    ]
  },
}

Сопоставление путей с подстановочными знаками

Для сопоставления пути с подстановочным знаком можно использовать * после параметра, например /blog/:slug* будет соответствовать /blog/a/b/c/d/hello-world:

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Сопоставленные параметры могут использоваться в destination
        permanent: true,
      },
    ]
  },
}

Сопоставление путей с регулярными выражениями

Для сопоставления пути с регулярным выражением можно обернуть regex в скобки после параметра, например /post/:slug(\\d{1,}) будет соответствовать /post/123, но не /post/abc:

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Сопоставленные параметры могут использоваться в destination
        permanent: false,
      },
    ]
  },
}

Следующие символы (, ), {, }, :, *, +, ? используются для сопоставления путей с регулярными выражениями, поэтому при использовании в source как обычные значения они должны быть экранированы добавлением \\ перед ними:

next.config.js
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.
next.config.js
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 к перенаправлению:

next.config.js
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 для правильного сопоставления.

next.config.js
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.