Your Lovable app is broken after GitHub export: the missing env var fix
You connected your Lovable project to GitHub (or cloned a repo someone else exported), ran npm install and npm run dev, and got a blank white screen. Or you deployed the repo straight to Vercel or Netlify and the live site renders nothing. The app worked perfectly inside Lovable. Nothing is wrong with the code you exported. The repo is simply missing its environment variables, because Lovable injects them at publish time and they never get committed to GitHub. We diagnosed a real Lovable campus app with exactly this: the page served zero rendered content until the env handling was fixed. Here is how to fix yours in about ten minutes.
Why the exported repo breaks when the Lovable version works
Inside Lovable, your Supabase URL and publishable key are stored as project settings and injected into the build automatically. But .env files are gitignored (correctly, they can hold secrets), so the GitHub repo ships without them, and many Lovable exports do not include a .env.example either. When you run the repo anywhere Lovable is not doing the injecting, every import.meta.env.VITE_SUPABASE_URL read comes back undefined. The same applies to remixes: remixing or cloning someone else's Lovable project copies their code, never their env values, and you are expected to wire in your own Supabase project.
The import-time crash: why the screen is blank instead of showing an error
This is the part that makes people think the export itself is corrupted. Lovable apps typically create the Supabase client in src/integrations/supabase/client.ts (older or hand-edited projects sometimes use src/lib/supabase.ts). That file runs at module load, before React ever mounts. Two ways it dies:
- It throws immediately. Code like
if (!supabaseUrl) throw new Error(...), orcreateClient(undefined, undefined)raisingsupabaseUrl is required, kills the whole JavaScript bundle before a single component renders. Your ErrorBoundary never fires because React never started. Result: a permanently blank page with no visible error. - It limps along with undefined values. No throw, but every Supabase call fails, so the app renders a shell and nothing loads.
How to confirm this is your problem: open the blank page, press F12 (or right-click, Inspect), open the Console tab, and reload. If the very first red error mentions supabaseUrl is required, VITE_SUPABASE_URL, or a throw inside client.ts, and the Elements tab shows an empty <div id="root"></div>, you have the import-time crash. In the campus app we rescued, that empty root div was the entire symptom, and the fix took the rendered page from zero content to a working app.
Step 1: find out which variables the code expects
Search the repo for import.meta.env. In a Lovable export you will almost always find VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY (some projects use VITE_SUPABASE_ANON_KEY instead; use whatever name the code actually reads, exactly). Also note VITE_SUPABASE_PROJECT_ID if it appears. A quick way from the terminal:
grep -rn "import.meta.env" src/
Step 2: get the real values from your Supabase dashboard
Log in at supabase.com, open the project this app uses (if you remixed someone else's app, create a fresh project of your own), then go to Settings, then API. That one page has both values:
- Project URL: looks like
https://abcdefghij.supabase.co. This isVITE_SUPABASE_URL. - Publishable key (starts with
sb_publishable_) or the legacyanonkey (a long JWT starting witheyJ). This isVITE_SUPABASE_PUBLISHABLE_KEYorVITE_SUPABASE_ANON_KEY. Never put theservice_roleorsb_secret_key in frontend env vars; those bypass Row Level Security and anyone can read them from your shipped bundle.
If you do not know which Supabase project the app was built against, check Lovable: the project's Supabase integration panel shows the connected project. Copy URL and key from the same project in one sitting so they cannot mismatch.
Step 3: create the .env file for local dev
In the repo root (the folder with package.json), create a file named exactly .env:
VITE_SUPABASE_URL=https://abcdefghij.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_xxxxxxxxxxxx
Three Vite-specific rules people trip on:
- The
VITE_prefix is mandatory. Vite only exposes variables starting withVITE_to browser code. A variable named plainSUPABASE_URLis invisible to the app. - The names must match the code character for character. If the code reads
VITE_SUPABASE_ANON_KEY, a var namedVITE_SUPABASE_PUBLISHABLE_KEYdoes nothing. - Restart the dev server. Vite reads
.envat startup. Ifnpm run devwas already running when you created the file, stop it (Ctrl+C) and run it again, then hard-refresh the browser. This one detail explains most "I added the .env and it is still blank" cases.
Step 4: set the same variables on Vercel or Netlify
Your .env file stays on your machine; the deploy host never sees it. Set the variables in the host's dashboard:
- Vercel: open the project, then Settings, then Environment Variables. Add each variable name and value, apply to Production (and Preview if you use it).
- Netlify: Site configuration, then Environment variables, then Add a variable.
Paste raw values with no surrounding quotes and no trailing spaces or newlines. Then redeploy. Vite bakes env values into the JavaScript bundle at build time, so adding variables changes nothing until a fresh build runs. Trigger a new deploy from the host's UI or push any commit.
Step 5: make the repo survivable for the next person (and the next deploy)
Two small changes prevent this whole class of failure from coming back:
- Commit a
.env.examplelisting every variable name with placeholder values. It holds no secrets, so it belongs in git, and anyone cloning the repo (including future you, and deploy hosts, and diagnosis tools) can see exactly what the app needs. - Stop the import-time throw. In
src/integrations/supabase/client.ts, do not throw when the vars are missing. Export a flag instead and let the app render a readable setup message. This is exactly the fix we shipped on the campus app: instead of crashing before React mounted, the client module exports a config-error state and the app shows a setup screen telling you which variable is missing. A minimal version:
const url = import.meta.env.VITE_SUPABASE_URL;
const key = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
export const supabaseConfigError = !url || !key
? "Missing VITE_SUPABASE_URL or VITE_SUPABASE_PUBLISHABLE_KEY. Copy .env.example to .env and fill it in."
: null;
export const supabase = supabaseConfigError
? (null as never)
: createClient(url, key);
Then in your top-level component, if supabaseConfigError is set, render that message instead of the app. A blank screen becomes a one-line instruction.
If the env vars are set and it is still broken, check these
- Home page works but /dashboard 404s on refresh (deployed only). That is not env at all. It is the missing single-page-app rewrite on your host: every path must serve
index.html. On Netlify add a_redirectsfile with/* /index.html 200; on Vercel add avercel.jsonrewrite of all paths to/index.html. - App renders but every request 401s with "Invalid API key". The vars exist but the key is wrong, truncated, or from a different project. See our Supabase Invalid API key guide.
- Login bounces to the wrong URL. Supabase Auth still points at the Lovable preview domain. In Supabase go to Authentication, then URL Configuration, and add your localhost and deployed URLs.
- You remixed someone else's app and their database schema is missing. Env vars point the app at your fresh Supabase project, but that project has no tables. Check the repo's
supabase/migrationsfolder and apply the migrations to your project, or the app will render and then fail on every query.
Still stuck?
Run the instant diagnosis. Paste your public repo URL into the form and an automated clean-room check reports what is broken: install, build, missing env config, and render, with the exact blocker named, in minutes, free. This guide's failure class is the one it catches best; it is how we found the import-time crash in the campus app. Private repo or zip? Email works too.
Get an instant free diagnosisOr email me instead. Fixes with 24 hour turnaround start at $95. Prefer self-serve? The $5 instant diagnosis on Apify checks your repo privately, no public issue needed.