Environment variables
Environment variables are key–value settings supplied to an application at runtime rather than hard-coded into its source. They are the standard way to keep secrets — API keys, database URLs, tokens — out of the codebase and to vary configuration between local, staging, and production environments.
Also known as: env vars · secrets
A critical distinction in front-end frameworks is public vs. private variables: anything prefixed for client exposure (for example NEXT_PUBLIC_ in Next.js or VITE_ in Vite) is bundled into the browser and is NOT secret. True secrets like a service_role key must stay server-only and never carry a public prefix.
When you move a Lovable app to your own host, environment variables are also the most common thing left behind, which is why a deploy that worked in Lovable can break immediately on Vercel or Netlify. Common mistake: putting a true secret behind a public prefix like NEXT_PUBLIC_ or VITE_ so it gets bundled into the browser — public-prefixed values are visible to every visitor and must never hold a service_role key or any other secret.
Three systems set variables in a Lovable app and they do not have equal standing, which is the part almost no page states. From lowest precedence to highest: values in a generic .env file, then values in a mode-specific file such as .env.production, then variables that already exist in the environment when the build runs — the ones you set in your host's dashboard. Vite's documentation is explicit on both steps: a mode-specific env file takes higher priority than a generic one, and variables that already exist when Vite is executed have the highest priority and are not overwritten by .env files. That order is why a value set in the Vercel or Netlify dashboard silently wins over the .env file you have been editing locally.
The second boundary is not about precedence at all — it is about who can read the value. Only variables carrying the client prefix are inlined into the browser bundle; everything else is dropped from the client build entirely. Vite states plainly that VITE_* variables should not contain sensitive information such as API keys, because their values are bundled into your source code at build time. A key that must stay private therefore cannot be an environment variable in the front end under any prefix, correct or not.
That is what the third system is for. Secrets belong in the server-only store — Lovable's built-in secrets, or Supabase's — and are read inside an Edge Function that never ships to the browser. Lovable's own FAQ answers the question "Can I store sensitive API keys in Lovable?" with "No!", and directs you to built-in secrets or Supabase so keys are used only in backend code and never exposed in the browser. Precedence decides which value wins; the client prefix decides who can see it; and only the server-side store decides whether a secret is actually secret.
One operational note that costs people an afternoon: env files are read once, when the dev server starts. Vite's documentation says so directly — .env files are loaded at the start of Vite, so restart the server after making changes. A variable that looks absent is very often present and simply not reloaded.
Related
Stuck on the thing this term describes? Talk to a senior engineer.
Book a free 30-minute audit call. We'll diagnose what's wrong and tell you exactly what it costs to fix.