Fix API keys and secrets leaked into your frontend JavaScript bundle
If your API keys, database credentials, or third-party secrets are visible in the browser's developer tools or JavaScript bundle, they are compromised. AI code generators frequently place secrets directly in client-side code because it is the simplest path to a working demo. This is a serious security issue that requires immediate action.
Error messages you might see
Warning: API key found in client-side bundlesk-... or sk_live_... visible in Network tab request headersNEXT_PUBLIC_SECRET_KEY should not be prefixed with NEXT_PUBLIC_Vite: import.meta.env.VITE_SECRET_KEY is exposed to the clientWhy this happens in AI-generated code
AI tools put secrets in client-side environment variables
AI code generators often tell you to add secrets like API keys as NEXT_PUBLIC_ or VITE_ prefixed variables so they are accessible in the browser. This works, but it exposes the value to anyone who views your site's source code.
Direct API calls from the browser with secret keys
AI-generated code frequently calls third-party APIs (OpenAI, Stripe secret key, SendGrid) directly from React components using fetch or axios. The API key is included in the request and is visible in the browser's Network tab.
Hardcoded credentials in source files
Some AI tools embed API keys directly in the source code as string constants rather than using environment variables at all. These end up in the compiled JavaScript bundle and in your git history.
How to fix it
Move secret API calls to a server-side route
Create a Next.js API route (app/api/...) or Express endpoint that makes the third-party API call server-side. Your frontend calls your own API route, and the secret key never leaves the server. For example, instead of calling the OpenAI API from a React component, call /api/chat which uses the key from a server-only environment variable.
Rotate all exposed keys immediately
If a key was ever in client-side code, even briefly, treat it as compromised. Go to each provider's dashboard (OpenAI, Stripe, etc.) and rotate the key. Then store the new key in a server-only environment variable (without the NEXT_PUBLIC_ or VITE_ prefix).
Audit your environment variable prefixes
Review your .env files and search for NEXT_PUBLIC_ or VITE_ prefixed variables. Any variable with these prefixes is bundled into the client-side JavaScript. Only public, non-sensitive values (like a Supabase anon key or a Google Analytics ID) should use these prefixes.
Get professional help
Still stuck? Our engineers can audit your codebase for exposed secrets and set up proper server-side API patterns. 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
Are Supabase anon keys and Firebase API keys safe to expose?
Yes. Supabase anon keys and Firebase API keys are designed to be public. Security is enforced server-side through Row Level Security (Supabase) or Security Rules (Firebase). These are not secrets.
How can I check if my keys are in the client bundle?
Open your deployed site, press F12, go to the Sources tab, and search for your key string. You can also run `grep -r 'sk-' .next/` or `grep -r 'sk_live' dist/` on your build output. If your key appears anywhere, it is exposed.
My app works locally with the key in the client. Why is this a problem?
It works because the key is valid. The problem is that anyone visiting your site can extract the key from the JavaScript bundle or Network tab and use it themselves. This can lead to unauthorized usage, large bills, or data breaches depending on the API.
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.