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 tabVITE_SECRET_API_KEY appears in the compiled JavaScript bundleprocess.env.NEXT_PUBLIC_STRIPE_SECRET_KEY is accessible in the clientimport.meta.env.VITE_DATABASE_PASSWORD is bundled into the frontendWhy this happens in AI-generated code
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.
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.
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
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.
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.
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.
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.
Can't fix it yourself?
Our code audit identifies this issue and dozens more. Get a prioritized fix list.
Security Review
Security Review
Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.
Request a QuoteSecurity Review
Full Pentest
Enterprise-grade engagement tailored to your needs. Dedicated engineer, ongoing support.
Fix Bugs
Bug Fixing
Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.
Request a QuoteFix Bugs
Ongoing Support
Enterprise-grade engagement tailored to your needs. Dedicated engineer, ongoing support.
Refactor Code
Refactoring
Expert engineer works on your project directly. Fixed scope, fixed price, no surprises.
Request a QuoteRefactor Code
Full Rewrite
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.
Related resources
Related Technologies
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.