Spec-Zone.ru › Next.js

Переписывания

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

Переписывания действуют как прокси-сервер URL и маскируют целевой путь, создавая впечатление, что пользователь не изменил своё местоположение на сайте. В отличие от этого, перенаправления перенаправят на новую страницу и покажут изменения URL.

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

module.exports = {
  async rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ]
  },
}

Переписывания применяются к маршрутизации на стороне клиента, переписывание будет применено в приведённом выше примере.

rewrites — это асинхронная функция, которая ожидает возврата массива или объекта массивов (см. ниже), содержащих объекты со свойствами source и destination:

  • source: String — это шаблон входящего пути запроса.
  • destination: String — это путь, на который вы хотите перенаправить.
  • basePath: false или undefined — если ложно, basePath не будет включён при сопоставлении, может использоваться только для внешних переписываний.
  • locale: false или undefined — указывает, следует ли не включать локаль при сопоставлении.
  • has — массив объектов со свойствaми со свойствами type, key и value.
  • missing — массив отсутствующих объектов со свойствами type, key и value.

Когда функция rewrites возвращает массив, переписывания применяются после проверки файловой системы (страниц и файлов /public) и до динамических маршрутов. Когда функция rewrites возвращает объект массивов со специфической структурой, это поведение можно изменить и более точно контролировать, начиная с v10.1 Next.js:

module.exports = {
  async rewrites() {
    return {
      beforeFiles: [
        // These rewrites are checked after headers/redirects
        // and before all files including _next/public files which
        // allows overriding page files
        {
          source: '/some-page',
          destination: '/somewhere-else',
          has: [{ type: 'query', key: 'overrideMe' }],
        },
      ],
      afterFiles: [
        // These rewrites are checked after pages/public files
        // are checked but before dynamic routes
        {
          source: '/non-existent',
          destination: '/somewhere-else',
        },
      ],
      fallback: [
        // These rewrites are checked after both pages/public files
        // and dynamic routes are checked
        {
          source: '/:path*',
          destination: `https://my-old-site.com/:path*`,
        },
      ],
    }
  },
}

Важно знать: переписывания в beforeFiles не проверяют файловую систему/динамические маршруты сразу после сопоставления источника, они продолжаются до тех пор, пока все beforeFiles не будут проверены.

Порядок проверки маршрутов Next.js:

  1. Проверяются/применяются заголовки.
  2. Проверяются/применяются перенаправления.
  3. Проверяются/применяются переписывания.
  4. Проверяются/отображаются статические файлы из каталога public, файлов _next/static и статических страниц, не являющихся динамическими.
  5. Проверяются/применяются переписывания, если одно из этих переписываний совпадает, мы проверяем динамические маршруты/статические файлы после каждого совпадения.
  6. Проверяются/применяются переписывания, эти переписывания применяются перед рендерингом страницы 404 и после проверки динамических маршрутов/всех статических ресурсов. Если вы используете fallback: true/'blocking' в getStaticPaths, резервный rewrites в вашем next.config.js не будет выполнен.

Параметры переписывания

При использовании параметров в переписывании параметры будут передаваться в запросе по умолчанию, если ни один из параметров не используется в destination.

module.exports = {
  async rewrites() {
    return [
      {
        source: '/old-about/:path*',
        destination: '/about', // The :path parameter isn't used here so will be automatically passed in the query
      },
    ]
  },
}

Если параметр используется в пункте назначения, ни один из параметров не будет автоматически передан в запросе.

module.exports = {
  async rewrites() {
    return [
      {
        source: '/docs/:path*',
        destination: '/:path*', // The :path parameter is used here so will not be automatically passed in the query
      },
    ]
  },
}

Вы по-прежнему можете передавать параметры вручную в запросе, если один из них уже используется в пункте назначения, указав запрос в destination.

module.exports = {
  async rewrites() {
    return [
      {
        source: '/:first/:second',
        destination: '/:first?second=:second',
        // Since the :first parameter is used in the destination the :second parameter
        // will not automatically be added in the query although we can manually add it
        // as shown above
      },
    ]
  },
}

Важно знать: Статические страницы из Автоматической статической оптимизации или пререндеринга параметры из переписываний будут обработаны на клиенте после гидратации и предоставлены в запросе.

Сопоставление путей

Разрешено сопоставление путей, например, /blog/:slug будет соответствовать /blog/hello-world (без вложенных путей):

module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog/:slug',
        destination: '/news/:slug', // Matched parameters can be used in the destination
      },
    ]
  },
}

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

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

module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Matched parameters can be used in the destination
      },
    ]
  },
}

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

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

module.exports = {
  async rewrites() {
    return [
      {
        source: '/old-blog/:post(\\d{1,})',
        destination: '/blog/:post', // Matched parameters can be used in the destination
      },
    ]
  },
}

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

module.exports = {
  async rewrites() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        destination: '/en-us/:slug',
      },
    ]
  },
}

Сопоставление заголовков, куки и запроса

Чтобы сопоставить переписывание только тогда, когда значения заголовков, куки или запроса также соответствуют полю has или не соответствуют полю missing, можно использовать. Как поле source, так и все элементы has должны соответствовать, а все элементы missing не должны соответствовать для применения переписывания.

Элементы has и missing могут иметь следующие поля:

  • type: String — должно быть header, cookie, host, или query.
  • key: String — ключ из выбранного типа для сопоставления.
  • value: String или undefined — значение для проверки, если не определено, любое значение будет соответствовать. Можно использовать регулярное выражение, например, если значение first-(?<paramName>.*) используется для first-second, то second будет доступно в пункте назначения со значением :paramName.
module.exports = {
  async rewrites() {
    return [
      // if the header `x-rewrite-me` is present,
      // this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-rewrite-me',
          },
        ],
        destination: '/another-page',
      },
      // if the header `x-rewrite-me` is not present,
      // this rewrite will be applied
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-rewrite-me',
          },
        ],
        destination: '/another-page',
      },
      // if the source, query, and cookie are matched,
      // this rewrite 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',
          },
        ],
        destination: '/:path*/home',
      },
      // if the header `x-authorized` is present and
      // contains a matching value, this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        destination: '/home?authorized=:authorized',
      },
      // if the host is `example.com`,
      // this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        destination: '/another-page',
      },
    ]
  },
}

Переписывание на внешний URL

Примеры
  • Поэтапное внедрение Next.js
  • Использование нескольких зон

Переписывания позволяют переписывать на внешний URL. Это особенно полезно для поэтапного внедрения Next.js. Ниже приведен пример переписывания для перенаправления маршрута /blog вашего основного приложения на внешний сайт.

module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog',
        destination: 'https://example.com/blog',
      },
      {
        source: '/blog/:slug',
        destination: 'https://example.com/blog/:slug', // Matched parameters can be used in the destination
      },
    ]
  },
}

Если вы используете trailingSlash: true, вам также необходимо вставить конечный слэш в параметр source. Если целевой сервер также ожидает конечный слэш, он должен быть включён в параметр destination.

module.exports = {
  trailingSlash: true,
  async rewrites() {
    return [
      {
        source: '/blog/',
        destination: 'https://example.com/blog/',
      },
      {
        source: '/blog/:path*/',
        destination: 'https://example.com/blog/:path*/',
      },
    ]
  },
}

Поэтапное внедрение Next.js

Вы также можете настроить Next.js перенаправлять на существующий веб-сайт после проверки всех маршрутов Next.js.

Таким образом, вам не нужно изменять конфигурацию переписываний при миграции большего количества страниц в Next.js

module.exports = {
  async rewrites() {
    return {
      fallback: [
        {
          source: '/:path*',
          destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
        },
      ],
    }
  },
}

Переписывания с поддержкой basePath

При использовании поддержки basePath с переписываниями каждый source и destination автоматически предваряется basePath, если вы не добавите basePath: false в переписывание:

module.exports = {
  basePath: '/docs',
 
  async rewrites() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', // automatically becomes /docs/another
      },
      {
        // does not add /docs to /without-basePath since basePath: false is set
        // Note: this can not be used for internal rewrites e.g. `destination: '/another'`
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
      },
    ]
  },
}

Переписывания с поддержкой i18n

При использовании поддержки i18n с переписываниями каждый source и destination автоматически предваряется, чтобы обрабатывать конфигурированный locales, если вы не добавите locale: false в переписывание. Если используется locale: false, вы должны префикс source и destination с локалью, чтобы её корректно сопоставить.

module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },
 
  async rewrites() {
    return [
      {
        source: '/with-locale', // automatically handles all locales
        destination: '/another', // automatically passes the locale on
      },
      {
        // does not handle locales automatically since locale: false is set
        source: '/nl/with-locale-manual',
        destination: '/nl/another',
        locale: false,
      },
      {
        // this matches '/' since `en` is the defaultLocale
        source: '/en',
        destination: '/en/another',
        locale: false,
      },
      {
        // it's possible to match all locales even when locale: false is set
        source: '/:locale/api-alias/:path*',
        destination: '/api/:path*',
        locale: false,
      },
      {
        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level
        // `/` or `/fr` routes like /:path* would
        source: '/(.*)',
        destination: '/another',
      },
    ]
  },
}

История версий

Версия Изменения
v13.3.0 missing добавлено.
v10.2.0 has добавлено.
v9.5.0 Добавлены заголовки.

© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/api-reference/next-config-js/rewrites

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API