AI Build South Africa
Checked against the Vite, Next.js and Netlify documentation on environment variables, September 2026.

Quick answer

Your builder's preview and your live site are often separate environments. They run the same code, but a value set for one isn't always there for the other. When the live site asks for a key or address it was never given, it gets nothing back, and whatever needed it stops working.

Check five things in order: the value is set for the live site, its name matches exactly, the site was rebuilt or redeployed after the change, the live site has the live key rather than the test one, and the code reads the value the right way. Secret keys only ever go in backend variables. The prompt at the end of this guide gets your AI to list every value your project needs.

Why a value can work in preview and vanish once you're live

An environment variable is a named value your code looks up while it runs, instead of having it typed into the code: a database address, an email service's key, a payment provider's secret. Our guide to what an environment variable is covers the idea in full. What matters here is where the value lives. It doesn't live in your code. It lives in the environment the code runs in.

Your builder's preview and your live site are often two different environments. They run the same code, but each can have its own list of values. A separate host you move the site to starts with none of yours. Even on your builder's own hosting, a frontend value only reaches the live site once it has been built and published again. The preview usually has everything, because that's where you connected your services and pasted in your keys. The live site has only what was set for it. When the code reaches for a value the live site doesn't have, it gets nothing back, and the feature that needed it stops working.

That's why reading the code again rarely finds the fault. The code is the same in both places. The difference is outside it.

Two kinds of variable, and why the difference matters

Every variable in your project is read in one of two places, and that decides when a change takes effect and whether it can hold a secret.

Where a variable is read decides how it behaves
Question Frontend (browser) Backend (server)
When is the value picked up? Once, when the site is built. It's written into the files visitors download. While the code runs, each time it asks for it.
What does a change need? A new build and deploy. The backend code to run again with the new value, usually after a redeploy or republish.
Can anyone see it? Yes. Anyone who opens your site's files can read it. No. It stays on the server.
Can it hold a secret key? Never. Yes. This is where secret keys belong.

Many AI-built sites use a build tool called Vite, and it's a clear example of how the frontend side works. Vite's documentation says variables whose names start with VITE_ "will be exposed in client-side source code", while a variable you set without that prefix comes back undefined there, and that VITE_ values "are bundled into your source code at build time". So a VITE_ value is fixed into the finished files the moment the site is built. Change it later and the live site keeps the old value until it's built again. Other frameworks do the same thing with a different prefix, such as NEXT_PUBLIC_ in Next.js.

Some builders call the backend kind a "secret" and keep it in a separate place from ordinary settings. It's the same idea: a named value, read on a server, that never reaches the visitor's browser.

The five causes, in the order to check them

  1. The value was never set for the live site. It exists in the preview, or in a .env file on your computer, but not in the live environment. A .env file is often kept out of what gets uploaded, on purpose, so its values don't travel with the code. If you moved the site to a separate host, that host starts with no values at all.
  2. The name or value doesn't match exactly. Treat every name as case-sensitive: on the servers most sites run on, EMAIL_KEY and Email_Key are two different names, and one typo means the code asks for a value that isn't there. A frontend variable missing its prefix counts as a wrong name too: without VITE_ at the start, a standard Vite site's browser code never sees it. A value pasted with a stray space, or a key copied from the wrong account, fails the same way.
  3. It was changed, but nothing was rebuilt or redeployed. A frontend value needs a new build. A backend value needs the backend to pick it up, and on some platforms that means publishing again. Netlify's documentation, for one, says variable changes "require a build and deploy to take effect."
  4. The live site has the test value, not the live one. Payment, email and other services usually give you a test key and a live key. A test key on the live site gives errors or fake results. A live key left in the preview can send real emails or take real payments while you're testing.
  5. The code reads it the wrong way for where it runs. Browser code and server code look values up differently. In a Vite site, browser code reads them through import.meta.env. Code copied from a server example that uses process.env can fail in the browser, and each backend runtime has its own way too. This one fails in the preview as well, which is how you tell it apart from the other four.

How to tell which one you've got

The browser's console (right-click the page, choose Inspect, then Console) and your backend's logs usually say more than the screen does.

What you see, and where to look first
What you see Likely cause Check first
Console shows undefined A key or address is missing: not set for the live site, or the name or prefix is wrong Causes 1 and 2
Old value still used You changed a value, but nothing was rebuilt or redeployed since Cause 3
Payment, email or sign-in fails only live A backend secret missing from the live environment, or a test key in place of the live one Causes 1 and 4
"Unauthorised" or "invalid key" The wrong key, a test key, or a value with a stray space Causes 2 and 4
Fails in the preview too The code reads the value the wrong way; the error often names process or env Cause 5

What isn't possible

  • A secret key can't be made safe in frontend code. When a backend secret won't work, the quick fix people reach for is moving it into a VITE_ variable so the browser can see it. That works, and it publishes your key to every visitor. Our guide to why an API key can't go in the frontend explains what happens next. The real fix is a backend function that uses the key for you.
  • Your AI can't see your live settings. It can read your code and tell you which names the code expects. It usually can't open the settings of your live site or a separate host, so it can't confirm a value is there. That check is yours.
  • You often can't read a secret back. Many builders and hosts hide a secret's value once it's saved. If you're not sure a value is right, paste it in again rather than trying to check it by eye.
  • A working preview proves the code, not the live settings. Test the live site itself after every change to a value, especially anything that takes payments or sends email.

The prompt to give your AI

Copy this into your AI coding agent's chat. It gets you a list of every value your project needs, with where each is read, so you can compare it against what your live site actually has. It tells the AI not to change anything.

I'm not a coder. My app works in the preview but not on
the live site, and I think an environment variable is
missing. Don't change any files yet.

1. List every environment variable or secret this project
   reads, with its exact name, character for character.
2. For each one, say whether it's read in the browser
   (frontend) or on a server (backend), and which file
   reads it.
3. Say which ones are secret keys, and confirm none of
   those is read in the browser or has a browser prefix
   such as VITE_.
4. Say what breaks, and what error I'd see, if each one
   is missing on the live site.
5. Tell me which ones need a new build after a change,
   and which only need the backend to be redeployed.

Only name variables the code really reads. If you're not
sure about something, say so.

What to check in the AI's answer

  • Every name matches your live settings exactly. Put its list next to the variables set for your live site, on your builder or your host, and compare them letter by letter. Any name on its list that's missing from your live settings is your first suspect.
  • Each name comes with a file. A variable it can't point to a file for may be a guess. Ask it to quote the line that reads it.
  • No secret key is on the browser side. If it marks a secret as read in the browser, or finds one with a VITE_ prefix, ask it to move that work into a backend function before you do anything else.
  • It told you what needs a rebuild. If it doesn't separate frontend from backend values, ask again. That answer tells you whether saving a value is enough or the site has to be built again.
  • It didn't change anything. If it edited files anyway, ask it to show you exactly what it changed.

If you'd rather describe the symptom first, the Custom Prompt Builder turns "the payment page works in preview but not live" into a prompt your AI can act on.

Where to go next

Not affiliated with the platforms we write about

AI Build South Africa is an independent resource. We're not endorsed by, or an official partner of, Vite, Next.js or Netlify. See our Disclaimer for the full disclosure and our Terms of Service for the wider terms.

Frequently asked questions

Why is my environment variable not working after deploy?

Start with one check: open the variable settings for your live site and look for the exact name your code uses. If it isn't there, that's the fault; values set in the preview or in a .env file on your computer don't always carry over. If it is there, check the value, whether the site was rebuilt or redeployed since, and whether it's the live key rather than the test one.

Why are my environment variables undefined?

Undefined means the code asked for a name and got nothing back. The value isn't set in the environment the code is running in, the name is spelt differently, or a frontend variable is missing the prefix its framework needs, such as VITE_ in a Vite site. Compare the exact name in the code with the exact name in your live settings.

Why are my Vite env variables not loading?

Vite only passes the variables you set whose names start with VITE_ to your browser code, and that code reads them through import.meta.env, not process.env. The values are written into the files when the site is built, so a change on your host does nothing until the site is built and deployed again. Never put a secret key in a VITE_ variable, since anyone can read it.

Do I need to redeploy after changing an environment variable?

Usually, yes. A frontend variable is written into your site's files at build time, so it needs a new build and deploy. A backend variable is read while the code runs, but the backend often only picks up a new value after a redeploy or republish. Check your builder's or host's documentation to see whether saving a value redeploys for you.

How do I use environment variables in production?

Set each value in the live site's own settings, on your builder or your host, using the exact name your code expects. Don't rely on a .env file travelling with your code. Keep secret keys in backend variables only, use live keys on the live site and test keys in the preview, and test the live site after every change.

What's the difference between an environment variable and a secret?

A secret is an environment variable whose value must stay private, such as an API key or a password. Many builders keep secrets in a separate place and hide the value once it's saved. Other variables, such as a public address or which mode the site runs in, do the same job but have nothing to hide.

Related reading