Abdul Wahab

Blog/

NEXT_PUBLIC_ Variables: Why They’re Public in Next.js

Learn why NEXT_PUBLIC_ env vars are exposed, how to keep secrets safe, and best practices for Next.js apps.

NEXT_PUBLIC vars exposed in the browser versus secrets locked on the server

Introduction


When you see an environment variable that starts with NEXT_PUBLIC_ in a Next.js project, the first thing you should do is stop thinking of it as a secret. The name itself is a contract that the value will be bundled into the client bundle and shipped to the browser. In other words, anyone who can open DevTools can read it. That is not a bug or a security hole; it is how Next.js is designed to work.

Understanding NEXT_PUBLIC_ Variables


The prefix NEXT_PUBLIC_ tells the framework that the variable is safe to expose to the browser. It is the same as putting a key on a door and expecting no one to notice. The browser is public by nature, so anything you put there is public. If you need to keep a value secret, do not prefix it with NEXT_PUBLIC_.

Common Mistakes


A lot of developers copy patterns from plain React SPAs and assume that the same rules apply in Next.js. This leads to a handful of common pitfalls:

  • Adding payment keys, secret tokens, or private API credentials to NEXT_PUBLIC_ just “for now.”
  • Copying a React SPA that uses client-side environment variables and assuming the same security model works in Next.js.
  • Renaming a variable from a non-public name to NEXT_PUBLIC_ without moving the sensitive logic to the server.

These mistakes expose secrets to anyone who can view the built JavaScript bundle. The result is a security risk that can be mitigated with a simple change of mindset.

The Rule of Thumb


I follow a straightforward rule when deciding whether to prefix an environment variable with NEXT_PUBLIC_:

  1. If the browser needs the value to render or to call a public endpoint, use NEXT_PUBLIC_.
  2. If the server should be the only one that ever sees the value, keep it as a plain env var and use it in a Server Component, Route Handler, or server action. Never prefix it.

When the frontend needs something sensitive done, it should ask the backend to do it. The browser receives a response, not the key.

Moving Secrets to the Server


If you inherit a React app where env vars were sitting in the client, don’t just rename them. Move the sensitive work behind the server and rotate anything that was exposed. Here’s a quick checklist:

  • Search the repo for NEXT_PUBLIC_.
  • For each variable, ask: what would happen if a stranger read this value?
  • If the answer is “bad, ” move the logic that uses the variable to a server-side file.
  • Rotate any exposed keys or tokens.

You can also use Next.js API routes or server actions to act as a proxy. The client sends a request, the server performs the sensitive operation, and the client receives only the result.

Practical Checklist Before You Ship


Before you deploy, run through this quick check:

  1. Search for NEXT_PUBLIC_ , make sure you haven’t accidentally added a secret.
  2. Ask the “what if” question , what would happen if a stranger read every value?
  3. Move anything that fails the test , to the server and rotate it.
  4. Verify that the server-side code is not exposed , it should never be bundled into the client.
  5. Test the build , open the production bundle in DevTools and confirm no secrets are present.

Following this process will keep your secrets safe and your Next.js app compliant with the framework’s design.

Conclusion


NEXT_PUBLIC_ variables are public by definition. Treat them as such, and keep all secrets on the server. By applying a simple rule of thumb and performing a quick pre-deployment check, you can avoid exposing sensitive data and keep your application secure. If you need help refactoring a legacy app or building a new Next.js project with secure environment handling, feel free to reach out. I work on freelance full-stack projects and you can see more of my work at wabby.dev.

Written by Abdul Wahab

← All posts