Fait partie de Hébergement par cadricielNext.js · Dépannage

Variables d’environnement Next.js undefined en production : compilation ou exécution.

next build remplace chaque process.env.NEXT_PUBLIC_* par sa valeur à ce moment-là. Si la variable n’existait pas pendant la compilation, le navigateur reçoit undefined, et la définir après ne change rien tant que vous ne recompilez pas. Les variables serveur se lisent à l’exécution, sauf dans les pages que Next.js prérend pendant la compilation.

Faits vérifiés le

Quand chaque valeur est figée

Trouvez la ligne qui correspond à l’endroit où votre code lit la variable. La colonne du milieu indique le moment où sa valeur est fixée; tout changement fait après ce moment lui échappe.

Où elle est lueValeur figée àPour la changer
NEXT_PUBLIC_* dans un composant client †next build : intégrée au paquet JavaScriptRecompiler
NEXT_PUBLIC_* dans le code serveur †next build : intégrée là aussiRecompiler
Variable serveur dans une page dynamique, un Route Handler ou une Server Action † †À chaque requête, depuis process.envRedémarrer le serveur avec la nouvelle valeur
Variable serveur dans une page prérendue à la compilation †next build : le HTML est rendu à ce momentRecompiler, ou rendre la page dynamique avec await connection()
Tout ce qui est lu dans next.config.* †next buildRecompiler

† Les détails sur les concurrents proviennent des pages publiées par chaque fournisseur aux dates indiquées; les prix et forfaits changent, vérifiez auprès du fournisseur avant de décider. `NEXT_PUBLIC_*` dans un composant client (2026-10-29) · `NEXT_PUBLIC_*` dans le code serveur (2026-10-29) · Variable serveur dans une page dynamique, un Route Handler ou une Server Action (2026-10-29) · Variable serveur dans une page dynamique, un Route Handler ou une Server Action (2026-10-29) · Variable serveur dans une page prérendue à la compilation (2026-10-29) · Tout ce qui est lu dans `next.config.*` (2026-10-29)

Pourquoi une variable définie après la compilation n’atteint jamais le navigateur

Le navigateur n’a pas de process.env. Pour donner une valeur au code client, Next.js fait un remplacement de texte pendant next build : chaque process.env.NEXT_PUBLIC_X littéral devient la chaîne qu’il avait sur la machine de compilation. La documentation de Next.js est claire : après la compilation, l’appli « ne réagit plus aux changements de ces variables d’environnement ».

  • Définie pendant la compilation, ou inexistante. Un hébergeur qui n’injecte les variables qu’au démarrage de l’appli, ou une image Docker compilée sans elles, produit un paquet rempli de undefined.
  • Une image, plusieurs environnements : ça ne marche pas pour `NEXT_PUBLIC_`. Promouvez une compilation de préproduction en production, et le navigateur garde les valeurs de préproduction.
  • Docker : passez les valeurs destinées au navigateur en ARG dans l’étape de compilation, car un ENV défini seulement dans l’étape finale arrive après next build. Les secrets serveur vont dans l’environnement d’exécution, pas dans ARG, où ils se retrouvent dans l’historique de l’image.
// What you wrote (a client component)
const api = process.env.NEXT_PUBLIC_API_URL;

// What `next build` ships to the browser
const api = "https://api.example.com";

// ...or, if the variable wasn't set when the build ran
const api = undefined;

// Never inlined: dynamic lookups stay undefined in the browser
const name = "NEXT_PUBLIC_API_URL";
process.env[name];
const env = process.env;
env.NEXT_PUBLIC_API_URL;

Des variables serveur encore undefined

Les variables sans préfixe restent sur le serveur et sont lues dans process.env au moment où le code s’exécute. Quand l’une d’elles reste undefined, c’est en général pour l’une de ces raisons :

  • La page a été prérendue. Une page sans API liée à la requête (cookies(), headers(), connection()) est rendue pendant next build. Toute variable qu’elle lit est figée dans son HTML, et une variable qui n’existe qu’à l’exécution y vaut undefined. Appelez await connection() dans la page pour la rendre à chaque requête, comme le montre le guide d’auto-hébergement.
  • Elle est dans `.env.local`. Ce fichier est ignoré par Git par défaut : il ne quitte jamais votre portable. Définissez la valeur chez l’hébergeur.
  • Vous la lisez dans un composant client. Sans NEXT_PUBLIC_, le code client reçoit undefined, à dessein. Lisez-la dans un composant serveur et passez-la en prop.
  • Le fichier `.env` est dans `src/`. Next.js ne charge les fichiers .env* qu’à la racine du projet.

Comment les variables atteignent une compilation Next.js sur Canner

Vous définissez les variables sous l’onglet Variables d’environnement du projet. Chacune a une portée qui décide quelles phases la reçoivent :

  • **NEXT_PUBLIC_* ne doit pas être en exécution seulement. Cette portée tient la valeur hors de la compilation, précisément le moment où Next.js l’intègre. Le navigateur reçoit `undefined`. Choisissez production ou toutes**.
  • Un secret en exécution seulement lu dans une page statique vaut aussi `undefined`, pour la même raison. Rendez cette page dynamique, ou déplacez la lecture dans un Route Handler ou une Server Action.
  • Les modifications s’appliquent au prochain déploiement, variables serveur comprises. Chaque déploiement emporte sa propre copie de vos variables : redéployez après en avoir changé une. Le journal de compilation confirme ce qui est entré : [canner] wrote 12 env var(s) to .env.production (build phase).
  • Un `.env.production` versionné est remplacé. Canner écrit les variables du projet dans .env.production pour la compilation, puis de nouveau pour l’appli en marche. Gardez les valeurs par défaut communes dans .env, que Next.js lit en dernier, ou déplacez-les dans l’onglet Variables d’environnement.
  • Les aperçus sont des compilations distinctes. Une variable NEXT_PUBLIC_ à portée aperçu n’est intégrée qu’aux compilations d’aperçu : les aperçus peuvent diriger le navigateur vers une API de préproduction sans toucher à la production.
PortéeCompilationCommande de mise en productionAppli en marcheAperçus
productionOuiOuiOuiNon
aperçuCompilations d’aperçuNonApplis d’aperçuOui
toutesOuiOuiOuiOui
exécution seulementNonNonOui, en productionNon

Une configuration lue à l’exécution pour le navigateur

Quand une valeur destinée au navigateur doit changer sans recompilation, cessez d’utiliser NEXT_PUBLIC_ pour elle et servez-la à l’exécution. Deux façons de faire couvrent la plupart des applis.

La passer depuis un composant serveur. La valeur est lue à chaque requête et remise au composant client en prop :

// app/settings/page.tsx (server component)
import { connection } from "next/server";
import { SettingsForm } from "./settings-form"; // "use client"

export default async function Page() {
  await connection(); // this page renders at request time
  return <SettingsForm apiUrl={process.env.API_URL!} />;
}

Un point de terminaison de configuration publique

La même idée, sous forme de point de terminaison. L’appel à connection() empêche Next.js de rendre la réponse une seule fois à la compilation :

  • Pour vérifier ce qu’une compilation a vraiment intégré, cherchez la valeur dans les fragments client : grep -rl "api.example.com" .next/static/chunks. Aucun résultat : la variable était vide à la compilation.
  • Si le nom NEXT_PUBLIC_API_URL apparaît encore dans un fragment, le code le lit de façon dynamique et il n’a jamais été intégré.
// app/api/public-config/route.ts
import { connection } from "next/server";

export async function GET() {
  await connection(); // read per request, not frozen at build
  // Only values that are safe for anyone to see.
  return Response.json({
    apiUrl: process.env.API_URL,
    mapsKey: process.env.MAPS_BROWSER_KEY,
  });
}

Questions

Pourquoi ma variable NEXT_PUBLIC_ est-elle undefined en production alors qu’elle marche en local?

En local, next dev la lit dans votre fichier .env. En production, elle doit exister dans l’environnement où next build s’exécute, puisqu’elle est intégrée au paquet à ce moment-là. Définissez-la chez l’hébergeur pour la compilation, puis recompilez.

Faut-il recompiler après avoir changé une variable d’environnement?

Pour les variables NEXT_PUBLIC_, pour tout ce qui est lu dans next.config et pour les pages prérendues : oui. Les variables serveur lues à chaque requête demandent seulement un redémarrage. Sur Canner, tout changement s’applique au prochain déploiement.

Peut-on changer une variable NEXT_PUBLIC_ à l’exécution?

Non. Après la compilation, c’est une chaîne littérale dans votre JavaScript. Pour une valeur qui doit changer sans recompilation, lisez-la sur le serveur et passez-la au client, ou servez-la depuis un Route Handler.

Pourquoi mon .env.local ne fonctionne-t-il pas en production?

Il n’est pas déployé. .env.local est fait pour votre machine et il est ignoré par Git dans les nouveaux projets Next.js. Mettez plutôt les valeurs dans les variables d’environnement de votre hébergeur.

Déployez Next.js et ses variables à Montréal.

Collez votre .env dans l’éditeur en lot, choisissez une portée pour chaque valeur et déployez. Ou définissez-les avec le CLI.