Fix environment variables leaking into the browser JavaScript bundle

Environment variables prefixed with NEXT_PUBLIC_ (Next.js) or VITE_ (Vite) are embedded into the client-side JavaScript bundle at build time. If you accidentally use these prefixes for sensitive values like database URLs, API secrets, or private keys, those values are visible to anyone who views your site's source code.

Error messages you might see

NEXT_PUBLIC_DATABASE_URL is visible in the browser's Sources tab
VITE_SECRET_API_KEY appears in the compiled JavaScript bundle
process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY is accessible in the client
import.meta.env.VITE_DATABASE_PASSWORD is bundled into the frontend

Why this happens in AI-generated code

1

Misunderstanding the NEXT_PUBLIC_ prefix

Next.js only exposes environment variables prefixed with NEXT_PUBLIC_ to the browser. AI tools sometimes prefix sensitive variables with NEXT_PUBLIC_ because the code needs to use them in a client component. The correct fix is to move that logic server-side, not to expose the variable.

2

Misunderstanding the VITE_ prefix

Vite exposes all variables prefixed with VITE_ via import.meta.env. AI-generated Vite projects often use VITE_API_KEY or VITE_DATABASE_URL, making these values readable by anyone who opens the browser dev tools on your site.

3

Copying .env.example files with real values

AI tools sometimes generate .env.example files with placeholder names like NEXT_PUBLIC_OPENAI_KEY. Developers fill in real values and the prefix causes them to be bundled into the client.

How to fix it

1

Remove the public prefix from sensitive variables

Rename any sensitive variable to remove the NEXT_PUBLIC_ or VITE_ prefix. For example, change NEXT_PUBLIC_STRIPE_SECRET_KEY to STRIPE_SECRET_KEY. This makes it available only on the server. Then move the code that uses it to an API route or server component.

2

Audit your build output for leaked values

For Next.js, run `npx next build` and search the .next/ directory: `grep -r 'your-secret-value' .next/`. For Vite, build and search the dist/ directory. If your secret appears in any output file, it is exposed to the public.

3

Use server-only patterns for sensitive operations

In Next.js, use API routes (app/api/), Server Components, or Server Actions to access secrets. In Vite apps, set up a backend (Express, FastAPI, etc.) and proxy sensitive API calls through it. The browser should never need direct access to a secret key.

4

Get professional help

Still stuck? Our engineers can audit your environment variable configuration and restructure your app to keep secrets server-side. Visit /services to get started.

Related technologies

Can't fix it yourself?

Our code audit identifies this issue and dozens more. Get a prioritized fix list.

Most Popular

Security Review

Security Review

from $250

Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.

Request a Quote

Security Review

Full Pentest

Custom

Enterprise-grade engagement tailored to your needs. Dedicated engineer, ongoing support.

Fix Bugs

Bug Fixing

from $200

Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.

Request a Quote

Fix Bugs

Ongoing Support

Custom

Enterprise-grade engagement tailored to your needs. Dedicated engineer, ongoing support.

Refactor Code

Refactoring

from $400

Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.

Request a Quote

Refactor Code

Full Rewrite

Custom

Enterprise-grade engagement tailored to your needs. Dedicated engineer, ongoing support.

All projects start with a free consultation. We scope your project and provide a fixed quote before any work begins.

Frequently asked questions

How do environment variables work in Next.js vs Vite?

In Next.js, only variables prefixed with NEXT_PUBLIC_ are available in the browser. All others are server-only. In Vite, variables prefixed with VITE_ are exposed to the browser via import.meta.env. In both cases, the prefix controls visibility. Unprefixed variables are only available on the server.

What should I do if a secret was already exposed in production?

Rotate the secret immediately by generating a new key from the provider's dashboard. Remove the public prefix, redeploy your app, and check the new build output to confirm the secret is no longer present. The old key should be considered compromised.

Which environment variables are safe to expose to the client?

Only values that are public by design: Supabase anon keys, Firebase API keys, Google Analytics IDs, Stripe publishable keys, and public API base URLs. Never expose database URLs, secret API keys, private keys, or any credential that grants write access or bypasses security.

Still stuck? We can fix it for you.

Send us your repo. We'll diagnose the issue and give you a fixed quote within 24 hours.

Request a Quote