En-têtes HTTP

Les en-têtes (headers) vous permettent de définir des en-têtes HTTP personnalisés dans la réponse à une requête entrante sur un chemin donné.

Pour définir des en-têtes HTTP personnalisés, vous pouvez utiliser la clé headers dans next.config.js :

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'ma valeur d\'en-tête personnalisée',
          },
          {
            key: 'x-another-custom-header',
            value: 'mon autre valeur d\'en-tête personnalisée',
          },
        ],
      },
    ]
  },
}

headers est une fonction asynchrone qui attend un tableau d'objets avec les propriétés source et headers :

  • source : le modèle de chemin de la requête entrante.
  • headers : un tableau d'objets d'en-têtes de réponse, avec les propriétés key et value.
  • basePath : false ou undefined - si false, le basePath ne sera pas inclus lors de la correspondance, peut être utilisé uniquement pour les réécritures externes.
  • locale : false ou undefined - indique si la locale ne doit pas être incluse lors de la correspondance.
  • has : un tableau d'objets has avec les propriétés type, key et value.
  • missing : un tableau d'objets missing avec les propriétés type, key et value.

Les en-têtes sont vérifiés avant le système de fichiers, qui inclut les pages et les fichiers /public.

Comportement de substitution des en-têtes

Si deux en-têtes correspondent au même chemin et définissent la même clé d'en-tête, la dernière clé d'en-tête remplacera la première. Avec les en-têtes ci-dessous, le chemin /hello entraînera l'en-tête x-hello étant world car la dernière valeur définie est 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',
          },
        ],
      },
    ]
  },
}

Correspondance de chemin

Les correspondances de chemin sont autorisées, par exemple /blog/:slug correspondra à /blog/hello-world (pas de chemins imbriqués) :

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // Les paramètres correspondants peuvent être utilisés dans la valeur
          },
          {
            key: 'x-slug-:slug', // Les paramètres correspondants peuvent être utilisés dans la clé
            value: 'mon autre valeur d\'en-tête personnalisée',
          },
        ],
      },
    ]
  },
}

Correspondance de chemin avec joker

Pour correspondre à un chemin avec joker, vous pouvez utiliser * après un paramètre, par exemple /blog/:slug* correspondra à /blog/a/b/c/d/hello-world :

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // Les paramètres correspondants peuvent être utilisés dans la valeur
          },
          {
            key: 'x-slug-:slug*', // Les paramètres correspondants peuvent être utilisés dans la clé
            value: 'mon autre valeur d\'en-tête personnalisée',
          },
        ],
      },
    ]
  },
}

Correspondance de chemin avec regex

Pour correspondre à un chemin avec regex, vous pouvez encapsuler la regex entre parenthèses après un paramètre, par exemple /blog/:slug(\\d{1,}) correspondra à /blog/123 mais pas à /blog/abc :

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

Les caractères suivants (, ), {, }, :, *, +, ? sont utilisés pour la correspondance de chemin avec regex, donc lorsqu'ils sont utilisés dans source comme valeurs non spéciales, ils doivent être échappés en ajoutant \\ avant eux :

next.config.js
module.exports = {
  async headers() {
    return [
      {
        // cela correspondra à `/english(default)/something` demandé
        source: '/english\\(default\\)/:slug',
        headers: [
          {
            key: 'x-header',
            value: 'value',
          },
        ],
      },
    ]
  },
}

Pour appliquer un en-tête uniquement lorsque les valeurs d'en-tête, de cookie ou de requête correspondent également au champ has ou ne correspondent pas au champ missing, vous pouvez utiliser ces champs. À la fois source et tous les éléments has doivent correspondre, et tous les éléments missing ne doivent pas correspondre pour que l'en-tête soit appliqué.

Les éléments has et missing peuvent avoir les champs suivants :

  • type : String - doit être soit header, cookie, host, ou query.
  • key : String - la clé du type sélectionné à comparer.
  • value : String ou undefined - la valeur à vérifier, si undefined n'importe quelle valeur correspondra. Une chaîne de type regex peut être utilisée pour capturer une partie spécifique de la valeur, par exemple si la valeur first-(?<paramName>.*) est utilisée pour first-second, alors second sera utilisable dans la destination avec :paramName.
next.config.js
module.exports = {
  async headers() {
    return [
      // si l'en-tête `x-add-header` est présent,
      // l'en-tête `x-another-header` sera appliqué
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-add-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // si l'en-tête `x-no-header` n'est pas présent,
      // l'en-tête `x-another-header` sera appliqué
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-no-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // si la source, la requête et le cookie correspondent,
      // l'en-tête `x-authorized` sera appliqué
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // la valeur de page ne sera pas disponible dans les
            // clés/valeurs d'en-tête car value est fournie et
            // n'utilise pas un groupe de capture nommé, par exemple (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        headers: [
          {
            key: 'x-authorized',
            value: ':authorized',
          },
        ],
      },
      // si l'en-tête `x-authorized` est présent et
      // contient une valeur correspondante, l'en-tête `x-another-header` sera appliqué
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
      // si l'hôte est `example.com`,
      // cet en-tête sera appliqué
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
    ]
  },
}

En-têtes avec support de basePath

Lorsque vous utilisez le support de basePath avec des en-têtes, chaque source est automatiquement préfixé avec le basePath sauf si vous ajoutez basePath: false à l'en-tête :

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

  async headers() {
    return [
      {
        source: '/with-basePath', // devient /docs/with-basePath
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        source: '/without-basePath', // n'est pas modifié car basePath: false est défini
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
        basePath: false,
      },
    ]
  },
}

En-têtes avec support i18n

Lorsque vous utilisez le support i18n avec des en-têtes, chaque source est automatiquement préfixé pour gérer les locales configurées, sauf si vous ajoutez locale: false à l'en-tête. Si locale: false est utilisé, vous devez préfixer la source avec une locale pour qu'elle corresponde correctement.

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

  async headers() {
    return [
      {
        source: '/with-locale', // gère automatiquement toutes les locales
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // ne gère pas automatiquement les locales car locale: false est défini
        source: '/nl/with-locale-manual',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // cela correspond à '/' car `en` est la defaultLocale
        source: '/en',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // cela est converti en /(en|fr|de)/(.*) donc ne correspondra pas aux routes
        // de niveau supérieur `/` ou `/fr` comme /:path* le ferait
        source: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

Cache-Control

Vous ne pouvez pas définir les en-têtes Cache-Control dans next.config.js pour les pages ou les ressources, car ces en-têtes seront écrasés en production pour garantir que les réponses et les ressources statiques sont mises en cache efficacement.

Si vous avez besoin de revalider le cache d'une page qui a été générée statiquement, vous pouvez le faire en définissant la prop revalidate dans la fonction getStaticProps de la page.

Vous pouvez définir l'en-tête Cache-Control dans vos routes API en utilisant la méthode res.setHeader :

import type { NextApiRequest, NextApiResponse } from 'next'

type ResponseData = {
  message: string
}

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  res.setHeader('Cache-Control', 's-maxage=86400')
  res.status(200).json({ message: 'Hello from Next.js!' })
}
export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=86400')
  res.status(200).json({ message: 'Hello from Next.js!' })
}

Options

CORS

Cross-Origin Resource Sharing (CORS) est une fonctionnalité de sécurité qui vous permet de contrôler quels sites peuvent accéder à vos ressources. Vous pouvez définir l'en-tête Access-Control-Allow-Origin pour autoriser une origine spécifique à accéder à vos points de terminaison API.

async headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // Définissez votre origine
          },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET, POST, PUT, DELETE, OPTIONS",
          },
          {
            key: "Access-Control-Allow-Headers",
            value: "Content-Type, Authorization",
          },
        ],
      },
    ];
  },

X-DNS-Prefetch-Control

Cet en-tête contrôle la pré-résolution DNS, permettant aux navigateurs d'effectuer proactivement la résolution de nom de domaine sur les liens externes, images, CSS, JavaScript, etc. Cette pré-résolution est effectuée en arrière-plan, donc le DNS est plus susceptible d'être résolu au moment où les éléments référencés sont nécessaires. Cela réduit la latence lorsque l'utilisateur clique sur un lien.

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

Strict-Transport-Security

Cet en-tête informe les navigateurs qu'ils ne doivent accéder qu'en utilisant HTTPS, au lieu de HTTP. Avec la configuration ci-dessous, tous les sous-domaines présents et futurs utiliseront HTTPS pour une durée de max-age de 2 ans. Cela bloque l'accès aux pages ou sous-domaines qui ne peuvent être servis qu'en HTTP.

Si vous déployez sur Vercel, cet en-tête n'est pas nécessaire car il est automatiquement ajouté à tous les déploiements sauf si vous déclarez headers dans votre next.config.js.

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

X-Frame-Options

Cet en-tête indique si le site doit être autorisé à être affiché dans un iframe. Cela peut prévenir les attaques de clickjacking.

Cet en-tête a été remplacé par l'option frame-ancestors de CSP, qui a un meilleur support dans les navigateurs modernes (voir Content Security Policy pour les détails de configuration).

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

Permissions-Policy

Cet en-tête vous permet de contrôler quelles fonctionnalités et API peuvent être utilisées dans le navigateur. Il était précédemment nommé Feature-Policy.

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

X-Content-Type-Options

Cet en-tête empêche le navigateur de tenter de deviner le type de contenu si l'en-tête Content-Type n'est pas explicitement défini. Cela peut prévenir les exploits XSS pour les sites qui permettent aux utilisateurs de télécharger et partager des fichiers.

Par exemple, un utilisateur essayant de télécharger une image, mais celle-ci est traitée comme un autre Content-Type comme un exécutable, qui pourrait être malveillant. Cet en-tête s'applique également au téléchargement d'extensions de navigateur. La seule valeur valide pour cet en-tête est nosniff.

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

Referrer-Policy

Cet en-tête contrôle la quantité d'informations que le navigateur inclut lors de la navigation du site web actuel (origine) vers un autre.

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

Content-Security-Policy

Apprenez-en plus sur l'ajout d'une Content Security Policy à votre application.

Historique des versions

VersionChangements
v13.3.0missing ajouté.
v10.2.0has ajouté.
v9.5.0En-têtes ajoutés.