Skip to content
afterbuild.dev
$ grep -r "VITE_" dist/ | head -3

My environment variables work locally and are empty in production

The values are baked in at build time. Adding them afterwards is too late by design.

Seen in apps built with Lovable, Bolt, Replit.

16 of 100

Lovable projects have a .env.example, so for the other 84 the list of variables the app needs is written down nowhere.

100 public Lovable repositories, read 2026-08-03 · method and scripts in the measurements

What is actually happening

Vite replaces `import.meta.env.VITE_SOMETHING` with the literal value while building. After that the value is a string inside the bundle; the running app never looks it up again.

So the environment of the server that serves the files is irrelevant. What matters is the environment of the machine that ran the build.

Two consequences follow. Setting the variable in a hosting dashboard after the build does nothing until you build again. And every value handed to the browser this way is readable by anyone who opens the file.

Confirm it in one command

SHELL
grep -r "VITE_" dist/ | head -3

Finding the literal value in the built files is normal and expected — that is where it is supposed to end up. Finding the variable name instead means it was never substituted.

Fixing it yourself

Where it stops being a small job

When a value that should never have reached the browser is already in the bundle. Then the question is not how to configure it, but what that value can be used for by a stranger — and answering that requires looking at the service on the other end.

If something is already in the bundle that should never have been, the useful question is what a stranger could do with it. That one we would rather answer properly than quickly.

Send us the app