Your production app throws one of these:
import.meta.env.VITE_SUPABASE_URL is undefined supabaseUrl is required Cannot read properties of undefined Vite replaces import.meta.env values when the app is built, and only variables that start with VITE_ reach browser code. Set those VITE_ variables on the host before the build runs, then rebuild. Keep anything secret out of VITE_ variables entirely.
I see this constantly in Lovable and Bolt apps the first time they leave the builder and land on Vercel, Netlify, or Cloudflare.
Why it happens
- The variable was added after the build. Values are written into the bundle at build time, so adding a variable on the host does nothing until you rebuild.
- Missing
VITE_prefix. Variables without that prefix are not exposed to client code, so they read asundefinedin the browser. Vite's docs: variables prefixed withVITE_are exposed in client-side source code after bundling. - Set for the wrong environment. The variable exists for preview builds but not production, or the other way round.
- A
.envfile was not deployed. A.env.localfile is meant to be git-ignored, so a host building from the repository never sees it.
Find the cause
- Search the code for
import.meta.envand list every variable it reads. - In the host's settings (Vercel, Netlify, Cloudflare), check each one exists for the production environment with the exact name.
- Check the date of the last build against when the variables were added.
Fix 1: set the variables before building
- Add each
VITE_variable in the host's environment settings for production. - Trigger a new deployment so the build reads them.
VITE_SUPABASE_URL=https://your-project.supabase.co VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_... # never a secret key in a VITE_ variable Fix 2: move secrets to the server
Anything secret (a Stripe secret key, a Supabase secret key, a third-party API key) belongs in a server or edge function's environment, not in a VITE_ variable. Vite compiles VITE_* values into the code the browser downloads, so anyone can read them. Vite's own docs say the same: do not put sensitive information in VITE_* variables.
Check the fix worked
- Open the production site: the feature that needed the variable works.
- Run a free Launch Check: https://stacksmesh.com/tools/launch-check?utm_source=devto&utm_medium=article&utm_campaign=BR-0003 — no secret keys found in the bundle.
Stop it coming back
- Keep a
.env.examplefile listing every variable the app needs, without values. - Fail the build when a required variable is missing, instead of failing in the browser.
Quick answers
Why does it work on Lovable and not on my host? Lovable sets the values for its own builds. A new host needs them set again, before its first build.
Are VITE_ variables hidden from users? No. They are in the downloaded JavaScript.
Full write-up with the same steps: https://stacksmesh.com/fix/vite-env-variable-undefined-in-production?utm_source=devto&utm_medium=article&utm_campaign=BR-0003
I wrote this with AI assistance and reviewed it myself.


