Exported an AI Studio App? Your Gemini Key May Be in the Bundle (2026)

On October 13, 2026, a developer posted on Google's AI developer forum that an app exported from AI Studio had shipped their Gemini key to every visitor. They report about USD 4,010 in unauthorized charges over 94 days. The odd part: they say they never put the key in the project. It came from their computer's environment, set up for the Gemini CLI. We rebuilt the template and got the same result.

TL;DR

Older Google AI Studio web app exports use a vite.config that calls loadEnv(mode, '.', '') and copies GEMINI_API_KEY into the browser JavaScript through define. The empty prefix means it reads every environment variable on the build machine, so a key in your shell profile, .env.local, or your Vercel settings all end up in the public bundle. Search your built JS for AIza. If it's there, rotate the key and move the Gemini call server-side.

Which apps are affected

As of October 21, 2026, Google's AI Studio Build docs say the key is "injected into the server-side runtime and never included in client-side code." That describes apps built now. The same page says apps "built before May 14, 2026" get upgraded to the server-side approach "the next time you modify the app's Gemini features."

That upgrade happens inside AI Studio. If you downloaded the ZIP, pushed it to GitHub and deployed it to Vercel or Netlify months ago, your copy is still on the old template, and nothing upgrades it.

The forum post gives the heart of the exported vite.config like this:

vite.config.ts pattern, as quoted in the October 13 report
const env = loadEnv(mode, '.', '');
// ...
define: {
  'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
},

Some copies map process.env.GEMINI_API_KEY instead, or both. A public Vite + Gemini app on Hugging Face uses the same loadEnv(mode, '.', '') call with a comment saying the key "is injected into the app during the build process."

define does a find-and-replace at build time. Every process.env.API_KEY in your source becomes the literal key string in the shipped JavaScript.

Why the key leaks even if it's not in your project

The third argument to loadEnv is a prefix filter. Vite's own config docs put it plainly: set it to '' "to load all env regardless of the VITE_ prefix." With the default prefix, only VITE_ variables come through. With an empty string, everything does, including variables from the operating system, not just your .env files.

Now put that next to Google's own API key setup docs, which tell you to add export GEMINI_API_KEY=... to ~/.bashrc or ~/.zshrc so the client libraries pick it up automatically. Plenty of people did exactly that for the Gemini CLI. On their machine, every build of this template quietly pulls the key in.

The same thing happens in CI. Vercel's env var docs say your code can read project variables "during the Build Step." Add GEMINI_API_KEY in the Vercel dashboard, the way the AI Studio docs tell you to for ZIP exports, and the old template compiles it straight into the client.

We reproduced it

We built a minimal app with that pattern on Vite 6.4.4 (mapping both names) and checked the output each time:

Where the key was setKey in dist/assets/*.js?
Shell environment only, no .env filesYes
.env.local onlyYes
Shell environment only, loadEnv with its default VITE_ prefixNo
NowhereNo (value is undefined)

The first row is the one that surprises people. You can delete .env.local, check that nothing is committed, and still ship the key.

The usual leak check misses this. Most advice, including our own stolen key guide, tells you to grep for VITE_ or NEXT_PUBLIC_ key names. This variable is called GEMINI_API_KEY and arrives through define, so a prefix grep comes back clean. Search the built output for the key itself.

Check your app in two minutes

1

Look at vite.config.ts (or .js). You're looking for both of these:

grep -nE "loadEnv\([^)]*''\)" vite.config.*
grep -nE "process\.env\.(API_KEY|GEMINI_API_KEY)" vite.config.*

If both match, you have the legacy template.

2

Search the bundle for the key. Every Google API key starts with AIza. Build locally and search the output:

npm run build
grep -rlo "AIza[0-9A-Za-z_-]\{35\}" dist/

Or check the live site: open DevTools, go to the Sources tab, press Ctrl+Shift+F (Cmd+Option+F on a Mac) and search for AIza. A hit in your own JavaScript means anyone can copy the key.

3

If it's there, revoke it now. The key is already public, so delete it in AI Studio even if that breaks the app until the fix below is deployed, and put a new key only on the server. Then check billing for usage you don't recognize. The forum post's charges ran for months before anyone noticed, and an earlier thread from April 2026 reports about USD 6,000 within roughly 40 minutes from a key in a Vite bundle built from AI Studio sample code.

Fix it properly

Rotating alone doesn't help. The next build compiles the new key in too. The key has to stop reaching the browser.

  1. Delete the define entries for process.env.API_KEY and process.env.GEMINI_API_KEY, and remove the empty-prefix loadEnv call if nothing else needs it.
  2. Move the Gemini call into server code. On Vercel or Netlify that's a serverless function: the browser calls /api/generate, and the function reads process.env.GEMINI_API_KEY and calls Gemini. Google's API key docs recommend exactly this: "Never expose keys client-side in production."
  3. Or let AI Studio do it. Open the project in AI Studio, ask for a change to its Gemini features so the agent upgrades it, then re-export. Check the new vite.config before you deploy.

Don't rename the variable to VITE_GEMINI_API_KEY. That's a common forum suggestion when an exported app can't find its key, and it ships the key on purpose.

Putting a restriction on the key (allowed APIs, HTTP referrers) limits what a copied key can do, but a referrer header is easy to fake from a script. It's a seatbelt, not a fix.

Where this stands

On October 20 a forum moderator replied to the October 13 report: "Thank you for reporting this. We are actively working on it." We couldn't find an advisory or template change notice from Google as of October 21, 2026, and the Build docs say nothing about copies that were already exported. Since the current Build mode already runs Gemini calls server-side, what's left is the long tail of apps that were exported earlier and are still deployed.

Our scanner flags Google API keys sitting in a site's public JavaScript, and this template is a reliable way to put one there. If you shipped anything from AI Studio before mid-May, scan the live URL.

Is my Gemini API key exposed if I exported my app from AI Studio?

It depends on when the app was built. Google's docs say current AI Studio apps call Gemini from server-side code. Older exports used a vite.config that copies GEMINI_API_KEY into the browser JavaScript at build time. If your vite.config calls loadEnv with an empty third argument and has a define block for process.env.API_KEY or process.env.GEMINI_API_KEY, the key ships to every visitor.

I never put the key in my project. How did it get into the bundle?

loadEnv with an empty prefix reads every environment variable on the machine doing the build, not just your .env files. Google's own API key docs tell you to export GEMINI_API_KEY in ~/.bashrc or ~/.zshrc. If you did that for the Gemini CLI, any build of that template on your machine picks it up. The same goes for a key you added to Vercel or Netlify, which the build step can read.

Will Google fix my exported app automatically?

No. Google says apps built before May 14, 2026 get upgraded to the server-side approach the next time you modify the app's Gemini features inside AI Studio. A copy you downloaded as a ZIP or pushed to your own repo is your code now, and nothing changes it for you.

Does renaming the variable to VITE_GEMINI_API_KEY fix it?

No, that makes it worse in a different way. Vite puts any VITE_ variable into the client bundle on purpose. The only fix is to make the Gemini call from server code so the key never reaches the browser.

Shipped an AI Studio app?

Scan the live URL for API keys in your JavaScript in 60 seconds.

How-To Guides

Exported an AI Studio App? Your Gemini Key May Be in the Bundle (2026)