Vibe Code Rescue

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:

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:

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:

  1. The VITE_ prefix is mandatory. Vite only exposes variables starting with VITE_ to browser code. A variable named plain SUPABASE_URL is invisible to the app.
  2. The names must match the code character for character. If the code reads VITE_SUPABASE_ANON_KEY, a var named VITE_SUPABASE_PUBLISHABLE_KEY does nothing.
  3. Restart the dev server. Vite reads .env at startup. If npm run dev was 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:

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:

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

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 diagnosis

Or 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.