Environment Variables

Managing configuration and secrets in Next.js

🔐 What are Environment Variables?

Environment variables store configuration values and secrets outside your code. They keep sensitive data like API keys secure and allow different settings for development and production environments.


// Access environment variables
const apiKey = process.env.API_KEY
const dbUrl = process.env.DATABASE_URL
                                    

Types of Environment Variables

🔒

Server-Only

Secure backend variables

API_KEY DATABASE_URL
🌐

Public Variables

Client-side accessible

NEXT_PUBLIC_* Browser safe
🛠️

Development

Local development only

.env.local .env.development
🚀

Production

Live environment

.env.production Vercel dashboard

🔹 Creating Environment Files

Create .env files in your project root to store environment variables. Next.js automatically loads these files based on your environment.

🔸 .env.local (Development)

# .env.local - Not committed to Git
DATABASE_URL=postgresql://localhost:5432/mydb
API_KEY=your-secret-api-key-here
STRIPE_SECRET_KEY=sk_test_123456789

# Public variables (accessible in browser)
NEXT_PUBLIC_API_URL=http://localhost:3000/api
NEXT_PUBLIC_SITE_NAME=My Awesome App

File Priority (highest to lowest):

  1. .env.local - Local overrides (not in Git)
  2. .env.development - Development environment
  3. .env.production - Production environment
  4. .env - Default for all environments

🔹 Using Server-Side Variables

Server-side variables are only accessible in server components, API routes, and server actions. They never get exposed to the browser.

🔸 In Server Components

// app/page.js (Server Component)
export default async function Page() {
  // Safe: Only runs on server
  const data = await fetch('https://api.example.com/data', {
    headers: {
      'Authorization': `Bearer ${process.env.API_KEY}`
    }
  })
  
  return <div>Data loaded securely</div>
}

🔸 In API Routes

// app/api/users/route.js
export async function GET() {
  const dbUrl = process.env.DATABASE_URL
  
  // Connect to database using secret URL
  const users = await db.query('SELECT * FROM users')
  
  return Response.json(users)
}

🔹 Using Public Variables

Public variables prefixed with NEXT_PUBLIC_ are embedded in the browser bundle. Use them for non-sensitive configuration that clients need to access.

🔸 In Client Components

'use client'

export default function ApiClient() {
  // Safe: Public variable
  const apiUrl = process.env.NEXT_PUBLIC_API_URL
  
  const fetchData = async () => {
    const response = await fetch(`${apiUrl}/posts`)
    const data = await response.json()
    return data
  }
  
  return (
    <div>
      <p>API URL: {apiUrl}</p>
      <button onClick={fetchData}>Fetch Data</button>
    </div>
  )
}

⚠️ Important Security Rules:

  • NEVER use NEXT_PUBLIC_ for secrets or API keys
  • NEVER expose database credentials to the client
  • ALWAYS keep .env.local out of version control
  • ALWAYS use server-side code for sensitive operations

🔹 Loading Environment Variables

Next.js automatically loads environment variables from .env files. You can also load them programmatically for advanced use cases.

🔸 Default Loading

// Automatically available
console.log(process.env.DATABASE_URL)
console.log(process.env.NEXT_PUBLIC_API_URL)

🔸 Runtime Configuration

// next.config.js
module.exports = {
  env: {
    CUSTOM_KEY: 'my-value',
  },
  // Or use publicRuntimeConfig for client-side
  publicRuntimeConfig: {
    apiUrl: process.env.API_URL,
  },
}

🔹 Production Deployment

When deploying to production, set environment variables in your hosting platform. For Vercel, use the dashboard or CLI to manage variables securely.

🔸 Vercel Dashboard

  1. Go to your project settings
  2. Navigate to "Environment Variables"
  3. Add your variables with appropriate environments
  4. Redeploy your application

🔸 Vercel CLI

# Add environment variable
vercel env add API_KEY

# Pull environment variables to local
vercel env pull .env.local

🔹 Best Practices

Follow these guidelines for secure and maintainable environment variable management:

  • Use .env.local: For local development secrets
  • Add to .gitignore: Never commit .env.local files
  • Document variables: Create .env.example with dummy values
  • Prefix public vars: Always use NEXT_PUBLIC_ for client-side
  • Validate on startup: Check required variables exist
  • Use different values: Separate dev and production credentials

🔸 Example .env.example

# .env.example - Commit this to Git
DATABASE_URL=your_database_url_here
API_KEY=your_api_key_here
NEXT_PUBLIC_API_URL=http://localhost:3000/api

🧠 Test Your Knowledge

What prefix makes environment variables accessible in the browser?