Vite says your env variable is undefined in production: fix it before the next build
VITE_ values are baked in at build time. Set them on the host, rebuild, and keep secrets off the client.

Production works until it doesn't. Suddenly you see import.meta.env.VITE_SUPABASE_URL is undefined, or supabaseUrl is required, or a plain Cannot read properties of undefined.
Vite does not read environment variables at request time in the browser. It replaces import.meta.env values when the app is built, and only names that start with VITE_ make it into client code. So the fix is almost always: set those variables on the host before the build, then rebuild. And never put a secret in a VITE_ variable.
Four reasons the value is missing
- Added after the last build. Changing host env settings does nothing until a new build runs.
- No
VITE_prefix. Without it, the name never reaches browser code. Vite documents this: onlyVITE_-prefixed variables are exposed after bundling. - Wrong environment. Preview has it; production does not (or the reverse).
.env.localstayed on your laptop. Those files are git-ignored on purpose, so the host never sees them when it builds from the repo.
Pin it down
- Search for every
import.meta.envuse and list the names. - Open the host's environment settings and confirm each name exists for production, spelled exactly the same.
- Compare when the variables were added with the timestamp of the last successful build.
Fix: set VITE_ vars, then rebuild
In Vercel, Netlify, or Cloudflare, add production values like:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...
Then trigger a fresh deployment so the build can read them. Publishable or anon keys that are meant for the browser can live here. Secret keys cannot.
Secrets belong on the server
A Stripe secret, a Supabase service role key, or any third-party API secret must live in a server or edge function environment. Vite's docs warn that VITE_* values are bundled into source at build time. Anyone who can open your site's JavaScript can read them.
Confirm it
- The production feature that needed the variable works.
- A free Launch Check finds no secret keys in the shipped bundle.
Keep it from coming back
Ship a .env.example that lists every required name with empty values. Prefer failing the build when a required variable is missing over discovering it in the browser.
Lovable worked, my host doesn't? Lovable injects values for its own builds. Your new host needs the same names set before its first build.
Step-by-step on our site: Environment variable is undefined in production.
I wrote this with AI assistance and reviewed it myself.
About the author
- Founder and CEO of StacksMesh (stacksmesh.com). We fix, launch and migrate apps built with Base44, Lovable, Bolt and Replit, with a fixed price in writing before any work. I write about making AI-built apps safe and production-ready.
Comments
Join the discussionNo comments yet. Be the first to comment.

