If you've worked with Next.js for a while, you've probably run into this at least once: an environment variable that works perfectly on your machine, then either goes missing after deploy or, worse, shows up in the browser where anyone can see it.
The core rule
Next.js splits environment variables into two groups:
-
Server only (default): plain names like
DATABASE_URLorAPI_SECRET_KEY. These never reach the browser. -
Public: any variable prefixed with
NEXT_PUBLIC_. These get bundled into your client JavaScript and are visible to anyone using DevTools.
Mixing these up is how secrets end up exposed.
What the full guide covers
In the complete post, I break down:
- How Next.js loads
.env,.env.local,.env.production, and friends, and in what order - Build time vs runtime variables, and why this distinction trips people up in Docker and Cloudflare setups
- How to validate your environment variables so a missing one fails your build instead of crashing in production
- Correct setup for Vercel, Cloudflare, and Docker deployments
- Sneaky mistakes, like destructuring
process.env, that silently break variable access
👉 Full guide here: https://devencyclopedia.com/blog/nextjs-environment-variables
Have you ever shipped a secret to the browser by mistake? Drop your story in the comments, happy to compare notes.