Lesson 24 / 25

Environment Variables and Security

Keep secrets on the server.

NEXT_PUBLIC_ means public

Next.js loads environment variables from .env* files and the environment. Variables are available only on the server unless their name starts with NEXT_PUBLIC_, in which case they are inlined into the browser bundle at build time and visible to anyone. Never prefix secrets that way. Keep database credentials and API keys in server-only modules, validate configuration at startup, set security headers, and remember that Server Actions and Route Handlers are public endpoints that need authentication and validation.

Server-only and public variables

Naming decides exposure.

# .env.local  (never commit real secrets)
DATABASE_URL=postgres://...          # server only
PAYMENT_SECRET_KEY=sk_live_...       # server only
NEXT_PUBLIC_SITE_URL=https://shop.example   # inlined into the browser bundle: public!

// lib/db.ts
import "server-only";                # build error if imported from client code
export const db = connect(process.env.DATABASE_URL!);

Search bundles for secrets

Before launch, search the built client JavaScript for key prefixes to confirm no secret was exposed.

Quick check: What happens to a variable named NEXT_PUBLIC_API_KEY?

  • It is encrypted automatically
  • It stays on the server
  • Its value is inlined into the browser bundle and visible to users
  • It is ignored
Answer

Its value is inlined into the browser bundle and visible to users — Only public values get the prefix.