Capítulo 41 de 456

Environment Variables

Core Idea

Como carregar variáveis de .env* no process.env, decidir quando expô-las ao browser (NEXT_PUBLIC_) e entender a ordem de precedência entre os arquivos por ambiente.

Key Concepts

  • .env* loading: Next.js carrega .env, .env.local, .env.$(NODE_ENV), .env.$(NODE_ENV).local automaticamente em process.env, disponível em Route Handlers e código server.
  • /src folder: .env* files ficam sempre na raiz do projeto, nunca dentro de /src.
  • NEXT_PUBLIC_ prefix: inlina o valor no bundle JS enviado ao browser em build time, substituindo toda referência a process.env.NEXT_PUBLIC_X pelo valor literal.
  • Dynamic lookup não é inlinado: process.env[varName] ou env.NEXT_PUBLIC_X (via variável intermediária) NÃO são substituídos pelo compilador; só a referência estática funciona.
  • @next/env package: expõe loadEnvConfig(projectDir) para carregar as mesmas env vars fora do runtime do Next.js (ex.: config de ORM, test runner).
  • Referência a outra variável com $: .env suporta $VARIABLE para compor valores (ex.: TWITTER_URL=https://x.com/$TWITTER_USER); escapar com \$ para usar $ literal.
  • Multiline vars: suportado com quebra de linha real dentro de aspas duplas ou \n explícito.
  • Runtime env vars: variáveis não-NEXT_PUBLIC_ lidas durante dynamic rendering (ex.: após await connection()) são avaliadas em runtime, permitindo uma única imagem Docker promovida entre ambientes.
  • .env.test: terceiro ambiente além de development/production; carregado quando NODE_ENV=test; .env.local é ignorado neste ambiente para manter testes determinísticos entre execuções.

Code Examples

# .env
DB_HOST=localhost
TWITTER_USER=nextjs
TWITTER_URL=https://x.com/$TWITTER_USER
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk
  • O que demonstra: variável privada (DB_HOST), composição via $VARIABLE, e variável pública inlinada no bundle (NEXT_PUBLIC_).
// app/page.ts — runtime env var em dynamic rendering
import { connection } from 'next/server'

export default async function Component() {
  await connection()
  // cookies, headers e outras Request-time APIs também opt-in dynamic rendering
  const value = process.env.MY_VALUE // avaliado em runtime, não build time
}
  • O que demonstra: como forçar leitura de env var no momento da request (não congelada no build), útil para imagem Docker única promovida entre ambientes.
// envConfig.ts — carregar env fora do runtime Next.js
import { loadEnvConfig } from '@next/env'

const projectDir = process.cwd()
loadEnvConfig(projectDir)
  • O que demonstra: uso de @next/env para disponibilizar as mesmas env vars em orm.config.ts ou setup de testes (Jest).

Reference Tables

Ordem de carregamento (para na primeira que encontrar a variável)

OrdemFonte
1process.env
2.env.$(NODE_ENV).local
3.env.local (não em test)
4.env.$(NODE_ENV)
5.env
VersionChanges
v9.4.0Suporte a .env e NEXT_PUBLIC_ introduzido

Anti-patterns

  • Commitar arquivos .env* reais: create-next-app já ignora via .gitignore; nunca versionar segredos.
  • Esperar que NEXT_PUBLIC_ mude após o build: valor fica congelado no bundle; promover a mesma imagem entre ambientes não muda esses valores — use runtime env vars se precisar disso.
  • Fazer lookup dinâmico esperando inlining: process.env[varName] não é substituído pelo compilador; só funciona no server.

Key Takeaways

  1. Só prefixe com NEXT_PUBLIC_ o que realmente precisa existir no browser; qualquer outra var fica só no server por padrão.
  2. Para runtime config (mesma imagem, múltiplos ambientes), leia process.env depois de await connection() em vez de depender de NEXT_PUBLIC_.
  3. .env.test ignora .env.local de propósito, para testes serem reproduzíveis entre máquinas.
  4. @next/env é o caminho oficial para reusar o mesmo carregamento de env em ferramentas fora do Next.js runtime (ORM configs, Jest setup).

Connects To

  • Data Security (ch037): reforça que só o DAL deveria ler process.env para segredos sensíveis.
  • Deploying to Platforms (ch039): runtime env vars exigem servidor Node.js compatível com dynamic rendering.
  • Debugging (ch038): NODE_ENV interage com qual arquivo .env* é carregado durante sessão de debug/test.