En-têtes HTTP

Les en-têtes HTTP vous permettent de définir des en-têtes personnalisés sur la réponse à une requête entrante pour 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 motif 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 remplacement 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 ayant la valeur 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 expression régulière

Pour correspondre à un chemin avec une expression régulière, vous pouvez encapsuler l'expression 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 d'expressions régulières, 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',
          },
        ],
      },
    ]
  },
}

Correspondance d'en-têtes, cookies et requêtes

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, ces champs peuvent être utilisés. À 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 pourra être utilisé 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 la 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, `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 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

Next.js définit l'en-tête Cache-Control à public, max-age=31536000, immutable pour les ressources réellement immuables. Cela ne peut pas être remplacé. Ces fichiers immuables contiennent un hash SHA dans leur nom de fichier, ils peuvent donc être mis en cache indéfiniment. Par exemple, les imports d'images statiques. Vous ne pouvez pas définir d'en-têtes Cache-Control dans next.config.js pour ces ressources.

Cependant, vous pouvez définir des en-têtes Cache-Control pour d'autres réponses ou données.

Apprenez-en plus sur la mise en cache avec le routeur App.

Options

CORS

Le partage de ressources cross-origin (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 gestionnaires de route.

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 de résoudre proactivement les noms de domaine pour 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 au site 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 max-age de 2 ans. Cela bloque l'accès aux pages ou sous-domaines qui ne peuvent être servis qu'en HTTP.

{
  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 des exploits XSS pour les sites web qui permettent aux utilisateurs de téléverser et partager des fichiers.

Par exemple, un utilisateur essayant de télécharger une image, mais celle-ci étant traitée comme un autre Content-Type tel qu'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 depuis le 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 Politique de Sécurité du Contenu (Content Security Policy) à votre application.

Historique des versions

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