Back to blog
technicalvulnerabilitiesNext.js

NEXT_PUBLIC_: when your environment variables end up in the browser

Published on 2026-06-226 min readCleanIssue

A misunderstood convention

In Next.js, the rule is simple: an environment variable prefixed with NEXT_PUBLIC_ is inlined into the JavaScript bundle at build time. It is then served to every visitor of your site, readable in plain text in the browser sources.

The rule is simple, but its consequences are consistently underestimated. In our audits of Next.js-based SaaS products, we find in public bundles:

  • third-party API keys (email sending, geocoding, data enrichment)
  • Supabase service_role keys — meaning full database access, RLS bypassed
  • URLs of unprotected staging environments
  • "temporary" internal API tokens that are months old
  • How it happens

    Nobody ships a secret key client-side on purpose. The real-world scenarios:

    The convenience rename

    An API call fails client-side because the variable is undefined. Obscure error message, deadline looming. Someone renames SUPABASE_SERVICE_KEY to NEXT_PUBLIC_SUPABASE_SERVICE_KEY, it works, everyone moves on. The key is now public.

    The component that switches sides

    A server component using a private variable becomes a client component ("use client") during a refactor. The variable is no longer available — same reflex: add the prefix.

    The AI suggestion

    Code assistants regularly propose the NEXT_PUBLIC_ prefix as the fix when a variable is undefined client-side. It's technically the right answer to the wrong question.

    The mental model

    The NEXT_PUBLIC_ prefix is not a configuration mechanism, it's a publication statement. Before using it, ask: "am I comfortable with this value appearing in my site's public source code?"

    Legitimate: your API's public URL, a Stripe *publishable* key, a Supabase *anon* key (designed to be public, provided RLS is correct), an analytics tool identifier.

    Never: a service_role key, a Stripe secret key, SMTP credentials, usage-billed third-party API tokens.

    Verification checklist

  • [ ] grep -r "NEXT_PUBLIC_" .env* and justify every variable one by one
  • [ ] Search your production bundle (.next/static/chunks/) for your own secrets
  • [ ] Revoke and regenerate any key that was ever exposed, even briefly — deployed builds are archived by caches and crawlers
  • [ ] Move sensitive calls to Route Handlers or Server Actions
  • [ ] Add a CI check that fails if a known key pattern appears in the bundle
  • Our Next.js audit includes production bundle analysis: we find exposed secrets in roughly a third of the applications we test. Check yours before someone else does.

    Related articles

    Three adjacent analyses to keep exploring the same attack surface.

    Sources

    Written by CleanIssue
    Reviewed on 2026-06-22

    Related services

    If this topic maps to a real risk in your stack, these are the most relevant CleanIssue audits.

    Need an external review of your HR SaaS?

    Share your product, stack, and client context. We will come back with the right review scope.

    Discuss your audit