Skip to main content
Practice Problems

Environment variables in Next.js

Environment Variables in Next.js

Next.js has built-in support for environment variables with special conventions for server-only and public (client-accessible) variables.


File Conventions

.env β†’ All environments .env.local β†’ Local overrides (git-ignored) .env.development β†’ Development only .env.production β†’ Production only .env.test β†’ Test only

Priority (highest to lowest): .env.local > .env.[environment] > .env

Server vs Client Variables

bash
# .env.local # βœ… Server-only (default) β€” NOT exposed to browser DATABASE_URL=postgresql://localhost:5432/mydb JWT_SECRET=super-secret-key API_KEY=sk-1234567890 # βœ… Public β€” exposed to browser (NEXT_PUBLIC_ prefix) NEXT_PUBLIC_API_URL=https://api.example.com NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX NEXT_PUBLIC_STRIPE_PUBLIC_KEY=pk_live_xxx

Usage

tsx
// Server Component or API Route β€” has access to ALL variables async function ServerComponent() { const dbUrl = process.env.DATABASE_URL; // βœ… Available const apiUrl = process.env.NEXT_PUBLIC_API_URL; // βœ… Available const secret = process.env.JWT_SECRET; // βœ… Available } // Client Component β€” ONLY NEXT_PUBLIC_ variables "use client"; function ClientComponent() { const apiUrl = process.env.NEXT_PUBLIC_API_URL; // βœ… Available const dbUrl = process.env.DATABASE_URL; // ❌ undefined! const secret = process.env.JWT_SECRET; // ❌ undefined! }

Important Rules

RuleDetails
Default is server-onlyVariables without NEXT_PUBLIC_ are server-only
NEXT_PUBLIC_ prefixRequired to expose a variable to the browser
Static replacementNEXT_PUBLIC_ vars are inlined at build time
.env.local is git-ignoredUse for secrets, override per developer
Restart requiredChanges to .env files require restarting the dev server

Static Replacement (Build Time)

NEXT_PUBLIC_ variables are replaced at build time, not runtime:

tsx
// βœ… This works β€” direct reference const url = process.env.NEXT_PUBLIC_API_URL; // ❌ This does NOT work β€” dynamic access const key = "NEXT_PUBLIC_API_URL"; const url = process.env[key]; // undefined in client!

Type Safety with TypeScript

typescript
// env.d.ts declare namespace NodeJS { interface ProcessEnv { DATABASE_URL: string; JWT_SECRET: string; NEXT_PUBLIC_API_URL: string; NEXT_PUBLIC_GA_ID: string; NODE_ENV: "development" | "production" | "test"; } }

Runtime Environment Variables

For variables that need to change after build (e.g., in Docker):

tsx
// next.config.js module.exports = { // Server-side runtime variables serverRuntimeConfig: { apiSecret: process.env.API_SECRET, }, // Available on both server and client publicRuntimeConfig: { apiUrl: process.env.API_URL, }, };

Security Best Practices

  • Never put secrets in NEXT_PUBLIC_ variables
  • Always use .env.local for sensitive values
  • Add .env.local to .gitignore
  • Provide .env.example with placeholder values for team
  • Use TypeScript declarations for type safety

Important:

By default, environment variables in Next.js are server-only and not exposed to the browser. Use the NEXT_PUBLIC_ prefix to explicitly make a variable available on the client. Remember that public variables are inlined at build time and cannot be changed without rebuilding. Never expose secrets with NEXT_PUBLIC_.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems