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
Public Variables
Client-side accessible
Development
Local development only
Production
Live environment
🔹 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):
- .env.local - Local overrides (not in Git)
- .env.development - Development environment
- .env.production - Production environment
- .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
- Go to your project settings
- Navigate to "Environment Variables"
- Add your variables with appropriate environments
- 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