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.

Leave a Comment