Secrets

Environment Variables and API Keys, Explained for Vibe Coders

10 min read · Updated October 15, 2026 · Checked against official docs

Your AI tool asked for an “API key” and told you to “add it to your environment variables”. Then something stopped working, or worse, it worked and your key ended up somewhere public. This guide explains the idea in plain language, then shows where keys go on each platform.

The one-sentence version

An environment variable is a named setting (like STRIPE_SECRET_KEY) that lives outside your code, so your code can say “use whatever value is called X” without the value being written in the file. That lets you keep secrets out of your code, out of GitHub and out of AI chats, and use different values for testing and for the live site.

Two kinds of keys: the ones you can show, and the ones you can’t

Almost every service hands out two kinds of key. Learn to tell them apart and you’ve avoided the most expensive vibe-coding mistake there is.

Public / publishableSecret
Who may see itAnyone. It ships inside your web pageOnly your server code
What it can doOnly what your security rules allowUsually everything on your account
SupabasePublishable key sb_publishable_… (legacy: anon)Secret key sb_secret_… (legacy: service_role)
StripePublishable key pk_…Secret key sk_…, restricted key rk_…, webhook secret whsec_…
AI providers (OpenAI, Anthropic…)Usually noneThe API key

Supabase puts it nicely: the publishable key “is taped to the front door, and it only opens the lobby. The secret key is the master key.” A Supabase secret key bypasses Row Level Security completely. (Supabase: API keys) Stripe likewise says only publishable keys are safe to expose. (Stripe: API keys) A leaked AI key means someone else spends your credits.

Heads up: Supabase is deprecating the legacy anon and service_role keys by the end of 2026. If a tutorial or AI tool tells you to copy a long key that starts with eyJ, it was written for the legacy keys.

The prefix rule: VITE_ and NEXT_PUBLIC_ mean “put this in the browser”

Most AI app builders produce either a Vite app (Lovable, most Bolt projects) or a Next.js app. Both have a special prefix that tells the build tool “copy this value into the JavaScript that every visitor downloads”:

  • Vite: variables starting with VITE_ are exposed in client-side code. Vite’s docs say outright that VITE_* variables “should not contain sensitive information such as API keys”. (Vite: Env variables)
  • Next.js: variables starting with NEXT_PUBLIC_ are inlined into the JavaScript sent to the browser at build time. Everything without the prefix stays on the server. (Next.js: Environment variables)

So the rule is simple:

# ✅ Fine: these are public by design
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...

# ❌ Never do this. The prefix ships your secret to every visitor
VITE_OPENAI_API_KEY=sk-...
NEXT_PUBLIC_STRIPE_SECRET_KEY=sk_live_...

# ✅ Secrets: no public prefix, read only from server code
OPENAI_API_KEY=sk-...
STRIPE_SECRET_KEY=sk_live_...
SUPABASE_SECRET_KEY=sb_secret_...

“But it says undefined in the browser!” That’s the system working. If your browser code needs a secret to call an API, the fix is not to add the prefix. The fix is to move that API call into server code (an API route, a serverless function or an Edge Function) and have the browser call that. Ask your AI tool: “Move the call to [service] into a server-side function so the API key never reaches the browser.”

.env files and Git

Locally, variables usually live in a file called .env or .env.local in your project folder.

  • In a normal Vite or Next.js project (including Cursor projects), keep .env* files with secrets out of Git. Next.js’s default template adds them to .gitignore for you, and Vite recommends ignoring *.local files.
  • Before your first push, run git status and make sure no .env file with real secrets is listed.
  • If a secret was ever committed, assume it’s leaked, even if you deleted it later. Git history keeps it. Rotate it (see below).

Lovable is the exception. Lovable needs its .env file committed so builds can read the VITE_ values. That’s fine because that file should only ever contain public values. Secrets go in Lovable’s Secrets manager instead. (Lovable: Secrets)

Where to put keys on each platform

Lovable

  • Secrets (backend values) live in More → Cloud → Secrets. They’re encrypted, injected into your Edge Functions and never reach the browser. Values are write-only after saving.
  • VITE_ values live in the project’s .env file. Lovable rejects VITE_-prefixed names in Secrets on purpose.
  • Usually you don’t add secrets by hand. When a feature needs one, Lovable asks for it through a secure input in the chat. Prefer that over pasting keys into a normal message.

Replit

  • Open your project, select Tools, then under Setup select Secrets. Click New Secret, enter a Key and Value, then Add Secret. Your code reads it as an environment variable.
  • Replit also has a separate Configurations section for non-sensitive settings. Don’t store API keys there.
  • Published apps have their own production values: open Publishing, select Adjust settings and find Production app secrets. Check them before you launch. (Replit: Secrets)

Bolt

Bolt keeps API keys in its own Secrets panel while you build. One gotcha: if you export a Bolt project and deploy it somewhere else (like Vercel Drop), the export doesn’t include the values from Bolt’s Secrets panel. You have to recreate each one on the new host and redeploy. (Vercel: Deploy a Bolt.new app with Vercel Drop)

Vercel (for Cursor, Bolt exports, or anything on GitHub)

  1. Open your project in the Vercel dashboard and select Environment Variables in the sidebar.
  2. Enter the Name and Value. Choose Secret for keys (write-only after saving) or Config for values that should stay readable.
  3. Pick which environments it applies to: Production, Preview and/or Development.
  4. Click Save, then redeploy.

That last step matters: changes to environment variables only apply to new deployments, never to ones that already exist. If you changed a key and “nothing happened”, that’s why. (Vercel: Managing environment variables)

To copy your Vercel Development variables to your machine, run vercel env pull, which writes them into a local .env file. Make sure that file is gitignored. (Vercel: Environment variables)

Use different keys for testing and for real

Give your live site and your test or preview versions different values:

VariableProduction (live site)Preview / Development
STRIPE_SECRET_KEYlive key sk_live_…test key sk_test_…
Supabase keysyour real projecta separate staging project if you have one
Site URLhttps://yourdomain.comlocalhost or the preview URL

This keeps a half-finished preview from charging real cards or writing junk into your real database.

Never paste secrets into AI chat

Treat AI chats like email. Supabase’s own guidance is that secret keys should never travel over chat, email or SMS. (Supabase: API keys) Instead, put the key in the platform’s secret storage and tell the AI the name of the variable: “Use the RESEND_API_KEY environment variable. Don’t ask me for the value.”

If a key leaked: rotate it calmly

  1. Fix the cause first. Remove the key from your code, your bundle or your repo.
  2. Create a new key at the provider (Stripe, Supabase, OpenAI…).
  3. Replace it everywhere it’s used (Vercel env vars, Lovable Secrets, Replit Secrets) and redeploy.
  4. Confirm everything works with the new key, then delete or revoke the old one. For Supabase secret keys, deleting can’t be undone, so do this step last.

Quick self-check (2 minutes)

  • No secret has a VITE_ or NEXT_PUBLIC_ prefix
  • Search your live site’s JavaScript (DevTools → Sources) for sk_, sb_secret_, service_role and whsec_. Nothing should turn up
  • .env files with secrets are gitignored (except Lovable’s public-only .env)
  • Production uses live keys and previews use test keys
  • You redeployed after your last env var change

Official sources used: Supabase: API keys · Stripe: API keys · Vite: Env variables and modes · Next.js: Environment variables · Lovable: Secrets · Replit: Secrets · Vercel: Managing environment variables · Vercel: Bolt + Vercel Drop. Checked October 2026.

Want the whole launch path in one place?

The Ship It Kit bundles copy-paste prompts, step-by-step deploy guides and a pre-launch checklist for Lovable, Bolt, Cursor and Replit apps. One-time $19.

Get the Ship It Kit, $19 See what's inside

Spotted something out of date? Platforms change their screens often. The official docs linked above are always the source of truth.