Variables de entorno en Next.js: .env, NEXT_PUBLIC_ | We.Inc
Cómo carga Next.js los archivos .env, en qué orden, qué hace realmente NEXT_PUBLIC_ en el build y cómo leer valores en runtime. Pega tu .env para ver qué llega al navegador.
Next.js lee los archivos .env de la raíz del proyecto y los carga en process.env. Por defecto, las variables solo existen en el servidor. Si antepones NEXT_PUBLIC_ a un nombre, Next.js copia su valor en el JavaScript del navegador durante next build, así que pasa a ser público y queda fijo hasta que vuelvas a hacer el build. Nunca pongas un secreto detrás de ese prefijo.
Orden de carga: gana el primer archivo que define una variable
Orden
Origen
Notas
Los valores ya definidos por el shell o el hosting siempre ganan
.env.$(NODE_ENV).local
Por ejemplo .env.development.local
.env.local
Se omite cuando NODE_ENV es test
.env.$(NODE_ENV)
Por ejemplo .env.production
.env
Valores por defecto compartidos por todos los entornos
Pega abajo el contenido de un archivo .env. El comprobador clasifica cada variable como solo de servidor o enviada al navegador, y señala los nombres públicos que parecen secretos. Funciona por completo en esta página; nada de lo que pegues se sube.
Pega las líneas de tu .env en el cuadro, o edita el ejemplo.
Lee la tabla: cada variable aparece como solo de servidor o enviada al navegador.
Actúa ante cualquier aviso, como un nombre NEXT_PUBLIC_ que contenga KEY, SECRET o TOKEN.
Vuelve a hacer el build después de cambiar cualquier valor NEXT_PUBLIC_, porque el valor antiguo está incrustado en el bundle.
Deja los archivos .env en la raíz del proyecto, aunque tu código esté en una carpeta src. Next.js no los busca dentro de src.
Haz commit de .env y .env.test con valores seguros por defecto si tu equipo los quiere, pero nunca de los archivos .env*.local.
Lee las variables públicas por su nombre literal completo. process.env[name] o un process.env desestructurado no se sustituyen en el build.
¿Necesitas una sola imagen Docker para staging y producción? Lee las variables de servidor durante el renderizado dinámico y pasa como props lo que necesite el navegador.
Usa loadEnvConfig de @next/env para cargar los mismos archivos en la configuración de un ORM, un script o un entorno de tests fuera de Next.js.
Preguntas frecuentes
¿Por qué mi variable de entorno es undefined en el navegador?
Sin el prefijo NEXT_PUBLIC_ una variable solo existe en el servidor, y Next.js la sustituye por una cadena vacía en el código del cliente. Añade el prefijo solo si el valor se puede publicar sin riesgo, y vuelve a hacer el build.
Cambié un valor NEXT_PUBLIC_ en mi hosting y no pasó nada. ¿Por qué?
Los valores públicos se incrustan al ejecutar next build. Un bundle desplegado conserva el valor antiguo hasta que vuelvas a hacer el build con el nuevo.
¿Funciona .env.local en los tests?
No. Cuando NODE_ENV es test, Next.js omite .env.local para que cada ejecución de tests reciba los mismos valores. Pon los valores por defecto de test en .env.test y tus overrides personales en .env.test.local.
¿Puede una variable hacer referencia a otra?
Sí. Escribe $OTHER_NAME dentro de un valor y Next.js lo expande. Si el valor necesita un signo de dólar literal, escápalo como \$.
¿Qué valor tiene NODE_ENV?
Si no lo defines, next dev usa development y el resto de comandos usan production. Los valores permitidos son production, development y test.
Qué hace realmente NEXT_PUBLIC_
El prefijo es una instrucción para el bundler. Durante next build, cada process.env.NEXT_PUBLIC_SOMETHING literal de tu código se sustituye por el valor del entorno en el que se ejecutó el build, y ese texto acaba en los archivos JavaScript que cualquiera puede descargar.
Eso tiene dos consecuencias. Primero, una variable pública nunca es secreta, se llame como se llame el archivo. Segundo, queda congelada: promover un build de staging a producción arrastra consigo el valor de staging.
Leer valores en runtime
El código de servidor puede leer cualquier variable, pública o no. Para asegurarte de que un valor se lee en cada petición y no en el build, renderiza la página de forma dinámica, por ejemplo haciendo await de connection() de next/server antes de leer process.env.
El navegador no puede leer en absoluto las variables de servidor. Si un Client Component necesita un valor en runtime, obtenlo de tu propio Route Handler o pásalo como prop desde un Server Component.
Protégete de las fugas
Un helper que lee una clave de API puede acabar importado en un Client Component por accidente. Añade import 'server-only' al principio de esos archivos y el build fallará si un archivo de cliente los incluye.
Leer variables en el código
Valor solo de servidor en un Route Handler
DB_URL no tiene prefijo, así que solo existe en el servidor. Los Route Handlers y los Server Components pueden leerla sin problema.
Valor público en un Client Component
Hace falta el nombre literal completo. En el build, Next.js lo cambia por el valor, así que el navegador ve una cadena normal.
Leer un valor en cada petición
Hacer await de connection() hace que la página se renderice de forma dinámica, así que el valor viene del servidor en ejecución y no del build.
loadEnvConfig aplica el mismo orden de carga, lo que mantiene los scripts y los entornos de tests sincronizados con la app.
Comprobador de .env
Pega líneas de .env
Dónde se puede leer cada variable
Variable
Disponible en
Nota
Solo servidor
Servidor y navegador (incrustada en el build)
No es una línea de variable
El nombre parece un secreto. Todo lo que lleva NEXT_PUBLIC_ es visible para cualquier visitante.
Hace referencia a {v}, que Next.js expande.
NODE_ENV solo acepta production, development o test.