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 lue | Valeur figée à | Pour la changer |
|---|---|---|
NEXT_PUBLIC_* dans un composant client † | next build : intégrée au paquet JavaScript | Recompiler |
NEXT_PUBLIC_* dans le code serveur † | next build : intégrée là aussi | Recompiler |
| Variable serveur dans une page dynamique, un Route Handler ou une Server Action † † | À chaque requête, depuis process.env | Redémarrer le serveur avec la nouvelle valeur |
| Variable serveur dans une page prérendue à la compilation † | next build : le HTML est rendu à ce moment | Recompiler, ou rendre la page dynamique avec await connection() |
Tout ce qui est lu dans next.config.* † | next build | Recompiler |
† 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
ARGdans l’étape de compilation, car unENVdéfini seulement dans l’étape finale arrive aprèsnext build. Les secrets serveur vont dans l’environnement d’exécution, pas dansARG, 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 pendantnext build. Toute variable qu’elle lit est figée dans son HTML, et une variable qui n’existe qu’à l’exécution y vautundefined. Appelezawait 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çoitundefined, à 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.productionpour 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ée | Compilation | Commande de mise en production | Appli en marche | Aperçus |
|---|---|---|---|---|
| production | Oui | Oui | Oui | Non |
| aperçu | Compilations d’aperçu | Non | Applis d’aperçu | Oui |
| toutes | Oui | Oui | Oui | Oui |
| exécution seulement | Non | Non | Oui, en production | Non |
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_URLapparaî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.
À lire aussi
- GuideVite : import.meta.env undefined en production
- GuideÉchec de compilation : lire le journal et corriger
- GuideJavaScript heap out of memory à la compilation
- GuideOù exécuter les migrations lors d’un déploiement
- GuideDéploiement sans interruption et sondes d’état
- RubyHébergement Ruby on Rails au Canada
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.