Back to blog

Published on Thursday, June 5, 2025

How to Use Environment Variables in Next.js

How to Use Environment Variables in Next.js

Video Tutorial

Introduction

Environment variables help you manage configuration and secrets (like API keys) without hardcoding them into your codebase. Next.js has built-in support for using .env files securely and efficiently.

What Are Environment Variables?

They’re simple KEY=value pairs stored outside your source code.

API_KEY=super-secret-key

Use them in your app like this:

const key = process.env.API_KEY;

Supported .env Files in Next.js

FilePurpose
.envDefault (shared across all envs)
.env.localLocal overrides (ignored by Git)
.env.development, .env.production, .env.testEnvironment-specific
.env.development.localLocal dev-only overrides

Tip:

.env.local is automatically added to .gitignore when you create a Next.js app — keeping secrets safe.

Server vs. Client Variables

1. Server-Only Variables (Safe for Secrets)

Environment variables without the NEXT_PUBLIC_ prefix are only available on the server — perfect for secrets like database credentials.

DATABASE_URL=postgres://user:pass@localhost
app/page.tsx
// (server component)

export default function Home() {
  const dbUrl = process.env.DATABASE_URL;
  console.log(dbUrl); // ✅ Safe: only runs on server

  return <main>Welcome</main>;
}

Client-Side Variables (NEXT_PUBLIC_)

To expose variables to the browser, prefix them with NEXT_PUBLIC_:

NEXT_PUBLIC_API_URL="https://api.example.com"
app/page.tsx
// (client component)
'use client';

export default function Home() {
  console.log(process.env.NEXT_PUBLIC_API_URL); // ✅ Accessible in browser

  return <main>Hello from the client!</main>;
}

Important:

Never use NEXT_PUBLIC_ for secrets like tokens or passwords. These values are bundled and exposed in your JavaScript.

Referencing Other Variables

Next.js lets you reference one variable inside another using $VARIABLE.

USERNAME=sikandar
PROFILE_URL=https://example.com/$USERNAME
console.log(process.env.PROFILE_URL); 
// Output: https://example.com/sikandar

Tip:

To include a literal $, escape it like this: \$.

Build-Time vs Runtime Variables

1. Build-Time (For NEXT_PUBLIC_)

Variables prefixed with NEXT_PUBLIC_ are inlined during build. Their values are fixed in the final JavaScript bundle.

NEXT_PUBLIC_ANALYTICS_ID="abc123"
import { setupAnalytics } from '@/lib/analytics';

setupAnalytics(process.env.NEXT_PUBLIC_ANALYTICS_ID); // Replaced at build time

Tip:

Changing these values post-deployment requires rebuilding the app.

2. Runtime (For Server Variables)

Non-NEXT_PUBLIC_ variables like DATABASE_URL are read at runtime and are ideal for server-side logic (API routes, SSR, etc.).

DATABASE_URL=postgres://user:pass@localhost
export default function handler(req, res) {
  const dbUrl = process.env.DATABASE_URL;
  res.status(200).json({ dbUrl });
}

Environment Variable Load Order

Environment variables are looked up in the following places, in order, stopping once the variable is found.

  • process.env
  • .env.$(NODE_ENV).local
  • .env.local (Not checked when NODE_ENV is test.)
  • .env.$(NODE_ENV)
  • .env

Good to know:

The allowed values for NODE_ENV are production, development and test.

Good to know

  • Store secrets in .env.local (auto-ignored by Git).
  • Use NEXT_PUBLIC_ only for safe, non-sensitive client-side values.
  • Keep .env* files in your project root directory.
  • Rebuild when changing NEXT_PUBLIC_ values.

Conclusion

Next.js simplifies environment variable management by supporting multiple .env formats, handling server/client separation, and offering clean integration for all environments.

Use this flexibility to keep your app secure, maintainable, and deploy-ready.