NEXT_PUBLIC variables are not secret
Anything with that prefix is copied into the browser bundle. Treat it as published.
Hammad Iqbal
Software Engineer
Environment variables feel private because they live in a file that is not committed. In a Next.js app, though, a variable whose name starts with NEXT_PUBLIC_ is inlined into the JavaScript sent to every visitor. That is by design, and it is easy to forget.
- The prefix means 'send this to the browser'.
- Public keys and URLs are fine, private keys and service secrets are not.
- Do the sensitive work in route handlers or server code.
What the prefix really does
At build time the value is replaced directly in the client code. Opening the browser's network or source tools shows it in plain text. There is no hiding it, so the question is only whether it was meant to be public.
What belongs where
Publishable keys are made to be shipped to the client, but they only stay safe if the database rules behind them are tight. Row level security does the real protection.
- Public: analytics project keys, public API URLs, publishable keys that are designed to be exposed
- Server only: database passwords, service role keys, SMTP credentials, webhook secrets
Keep secrets on the server
If the browser needs something that requires a secret, such as sending an email or calling a paid API, expose a small server route that does it. The browser calls the route and never sees the credential.
If it starts with NEXT_PUBLIC_, assume the world can read it, and keep real secrets in server code.
Have a project this kind of thinking applies to?
Tell me what you're building — I read every message myself.