Environment Variables
Environment Variables
Section titled “Environment Variables”Introduction
Section titled “Introduction”Environment variables keep configuration — API keys, database URLs, secrets — out of your code. They change per environment (development, preview, production) without changing the code.
Why Do We Need This?
Section titled “Why Do We Need This?”Hardcoding secrets in your code is a security risk. Environment variables let you:
- Keep API keys and secrets out of version control
- Use different values for development and production
- Change configuration without redeploying
Using Environment Variables
Section titled “Using Environment Variables”Local Development
Section titled “Local Development”# .env.local (not committed to git)DATABASE_URL=postgresql://localhost:5432/mydbNEXTAUTH_SECRET=my-dev-secretNEXT_PUBLIC_API_URL=http://localhost:3000/apiIn Code
Section titled “In Code”// Server-side only (can't be accessed by the browser)const dbUrl = process.env.DATABASE_URL
// Client-side (prefix with NEXT_PUBLIC_)const apiUrl = process.env.NEXT_PUBLIC_API_URLIn next.config.js
Section titled “In next.config.js”module.exports = { env: { CUSTOM_KEY: 'my-value', }, publicRuntimeConfig: { // Available on both server and client },}Public vs Private Variables
Section titled “Public vs Private Variables”| Prefix | Accessible Where | Example |
|---|---|---|
NEXT_PUBLIC_ | Browser and server | NEXT_PUBLIC_API_URL |
| No prefix | Server only | DATABASE_URL, API_SECRET |
// ✅ Can be used in client componentsconst apiUrl = process.env.NEXT_PUBLIC_API_URL
// ❌ Will be undefined in client componentsconst dbUrl = process.env.DATABASE_URL // Server onlyEnvironment-Specific Files
Section titled “Environment-Specific Files”| File | When It Loads | Priority |
|---|---|---|
.env | Always | Lowest |
.env.local | Always (ignored by Git) | Overrides .env |
.env.development | next dev only | Overrides .env.local |
.env.production | next start only | Overrides .env.local |
# .env — shared defaultsDATABASE_URL=postgresql://localhost:5432/mydb
# .env.local — local overrides (not in Git)DATABASE_URL=postgresql://localhost:5432/my-local-db
# .env.production — production overridesDATABASE_URL=postgresql://prod-server:5432/my-prod-dbDeployment Platforms
Section titled “Deployment Platforms”Vercel
Section titled “Vercel”Set environment variables in Project Settings → Environment Variables. You can set different values for:
- Development (preview deployments)
- Preview (branch deployments)
- Production
Docker
Section titled “Docker”services: app: image: myapp environment: - DATABASE_URL=${DATABASE_URL} - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}Common Mistakes
Section titled “Common Mistakes”- Committing
.env.localto Git — Add.env.localto.gitignore. Only commit.env.examplewith placeholder values. - Using
NEXT_PUBLIC_for secrets — Anything prefixed withNEXT_PUBLIC_is visible in the browser. Never put API keys or secrets here. - Checking for variables at build time — Some variables are only available at runtime. Use
process.env.Xat runtime, not build time.
Best Practices
Section titled “Best Practices”- Use
.env.localfor local development (not committed) - Use
.env.exampleas a template with placeholder values (committed) - Prefix client-accessible variables with
NEXT_PUBLIC_ - Never commit secrets to version control
- Set environment variables in your deployment platform’s dashboard
Summary
Section titled “Summary”Environment variables keep configuration out of your code. Use NEXT_PUBLIC_ prefix for browser-accessible variables. Set different values per environment using .env.development, .env.production, or your deployment platform’s dashboard.