Encabezados (headers)

Los encabezados permiten establecer encabezados HTTP personalizados en la respuesta a una solicitud entrante en una ruta determinada.

Para configurar encabezados HTTP personalizados, puede usar la clave headers en next.config.js:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'mi valor de encabezado personalizado',
          },
          {
            key: 'x-another-custom-header',
            value: 'mi otro valor de encabezado personalizado',
          },
        ],
      },
    ]
  },
}

headers es una función asíncrona que espera que se devuelva un array con objetos que tengan las propiedades source y headers:

  • source: patrón de ruta de la solicitud entrante.
  • headers: array de objetos de encabezado de respuesta, con propiedades key y value.
  • basePath: false o undefined - si es false, el basePath no se incluirá al hacer coincidencias, solo se puede usar para reescrituras externas.
  • locale: false o undefined - indica si no se debe incluir la configuración regional 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.

Los encabezados se verifican antes del sistema de archivos, que incluye páginas y archivos en /public.

Comportamiento de Sobrescritura de Encabezados

Si dos encabezados coinciden con la misma ruta y establecen la misma clave de encabezado, la última clave de encabezado sobrescribirá la primera. Usando los encabezados a continuación, la ruta /hello resultará en que el encabezado x-hello sea world debido a que el último valor de encabezado establecido es world.

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'x-hello',
            value: 'there',
          },
        ],
      },
      {
        source: '/hello',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

Coincidencia de Rutas

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

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // Los parámetros coincidentes pueden usarse en el valor
          },
          {
            key: 'x-slug-:slug', // Los parámetros coincidentes pueden usarse en la clave
            value: 'mi otro valor de encabezado personalizado',
          },
        ],
      },
    ]
  },
}

Coincidencia de Rutas con Comodín

Para coincidir con una ruta comodín, puede 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 headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // Los parámetros coincidentes pueden usarse en el valor
          },
          {
            key: 'x-slug-:slug*', // Los parámetros coincidentes pueden usarse en la clave
            value: 'mi otro valor de encabezado personalizado',
          },
        ],
      },
    ]
  },
}

Coincidencia de Rutas con Expresiones Regulares

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

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:post(\\d{1,})',
        headers: [
          {
            key: 'x-post',
            value: ':post',
          },
        ],
      },
    ]
  },
}

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 de ellos:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        // esto coincidirá con `/english(default)/something` cuando se solicite
        source: '/english\\(default\\)/:slug',
        headers: [
          {
            key: 'x-header',
            value: 'value',
          },
        ],
      },
    ]
  },
}

Coincidencia de Encabezados, Cookies y Consultas

Para aplicar un encabezado solo cuando los valores de encabezado, cookie o consulta también coincidan, se puede usar el campo has o no coincidan con el campo missing. Tanto source como todos los elementos has deben coincidir, y todos los elementos missing no deben coincidir para que se aplique el encabezado.

Los elementos has y missing pueden tener los siguientes campos:

  • type: String - debe ser header, cookie, host o query.
  • key: String - la clave del tipo seleccionado para coincidir.
  • value: String o undefined - el valor a verificar, si es undefined cualquier valor coincidirá. Se puede usar una cadena tipo regex para capturar una parte específica del valor, por ejemplo, si se usa el valor first-(?<paramName>.*) para first-second, entonces second será utilizable en el destino con :paramName.
next.config.js
module.exports = {
  async headers() {
    return [
      // si el encabezado `x-add-header` está presente,
      // se aplicará el encabezado `x-another-header`
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-add-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // si el encabezado `x-no-header` no está presente,
      // se aplicará el encabezado `x-another-header`
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-no-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // si coinciden la fuente, la consulta y la cookie,
      // se aplicará el encabezado `x-authorized`
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // el valor de page no estará disponible en las
            // claves/valores del encabezado ya que se proporciona value y
            // no usa un grupo de captura con nombre, ej. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        headers: [
          {
            key: 'x-authorized',
            value: ':authorized',
          },
        ],
      },
      // si el encabezado `x-authorized` está presente y
      // contiene un valor coincidente, se aplicará `x-another-header`
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
      // si el host es `example.com`,
      // se aplicará este encabezado
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
    ]
  },
}

Encabezados con soporte para basePath

Cuando se usa el soporte para basePath con encabezados, cada source se prefija automáticamente con el basePath a menos que agregue basePath: false al encabezado:

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

  async headers() {
    return [
      {
        source: '/with-basePath', // se convierte en /docs/with-basePath
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        source: '/without-basePath', // no se modifica ya que se establece basePath: false
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
        basePath: false,
      },
    ]
  },
}

Encabezados con soporte para i18n

Cuando se usa el soporte para i18n con encabezados, cada source se prefija automáticamente para manejar los locales configurados, a menos que agregue locale: false al encabezado. Si se usa locale: false, debe prefijar el source con un locale para que coincida correctamente.

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

  async headers() {
    return [
      {
        source: '/with-locale', // maneja automáticamente todos los locales
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // no maneja locales automáticamente ya que se establece locale: false
        source: '/nl/with-locale-manual',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // esto coincide con '/' ya que `en` es el defaultLocale
        source: '/en',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // 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: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

Cache-Control

No puede establecer encabezados Cache-Control en next.config.js para páginas o recursos, ya que estos encabezados se sobrescribirán en producción para garantizar que las respuestas y los recursos estáticos se almacenen en caché de manera efectiva.

Aprenda más sobre caché con el Enrutador de Aplicación.

Opciones

X-DNS-Prefetch-Control

Este encabezado controla la precarga de DNS, permitiendo que los navegadores realicen proactivamente la resolución de nombres de dominio en enlaces externos, imágenes, CSS, JavaScript y más. Esta precarga se realiza en segundo plano, por lo que es más probable que el DNS se resuelva cuando se necesiten los elementos referenciados. Esto reduce la latencia cuando el usuario hace clic en un enlace.

{
  key: 'X-DNS-Prefetch-Control',
  value: 'on'
}

Strict-Transport-Security

Este encabezado informa a los navegadores que solo se debe acceder mediante HTTPS, en lugar de HTTP. Usando la configuración a continuación, todos los subdominios presentes y futuros usarán HTTPS durante un max-age de 2 años. Esto bloquea el acceso a páginas o subdominios que solo se pueden servir a través de HTTP.

Si está implementando en Vercel, este encabezado no es necesario ya que se agrega automáticamente a todas las implementaciones a menos que declare headers en su next.config.js.

{
  key: 'Strict-Transport-Security',
  value: 'max-age=63072000; includeSubDomains; preload'
}

X-Frame-Options

Este encabezado indica si se debe permitir que el sitio se muestre dentro de un iframe. Esto puede prevenir ataques de clickjacking.

Este encabezado ha sido reemplazado por la opción frame-ancestors de CSP, que tiene mejor soporte en navegadores modernos.

{
  key: 'X-Frame-Options',
  value: 'SAMEORIGIN'
}

Permissions-Policy

Este encabezado le permite controlar qué funciones y APIs se pueden usar en el navegador. Anteriormente se llamaba Feature-Policy.

{
  key: 'Permissions-Policy',
  value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}

X-Content-Type-Options

Este encabezado evita que el navegador intente adivinar el tipo de contenido si el encabezado Content-Type no está configurado explícitamente. Esto puede prevenir exploits XSS en sitios web que permiten a los usuarios subir y compartir archivos.

Por ejemplo, un usuario que intenta descargar una imagen, pero que se trata como un Content-Type diferente, como un ejecutable, que podría ser malicioso. Este encabezado también se aplica a la descarga de extensiones del navegador. El único valor válido para este encabezado es nosniff.

{
  key: 'X-Content-Type-Options',
  value: 'nosniff'
}

Referrer-Policy

Este encabezado controla cuánta información incluye el navegador al navegar desde el sitio web actual (origen) a otro.

{
  key: 'Referrer-Policy',
  value: 'origin-when-cross-origin'
}

Content-Security-Policy

Aprenda más sobre cómo agregar una Política de Seguridad de Contenido (Content Security Policy) a su aplicación.

Historial de Versiones

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