Provider imports
Follow imports into `"use client"` pages, browser utilities, or direct click handlers.
If a client-side page constructs a Gemini provider client with a `NEXT_PUBLIC_` key, assume the key can be recovered from the browser build when configured. Move provider calls to a server route, rotate the exposed key, authorize the requesting user, and put request, concurrency, and spend limits before each provider call.
This guide covers check 03: Secrets and key management; check 06: Performance and scalability in the Zenveus Production Readiness Standard.
For builders
A Gemini key in browser code can be copied and used outside your app. A browser credit counter cannot control those direct calls. Rotate the exposed key and route paid generation through an authenticated server with quotas.
A scoped repair request
Use this prompt in Lovable, Cursor, Replit, or Claude Code with the relevant server files available.
Audit my Gemini integration for keys in client components or public environment variables. Rotate exposed keys, move paid generation to an authenticated server route, and enforce input bounds, shared quotas, timeouts, and output limits before the provider call. Work on a branch with synthetic data and mocked external services. Show the smallest diff, identify required adapters and deployment settings, and add allowed and denied tests that prove side effects cannot happen before checks pass. Do not disable security checks to make a test pass.The same failure may appear as
Find the failure layer
Each check removes a class of causes. Keep the first failing result, its timestamp, and the production log beside it.
Follow imports into `"use client"` pages, browser utilities, or direct click handlers.
Check provider usage and restrictions for unexpected calls.
A UI credit counter is insufficient if the provider call happens directly in the browser.
Ranked diagnosis
The client page imports a Gemini helper initialized with a public-prefixed key.
The prefix deliberately makes configured values available to the browser.
Direct calls can bypass a local counter.
The app has no server checkpoint before provider spending.
Step-by-step repair
Edit lib/gemini.ts or utils/AiModal.ts and any use client page that imports it. Move the provider call to app/api/generate/route.ts.
Production safety ruleNever disable access controls, expose service keys, or add wildcard CORS as a routine shortcut.
Create a replacement key in the provider project, configure it only on the server, and revoke the exposed key. Review usage and available API restrictions. Rebuilding without rotation leaves copied keys usable.
Keep the SDK and GEMINI_API_KEY in a module marked server-only. The browser should send its input to your own API and receive only the permitted generated output.
Verify the user, validate input and request size, use a server-selected model and output cap, then reserve user and global quota atomically. Do not accept a model, key, or spend limit from the browser.
Remove NEXT_PUBLIC provider variables, rebuild, and inspect fresh assets. Test the replacement route with a mock provider before making a small authorized provider call.
Implementation example
// lib/gemini-server.ts
import 'server-only';
export function getGeminiKey(): string {
const key = process.env.GEMINI_API_KEY;
if (!key) throw new Error('GEMINI_API_KEY is missing');
return key;
}
// Only the authorized server handler imports this helper.
// Browser code sends input to /api/generate and never imports it.Use the helper inside your installed Gemini SDK integration after authorization and quota reservation. It prevents accidental client imports; it does not implement authentication or quotas by itself.
Prove the repair
Run these checks with synthetic data in your test environment, then repeat the relevant acceptance checks after deployment.
When the built-in AI fix makes it worse
Pause generated changes, restore a known working branch, and capture one failing request with its logs. Change one layer and rerun the allowed and denied checks before proceeding.
Engineering handoff
We trace one production request through the complete path, isolate the failing boundary, and leave behind evidence your team can repeat.
Provider constructors and the served client graph that contains the credential.
Provider usage history, key restrictions, rotation, and old build artifacts.
Authentication, atomic quotas, timeouts, and model/input/output bounds.
Mock provider counts when identity, quota, or input checks fail.
Typical repair pattern
No key appears in client assets; anonymous and over-quota requests stop before the provider call.
Before the next release
Clear answers
No. Next.js makes configured public-prefixed values available to browser code at build time.
It can guide the UI, but quota enforcement belongs at the server boundary before a billable call.
A deliberate public demo can be anonymous with strict abuse controls. Account features should require identity and quotas.
Run the verification checks on this page against your test environment, then repeat the relevant checks after deployment. Example code needs your app's authentication, data model, and configuration; reading the guide alone does not verify your deployment.
Related symptoms
Official documentation and library references
Free next step
The free tool helps you inspect this symptom. Its result does not establish whether the whole app is production ready.
The Verdict
We can see the symptom from here. What we cannot tell you from outside is whether it is contained or structural. A scanner collects evidence. A named senior engineer makes the decision. For $299, a named senior engineer reads your code and signs a written Verdict against the nine checks in the Zenveus Production Readiness Standard. The 48-hour clock begins when the required access and context are available. If the report does not give your developer a list they can act on, you do not pay.
The 48-hour clock starts when the required access and context are available.
Free decision aid
Get a senior view of the constraint, the evidence you have, and the next decision that removes the most risk.
No email required for this decision aid. Dismiss once and this popup stays closed for the session.