Solución: variables de entorno undefined en Next.js
process.env.MI_VARIABLE devuelve undefined en Next.js aunque la hayas definido. Las reglas de prefijos NEXT_PUBLIC_, cuándo se leen y cómo depurar el problema.
¿Por qué ocurre?
Next.js tiene reglas estrictas sobre las variables de entorno: solo las que empiezan por NEXT_PUBLIC_ son accesibles desde el navegador (lado cliente). Las demás solo están disponibles en el servidor. Además, Next.js lee el .env en tiempo de build, no en runtime — si cambias el .env debes reiniciar el servidor.
Solución paso a paso
Reglas de prefijos en Next.js:
# .env.local# ✅ Accesible en el cliente Y en el servidor
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_STRIPE_KEY=pk_test_xxx
# ✅ Solo accesible en el SERVIDOR (getServerSideProps, API routes, Server Components)
DATABASE_URL=postgresql://...
STRIPE_SECRET_KEY=sk_test_xxx
JWT_SECRET=mi-secreto
Uso correcto en el cliente:
// ❌ Variable sin NEXT_PUBLIC_ — undefined en el cliente
const url = process.env.API_URL; // undefined// ✅ Con NEXT_PUBLIC_
const url = process.env.NEXT_PUBLIC_API_URL; // funciona en cliente
Uso correcto en el servidor:
// ✅ En getServerSideProps, getStaticProps, API routes — todas las variables disponibles
export async function getServerSideProps() {
const db = process.env.DATABASE_URL; // ✅ funciona
const publicUrl = process.env.NEXT_PUBLIC_API_URL; // ✅ también
// ...
}// ✅ En App Router — Server Components
// app/page.tsx (Server Component por defecto)
export default function Page() {
const dbUrl = process.env.DATABASE_URL; // ✅ solo en servidor
}
Archivos .env y su prioridad:
.env # base, siempre cargado
.env.local # local, sobreescribe .env, NO subir a git
.env.development # solo en npm run dev
.env.production # solo en npm run build
.env.test # solo en tests
# Prioridad: .env.local > .env.[entorno] > .env
Pasos de debug cuando sigue siendo undefined:
# 1. ¿Reiniciaste el servidor después de editar .env?
# Ctrl+C → npm run dev# 2. ¿El archivo se llama .env.local (no .env)?
ls -la | grep .env
# 3. ¿Hay espacios alrededor del = ?
# ❌ NEXT_PUBLIC_URL = https://api.com
# ✅ NEXT_PUBLIC_URL=https://api.com
# 4. Imprime todas las variables disponibles
console.log(Object.keys(process.env).filter(k => k.startsWith('NEXT')));
En Vercel/Netlify:
# Las variables de .env.local NO se despliegan automáticamente
# Debes añadirlas manualmente en el dashboard de Vercel/Netlify
# En Vercel: Settings → Environment Variables
# En Netlify: Site settings → Environment variables
Cómo evitarlo en el futuro
Nunca expongas claves secretas (DB, Stripe secret, JWT) con NEXT_PUBLIC_ — cualquiera puede verlas en el código del cliente. Solo pon NEXT_PUBLIC_ en valores que el frontend necesita conocer y que no son sensibles.
¿Quieres que una IA te ayude? Genera el prompt perfecto para tu error:
Generador de Prompts