Skip to Content
Browse all templates at capricorn.build →
Next.jsCustomizationEnvironment Variables

Environment Variables

Configure your template with environment variables for API keys, URLs, and other settings.

What Are Environment Variables?

Environment variables are settings that:

  • Change between development and production
  • Contain sensitive data (API keys, passwords)
  • Configure application behavior
  • Are never committed to Git

Creating Environment Files

Local Development

Create .env.local in your project root:

# .env.local (for local development only) NEXT_PUBLIC_SITE_URL=http://localhost:3000 NEXT_PUBLIC_API_URL=http://localhost:3001/api # Private keys (server-side only) DATABASE_URL=postgresql://localhost/mydb API_SECRET_KEY=your-secret-key SMTP_PASSWORD=your-email-password

Production

Create .env.production:

# .env.production (for production deployment) NEXT_PUBLIC_SITE_URL=https://yourdomain.com NEXT_PUBLIC_API_URL=https://api.yourdomain.com DATABASE_URL=postgresql://production-server/mydb API_SECRET_KEY=production-secret-key

Naming Convention

Client-Side Variables

Must start with NEXT_PUBLIC_:

# Accessible in browser NEXT_PUBLIC_SITE_NAME=My Site NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX NEXT_PUBLIC_API_ENDPOINT=https://api.example.com

Use in components:

// Client component const siteName = process.env.NEXT_PUBLIC_SITE_NAME const gaId = process.env.NEXT_PUBLIC_GA_ID

Server-Side Variables

No prefix needed:

# Only accessible on server DATABASE_URL=postgresql://... EMAIL_SERVER_PASSWORD=secret STRIPE_SECRET_KEY=sk_test_...

Use in API routes or Server Components:

// app/api/route.ts const dbUrl = process.env.DATABASE_URL const stripeKey = process.env.STRIPE_SECRET_KEY

Common Variables

Site Configuration

NEXT_PUBLIC_SITE_NAME=Your Site Name NEXT_PUBLIC_SITE_URL=https://yourdomain.com NEXT_PUBLIC_SITE_DESCRIPTION=Your site description

API Endpoints

NEXT_PUBLIC_API_URL=https://api.yourdomain.com NEXT_PUBLIC_GRAPHQL_ENDPOINT=https://api.yourdomain.com/graphql

Analytics

NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX NEXT_PUBLIC_GTM_ID=GTM-XXXXXXX NEXT_PUBLIC_FACEBOOK_PIXEL_ID=123456789

Database

DATABASE_URL=postgresql://user:password@host:5432/database MONGODB_URI=mongodb://user:password@host:27017/database

Email

EMAIL_SERVER_HOST=smtp.gmail.com EMAIL_SERVER_PORT=587 EMAIL_SERVER_USER=your-email@gmail.com EMAIL_SERVER_PASSWORD=your-password EMAIL_FROM=noreply@yourdomain.com

Payment Providers

STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_SECRET_KEY=sk_test_... PAYPAL_CLIENT_ID=your-client-id

Authentication

NEXTAUTH_URL=https://yourdomain.com NEXTAUTH_SECRET=your-random-secret GOOGLE_CLIENT_ID=your-client-id GOOGLE_CLIENT_SECRET=your-client-secret

Using Environment Variables

In Components

'use client' export default function Header() { const siteName = process.env.NEXT_PUBLIC_SITE_NAME return {siteName} }

In API Routes

// app/api/send-email/route.ts export async function POST(request: Request) { const emailPassword = process.env.EMAIL_SERVER_PASSWORD // Use to send email return Response.json({ success: true }) }

In Server Components

// app/dashboard/page.tsx export default async function Dashboard() { const dbUrl = process.env.DATABASE_URL // Fetch data using dbUrl return Dashboard }

With TypeScript

Create env.d.ts for type safety:

declare namespace NodeJS { interface ProcessEnv { NEXT_PUBLIC_SITE_NAME: string NEXT_PUBLIC_API_URL: string DATABASE_URL: string EMAIL_SERVER_PASSWORD: string } }

Security Best Practices

1. Never Commit Secrets

Add to .gitignore:

# .gitignore .env*.local .env.production .env

Commit .env.example instead:

# .env.example NEXT_PUBLIC_SITE_URL= DATABASE_URL= API_SECRET_KEY=

2. Use Different Keys for Development/Production

# Development STRIPE_SECRET_KEY=sk_test_123... # Production STRIPE_SECRET_KEY=sk_live_456...

3. Rotate Keys Regularly

Change sensitive keys periodically:

  • API keys every 6 months
  • Passwords every 3 months
  • After team member leaves

4. Limit Variable Scope

Only use NEXT_PUBLIC_ when necessary:

# Bad - exposes secret NEXT_PUBLIC_API_KEY=secret123 # Good - keeps server-side API_KEY=secret123

Platform-Specific Setup

Vercel

Add via dashboard:

  1. Go to Project Settings
  2. Click “Environment Variables”
  3. Add variables
  4. Redeploy

Or via CLI:

vercel env add NEXT_PUBLIC_SITE_URL production

Netlify

Add via dashboard:

  1. Site Settings → Environment Variables
  2. Add variables
  3. Redeploy

Or via netlify.toml:

[build.environment] NEXT_PUBLIC_SITE_URL = "https://yourdomain.com"

Self-Hosted

Create .env.production on server:

# On server cd /path/to/app nano .env.production # Add variables NEXT_PUBLIC_SITE_URL=https://yourdomain.com DATABASE_URL=postgresql://...

Load with PM2:

// ecosystem.config.js module.exports = { apps: [{ name: 'app', script: 'npm', args: 'start', env_production: { NODE_ENV: 'production', NEXT_PUBLIC_SITE_URL: 'https://yourdomain.com' } }] }

Troubleshooting

Variables Not Loading

  1. Restart dev server after adding variables:

    npm run dev
  2. Check variable name:

    • Client-side needs NEXT_PUBLIC_ prefix
    • No spaces around =
    • No quotes needed (usually)
  3. Check file location:

    • Must be in project root
    • Named exactly .env.local or .env.production

Variable is Undefined

// Check if variable exists const apiUrl = process.env.NEXT_PUBLIC_API_URL if (!apiUrl) { console.error('NEXT_PUBLIC_API_URL is not defined') }

Production Variables Not Working

  1. Set on hosting platform (Vercel/Netlify/etc)
  2. Redeploy after adding variables
  3. Check deployment logs for errors

Example Complete Setup

.env.local (Development)

# Site Config NEXT_PUBLIC_SITE_NAME=My Local Site NEXT_PUBLIC_SITE_URL=http://localhost:3000 # Database DATABASE_URL=postgresql://localhost/mydb_dev # Email (Use Mailtrap for testing) EMAIL_SERVER_HOST=smtp.mailtrap.io EMAIL_SERVER_PORT=2525 EMAIL_SERVER_USER=your-mailtrap-user EMAIL_SERVER_PASSWORD=your-mailtrap-password # Analytics (Development keys) NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX # Stripe (Test keys) NEXT_PUBLIC_STRIPE_KEY=pk_test_123 STRIPE_SECRET_KEY=sk_test_123

.env.production (Production)

# Site Config NEXT_PUBLIC_SITE_NAME=My Production Site NEXT_PUBLIC_SITE_URL=https://yourdomain.com # Database (Production) DATABASE_URL=postgresql://prod-server/mydb # Email (Production SMTP) EMAIL_SERVER_HOST=smtp.sendgrid.net EMAIL_SERVER_PORT=587 EMAIL_SERVER_USER=apikey EMAIL_SERVER_PASSWORD=your-sendgrid-api-key # Analytics (Production ID) NEXT_PUBLIC_GA_ID=G-YYYYYYYYYY # Stripe (Live keys) NEXT_PUBLIC_STRIPE_KEY=pk_live_456 STRIPE_SECRET_KEY=sk_live_456

Next Steps


Last updated on