Loading...
Loading...
Next.js environment variable management with file precedence, variable types, and deployment configurations. Use when configuring Next.js applications, managing environment-specific settings, or deploying to Vercel/Railway/Heroku.
npx skill4agent add bobmatnyc/claude-mpm-skills nextjs-env-variablesmy-nextjs-app/
├── .env # Shared defaults (committed)
├── .env.local # Local secrets (gitignored)
├── .env.development # Development defaults (committed)
├── .env.development.local # Local dev overrides (gitignored)
├── .env.production # Production defaults (committed)
├── .env.production.local # Production secrets (gitignored)
├── .env.test # Test environment (committed)
└── .env.example # Documentation (committed).env.$(NODE_ENV).local.env.production.local.env.local.env.$(NODE_ENV).env.production.envDATABASE_URL.env.env.production.local.env.production.localNEXT_PUBLIC_# .env.local
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=UA-123456789
NEXT_PUBLIC_SITE_NAME=My Awesome Site
NEXT_PUBLIC_ENABLE_FEATURE_X=true// Works in both client and server
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
// Usage in components
export default function MyComponent() {
return <div>API: {process.env.NEXT_PUBLIC_API_URL}</div>;
}NEXT_PUBLIC_*# ❌ WRONG - Secret exposed to browser
NEXT_PUBLIC_API_SECRET=sk_live_abc123
# ✅ CORRECT - Secret only on server
API_SECRET=sk_live_abc123# .env.local
DATABASE_URL=postgres://localhost:5432/mydb
JWT_SECRET=super-secret-jwt-key-do-not-expose
STRIPE_SECRET_KEY=sk_live_abc123
SMTP_PASSWORD=email-password-here// ✅ Works in API routes
export default async function handler(req, res) {
const dbUrl = process.env.DATABASE_URL;
// Use dbUrl...
}
// ✅ Works in getServerSideProps
export async function getServerSideProps() {
const secret = process.env.JWT_SECRET;
// Use secret...
}
// ❌ Does NOT work in components (browser)
export default function MyComponent() {
const dbUrl = process.env.DATABASE_URL; // undefined!
}# Shared defaults for all environments
NEXT_PUBLIC_APP_NAME=My Next.js App
NEXT_PUBLIC_DEFAULT_LOCALE=en
# Database (overridden in .env.local)
DATABASE_URL=postgres://localhost:5432/dev
# External services (no secrets)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_abc123# Local development secrets
DATABASE_URL=postgres://localhost:5432/mylocal
JWT_SECRET=dev-jwt-secret-change-in-production
STRIPE_SECRET_KEY=sk_test_local_key
# Local overrides
NEXT_PUBLIC_API_URL=http://localhost:4000/api# Production environment defaults
NEXT_PUBLIC_API_URL=https://api.production.com
NEXT_PUBLIC_ANALYTICS_ID=UA-PROD-123456
# These will be overridden by platform env vars
DATABASE_URL=set-this-in-vercel
JWT_SECRET=set-this-in-vercel# Copy this to .env.local and fill in actual values
# Client-side (browser accessible)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_ANALYTICS_ID=your-analytics-id
NEXT_PUBLIC_SITE_NAME=Your Site Name
# Server-side (secrets)
DATABASE_URL=postgres://user:password@host:5432/database # pragma: allowlist secret
JWT_SECRET=your-jwt-secret-32-chars-minimum
STRIPE_SECRET_KEY=sk_live_your_stripe_key
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-email@example.com
SMTP_PASSWORD=your-smtp-password# Development (.env.local)
DATABASE_URL=postgres://localhost:5432/myapp_dev
# Production (Vercel Environment Variables)
DATABASE_URL=postgres://user:pass@prod-host:5432/myapp_prod # pragma: allowlist secret# Public keys (client-side)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_abc123
# Secret keys (server-side only)
STRIPE_SECRET_KEY=sk_live_xyz789# Toggle features
NEXT_PUBLIC_ENABLE_DARK_MODE=true
NEXT_PUBLIC_ENABLE_BETA_FEATURES=falseDATABASE_URLpostgres://...NEXT_PUBLIC_*# Vercel automatically handles:
NEXT_PUBLIC_API_URL=https://api.example.com # ✅ Exposed to browser
# Server-only:
DATABASE_URL=postgres://... # ✅ Not exposed to browserNEXT_PUBLIC_*vercel --prod# Check structure
python scripts/validate_env.py .env.local --framework nextjs
# Compare with .env.example
python scripts/validate_env.py .env.local --compare-with .env.example
# Check for security issues
python scripts/scan_exposed.py --check-gitignore# List all .env files
ls -la .env*
# Validate each
for file in .env*; do
echo "=== $file ==="
python scripts/validate_env.py $file --framework nextjs
done# Compare local vs Vercel
python scripts/sync_secrets.py --platform vercel --compare
# Sync (dry-run first)
python scripts/sync_secrets.py --platform vercel --sync --dry-run
# Actually sync
python scripts/sync_secrets.py --platform vercel --sync --confirmprocess.env.MY_VARundefinedNEXT_PUBLIC_# ❌ Wrong
API_URL=https://api.example.com
# ✅ Correct
NEXT_PUBLIC_API_URL=https://api.example.comNEXT_PUBLIC_*vercel --prod.env.local.env.local# Compare
python scripts/sync_secrets.py --platform vercel --compare
# Find missing vars and add them in Vercel UI.env.local.gitignore.env.*.local.gitignoreNEXT_PUBLIC_*.env.env.example