Redirecciones

Las redirecciones te permiten redirigir una ruta de solicitud entrante a una ruta de destino diferente.

Para usar redirecciones, puedes utilizar la clave redirects en next.config.js:

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

redirects es una función asíncrona que espera que se devuelva un array con objetos que contengan las propiedades source, destination y permanent:

  • source: patrón de la ruta de solicitud entrante.
  • destination: ruta a la que deseas redirigir.
  • permanent: true o false - si es true, se usará el código de estado 308 que indica a los clientes/motores de búsqueda que almacenen en caché la redirección permanentemente. Si es false, se usará el código 307 que es temporal y no se almacena en caché.

¿Por qué Next.js usa 307 y 308? Tradicionalmente se usaba 302 para redirecciones temporales y 301 para permanentes, pero muchos navegadores cambiaban el método de solicitud de la redirección a GET, independientemente del método original. Por ejemplo, si el navegador hacía una solicitud POST /v1/users que devolvía código de estado 302 con ubicación /v2/users, la solicitud posterior podría ser GET /v2/users en lugar del esperado POST /v2/users. Next.js usa los códigos 307 (temporal) y 308 (permanente) para preservar explícitamente el método de solicitud utilizado.

  • basePath: false o undefined - si es false, el basePath no se incluirá al hacer coincidencias, solo puede usarse para redirecciones externas.
  • locale: false o undefined - si no se debe incluir el locale al hacer coincidencias.
  • has: array de objetos has con las propiedades type, key y value.
  • missing: array de objetos missing con las propiedades type, key y value.

Las redirecciones se verifican antes del sistema de archivos, que incluye páginas y archivos /public.

Cuando se usa el enrutador Pages, las redirecciones no se aplican al enrutamiento del lado del cliente (Link, router.push) a menos que esté presente Middleware y coincida con la ruta.

Cuando se aplica una redirección, cualquier valor de consulta proporcionado en la solicitud se pasará al destino de la redirección. Por ejemplo, observa la siguiente configuración de redirección:

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

Bueno saber: Recuerda incluir la barra diagonal / antes de los dos puntos : en los parámetros de ruta de source y destination, de lo contrario la ruta se tratará como una cadena literal y podrías causar redirecciones infinitas.

Cuando se solicita /old-blog/post-1?hello=world, el cliente será redirigido a /blog/post-1?hello=world.

Coincidencia de Rutas

Se permiten coincidencias de rutas, por ejemplo /old-blog/:slug coincidirá con /old-blog/hello-world (sin rutas anidadas):

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug', // Los parámetros coincidentes pueden usarse en el destino
        permanent: true,
      },
    ]
  },
}

Coincidencia de Rutas con Comodín

Para hacer coincidir una ruta con comodín, puedes usar * después de un parámetro, por ejemplo /blog/:slug* coincidirá con /blog/a/b/c/d/hello-world:

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Los parámetros coincidentes pueden usarse en el destino
        permanent: true,
      },
    ]
  },
}

Coincidencia de Rutas con Expresiones Regulares

Para hacer coincidir una ruta con regex, puedes envolver la expresión regular entre paréntesis después de un parámetro, por ejemplo /post/:slug(\\d{1,}) coincidirá con /post/123 pero no con /post/abc:

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Los parámetros coincidentes pueden usarse en el destino
        permanent: false,
      },
    ]
  },
}

Los siguientes caracteres (, ), {, }, :, *, +, ? se usan para coincidencias de rutas con regex, por lo que cuando se usan en source como valores no especiales, deben escaparse agregando \\ antes:

next.config.js
module.exports = {
  async redirects() {
    return [
      {
        // esto coincidirá con `/english(default)/something` cuando se solicite
        source: '/english\\(default\\)/:slug',
        destination: '/en-us/:slug',
        permanent: false,
      },
    ]
  },
}

Coincidencia de Cabeceras, Cookies y Consultas

Para que una redirección coincida solo cuando los valores de cabecera, cookie o consulta también coincidan, se puede usar el campo has o missing. Tanto el source como todos los elementos has deben coincidir, y todos los elementos missing no deben coincidir para que se aplique la redirección.

Los elementos has y missing pueden tener los siguientes campos:

  • type: String - debe ser header, cookie, host o query.
  • key: String - clave del tipo seleccionado para hacer coincidir.
  • value: String o undefined - valor a verificar, si es undefined, cualquier valor coincidirá. Se puede usar una cadena tipo regex para capturar una parte específica del valor, ej. si se usa first-(?<paramName>.*) para first-second, entonces second será usable en el destino con :paramName.
next.config.js
module.exports = {
  async redirects() {
    return [
      // si está presente la cabecera `x-redirect-me`,
      // se aplicará esta redirección
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'header',
            key: 'x-redirect-me',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // si está presente la cabecera `x-dont-redirect`,
      // NO se aplicará esta redirección
      {
        source: '/:path((?!another-page$).*)',
        missing: [
          {
            type: 'header',
            key: 'x-do-not-redirect',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // si coinciden source, consulta y cookie,
      // se aplicará esta redirección
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // el valor page no estará disponible en el
            // destino ya que se proporciona value y no
            // usa un grupo de captura nombrado ej. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        permanent: false,
        destination: '/another/:path*',
      },
      // si está presente la cabecera `x-authorized` y
      // contiene un valor coincidente, se aplicará esta redirección
      {
        source: '/',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        permanent: false,
        destination: '/home?authorized=:authorized',
      },
      // si el host es `example.com`,
      // se aplicará esta redirección
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
    ]
  },
}

Redirecciones con soporte basePath

Al usar soporte basePath con redirecciones, cada source y destination se prefija automáticamente con el basePath a menos que agregues basePath: false a la redirección:

next.config.js
module.exports = {
  basePath: '/docs',

  async redirects() {
    return [
      {
        source: '/with-basePath', // automáticamente se convierte en /docs/with-basePath
        destination: '/another', // automáticamente se convierte en /docs/another
        permanent: false,
      },
      {
        // no agrega /docs ya que se establece basePath: false
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
        permanent: false,
      },
    ]
  },
}

Redirecciones con soporte i18n

Al usar soporte i18n con redirecciones, cada source y destination se prefija automáticamente para manejar los locales configurados a menos que agregues locale: false a la redirección. Si se usa locale: false, debes prefijar source y destination con un locale para que coincida correctamente.

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },

  async redirects() {
    return [
      {
        source: '/with-locale', // maneja automáticamente todos los locales
        destination: '/another', // pasa automáticamente el locale
        permanent: false,
      },
      {
        // no maneja locales automáticamente ya que se establece locale: false
        source: '/nl/with-locale-manual',
        destination: '/nl/another',
        locale: false,
        permanent: false,
      },
      {
        // esto coincide con '/' ya que `en` es el defaultLocale
        source: '/en',
        destination: '/en/another',
        locale: false,
        permanent: false,
      },
      // es posible hacer coincidir todos los locales incluso con locale: false
      {
        source: '/:locale/page',
        destination: '/en/newpage',
        permanent: false,
        locale: false,
      },
      {
        // esto se convierte a /(en|fr|de)/(.*) por lo que no coincidirá con
        // las rutas de nivel superior `/` o `/fr` como lo haría /:path*
        source: '/(.*)',
        destination: '/another',
        permanent: false,
      },
    ]
  },
}

En algunos casos raros, podrías necesitar asignar un código de estado personalizado para que clientes HTTP antiguos redirijan correctamente. En estos casos, puedes usar la propiedad statusCode en lugar de permanent, pero no ambas. Para garantizar compatibilidad con IE11, se agrega automáticamente una cabecera Refresh para el código de estado 308.

Otras Redirecciones

Historial de Versiones

VersiónCambios
v13.3.0Se agregó missing.
v10.2.0Se agregó has.
v9.5.0Se agregó redirects.

On this page