Next.js Environment Variables
Environment variables are values your app reads from outside its code. Database URLs, API keys, and service credentials are environment variables. You never write these values directly into your code because that exposes secrets to anyone who reads your codebase. Instead, you store them in a separate file and let Next.js inject them at runtime.
The .env File
Create a file named .env.local in the root of your project. Write your variables as key-value pairs.
# .env.local DATABASE_URL=mongodb+srv://user:password@cluster.mongodb.net/mydb API_KEY=sk-abc123xyz789 STRIPE_SECRET_KEY=sk_live_...
Next.js automatically reads this file. Never commit .env.local to Git. Add it to .gitignore to keep your secrets private.
# .gitignore .env.local .env.production.local .env.development.local
Diagram: How Environment Variables Flow
.env.local file (on your machine, never committed to Git)
↓
Next.js reads at startup
↓
process.env.VARIABLE_NAME available in your code
↓
Used in: API routes, server components, server actions, middleware
Note: Server-only. Browser never sees these values.
Accessing Environment Variables
Read environment variables using process.env followed by the variable name.
// In a server component or API route const dbUrl = process.env.DATABASE_URL; const apiKey = process.env.API_KEY;
Server-Only vs Public Variables
By default, every variable in .env.local is server-only. Next.js does not expose them to the browser. If you need a variable in the browser — like a public analytics ID — prefix it with NEXT_PUBLIC_.
# .env.local # Server-only (safe for secrets): DATABASE_URL=mongodb+srv://... API_SECRET_KEY=sk-secret123 # Browser-safe (public, anyone can see these): NEXT_PUBLIC_ANALYTICS_ID=G-ABC123 NEXT_PUBLIC_SITE_URL=https://yoursite.com
DIAGRAM: Variable Exposure WITHOUT NEXT_PUBLIC_ prefix: Variable lives only on the server Browser: cannot access it → SECRET STAYS SAFE WITH NEXT_PUBLIC_ prefix: Variable is bundled into browser JavaScript Browser: can read it → Only use for non-sensitive values
Using Public Variables in Client Components
// Works in any component, including client components const siteUrl = process.env.NEXT_PUBLIC_SITE_URL; const analyticsId = process.env.NEXT_PUBLIC_ANALYTICS_ID;
Multiple Environment Files
Next.js supports different .env files for different environments. The right file loads automatically based on how you start the app.
.env → Loaded in all environments .env.local → Loaded in all environments, ignored by Git .env.development → Loaded only during npm run dev .env.production → Loaded only during npm run build / npm run start .env.development.local → Local overrides for development only .env.production.local → Local overrides for production only
Priority Order (highest to lowest)
.env.development.local (or .env.production.local) .env.local .env.development (or .env.production) .env
If the same variable appears in multiple files, the file higher on the list wins.
A Practical Example: Database Connection
# .env.local (development) DATABASE_URL=mongodb://localhost:27017/mydb_dev # .env.production.local (production — on your server only, not in Git) DATABASE_URL=mongodb+srv://user:pass@cluster.mongodb.net/mydb_prod
// app/lib/db.js
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.DATABASE_URL);
export default client;
Your code never changes. The database URL changes automatically based on the environment.
Checking for Missing Variables
Validate that required environment variables are present at startup. This prevents confusing runtime errors deep inside your app when a secret is missing.
// app/lib/env.js
function requireEnv(name) {
const value = process.env[name];
if (!value) {
throw new Error(`Missing required environment variable: ${name}`);
}
return value;
}
export const dbUrl = requireEnv('DATABASE_URL');
export const apiKey = requireEnv('API_KEY');
Setting Variables on Vercel
When you deploy to Vercel, you add environment variables through the Vercel dashboard. Go to your project settings, open the Environment Variables section, and add each key-value pair. Vercel injects them automatically on every deployment. You never need to upload your .env files.
LOCAL DEVELOPMENT: Variables → .env.local file on your machine PRODUCTION (Vercel): Variables → Vercel dashboard → Injected at build and runtime Other platforms (Railway, Render, Heroku): Variables → Platform dashboard settings → Injected similarly
Key Takeaway
Store secrets in .env.local and never commit this file to Git. Access variables with process.env.VARIABLE_NAME in server-side code. Add the NEXT_PUBLIC_ prefix only for values that are safe to expose in the browser. Use separate .env files for development and production so your app connects to the right services in each environment.
