Environment variables in Next.js
From the Next.js cheat sheet · Deployment · verified Jul 2026
Environment variables
typescript
// .env.local (git ignored)
DATABASE_URL=postgresql://localhost:5432/myapp
API_SECRET=secret_key_here
// Public variables (exposed to client)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
// env.ts - Type-safe environment variables
import { z } from 'zod'
const envSchema = z.object({
// Server-side variables
DATABASE_URL: z.string().url(),
API_SECRET: z.string().min(1),
NODE_ENV: z.enum(['development', 'production', 'test']),
// Client-side variables
NEXT_PUBLIC_API_URL: z.string().url(),
NEXT_PUBLIC_GA_ID: z.string().optional(),
})
// Validate at build time
const env = envSchema.parse({
DATABASE_URL: process.env.DATABASE_URL,
API_SECRET: process.env.API_SECRET,
NODE_ENV: process.env.NODE_ENV,
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
NEXT_PUBLIC_GA_ID: process.env.NEXT_PUBLIC_GA_ID,
})
export default env
// Usage in server components
import env from '@/lib/env'
async function getData() {
const response = await fetch(env.NEXT_PUBLIC_API_URL + '/data', {
headers: {
'Authorization': `Bearer ${env.API_SECRET}`
}
})
return response.json()
}💡 .env.local for local development
⚡ NEXT_PUBLIC_ prefix for client-side
📌 Runtime vs build-time variables
🟢 Validation with zod or t3-env