VibeFix › Guides
Lovable app broken after publishing? A step-by-step fix checklist
It works in the Lovable preview, then the published app shows a blank screen, loops back to the login page, or loads with no data. The cause is usually configuration outside your components, which is why re-prompting "fix it" often goes in circles. Work through these checks in order. Most take a few minutes each.
- Find the real error first
- Changes don't show up on the live site
- Blank white screen
- 404 when you refresh a page (self-hosted)
- Login loop or redirect to localhost
- Data is empty or saves silently fail
- Edge Functions, AI calls or payments fail
- Check for exposed keys before you share the link
- Stop the prompt loop
1. Find the real error first
Open your published URL in a private/incognito window (so old sessions and cached files don't hide the problem). Open DevTools (F12 or right-click → Inspect):
- Console: copy the first red error. Later errors are often side effects of the first one.
- Network: reload and look for red rows. A
401/403fromsupabase.copoints at auth or row-level security; a404on a JS file points at a stale or broken build; a500from a function points at its server-side code or secrets.
Paste that exact error (not "it's broken") into Lovable's Chat or Plan mode and ask it to explain the cause before changing code.
2. Changes don't show up on the live site
Publishing in Lovable deploys a snapshot. Edits you make afterwards are not live until you publish again (Publish → Update). If publishing is blocked, the current version has a build error: fix that in the editor first, then republish and hard-refresh the live page.
3. Blank white screen
A blank page almost always means a JavaScript error during startup. Common causes:
- Missing environment variables (when hosted outside Lovable). Lovable apps are Vite + React, and Vite only exposes variables prefixed with
VITE_, baked in at build time. If you exported the repo to Vercel, Netlify or similar, add the same variables there (for exampleVITE_SUPABASE_URLand the Supabase publishable/anon key, using the exact names your code reads), then redeploy: changing the variable alone doesn't update an existing build. - Code that assumes data exists. Errors like
Cannot read properties of undefinedon first load often come from renderinguser.nameoritems.mapbefore the data arrives. Guard with loading states. - A crash in one component takes the whole app down. Adding an error boundary turns the blank page into a readable message, which makes the next fix much faster.
4. 404 when you refresh a page (self-hosted)
If the homepage works but refreshing /dashboard or opening a shared deep link gives a 404 on your own host, the server is looking for a file that doesn't exist. Single-page apps need every route rewritten to index.html:
- Vercel (
vercel.json):{"rewrites":[{"source":"/(.*)","destination":"/index.html"}]} - Netlify (
public/_redirects):/* /index.html 200
5. Login loop or redirect to localhost
This is the most common "works in preview, broken live" bug. Auth providers only redirect back to URLs on an allowlist, and the default Site URL is often still the preview or localhost.
- Lovable Cloud (built-in backend): Lovable normally sets the Site URL when you publish and adds a custom domain once it's live, but a Site URL you set yourself is left alone. Check More → Cloud → Users → Auth settings → Advanced: Site URL should be your live address and Redirect URLs should include every domain you use.
- Your own Supabase project: nothing updates automatically. In Supabase → Authentication → URL Configuration, set the Site URL to your live domain, add it (for example
https://yourdomain.com/**) to Redirect URLs, and click Save. - Google sign-in with your own OAuth credentials: the redirect URI in Google Cloud Console must match exactly: scheme, domain, path and trailing slash. With your own Supabase project, that's your Supabase callback URL (
https://<project-ref>.supabase.co/auth/v1/callback); add your live domain to Authorized JavaScript origins too. - Login "succeeds" but the app sends you back to /login: the session may be fine while the profile query returns nothing because of row-level security (next step), so the app concludes you're logged out.
6. Data is empty or saves silently fail
With Supabase row-level security (RLS) enabled and no matching policy, reads return zero rows with no error, and writes are rejected. In preview you may not notice if you tested in a way that bypassed it.
- Open Supabase (or Lovable Cloud's database view) and check each table your app reads or writes: RLS should be on, with a policy for each action the app performs (SELECT, INSERT, UPDATE, DELETE).
- A typical "own rows" policy:
create policy "own rows" on public.profiles for select using (auth.uid() = id);Inserts need a separate policy withwith check (auth.uid() = user_id), and an insert followed by.select()also needs a SELECT policy. - supabase-js returns errors instead of throwing them. Log the
errorfrom every query; a silent failure is often an ignored error object. - Test with two real accounts: user B must not be able to see user A's rows. Don't fix "empty data" by turning RLS off; that makes every row public to anyone with your publishable key.
7. Edge Functions, AI calls or payments fail
- Secrets: server-side keys (OpenAI, Stripe secret key, etc.) must be stored as Edge Function secrets, not in frontend code. A function that works in one project and fails in another is usually missing a secret. Check the function's logs for the exact message.
- CORS: if the browser shows a CORS error calling your function, the function has to answer the
OPTIONSpreflight and include CORS headers on every response, including error responses. - Payments: Stripe checkout is meant to be tested on the published app, not inside the editor preview. Make sure webhook endpoints point at your live function URL and that test-mode and live-mode keys aren't mixed.
8. Check for exposed keys before you share the link
On the live site, open DevTools → Sources (or view the JS bundle) and search for sk_, service_role and secret. The Supabase publishable/anon key is designed to be public only when RLS is set up correctly; a service_role key or any sk_ secret in the browser must be moved server-side and rotated immediately, since anyone could already have copied it.
9. Stop the prompt loop
If three prompts in a row haven't fixed it, more of the same usually makes it worse. Revert to the last working version in Version history, switch to Plan mode, and give Lovable the exact error from step 1 plus what you expected to happen. Ask for a diagnosis before any code changes.
Still stuck? We'll fix it at a flat price.
VibeFix fixes broken Lovable, Bolt, Cursor, Replit and v0 apps. Request a free check first, and we'll tell you what's wrong and which plan fits before you pay. If we can't fix it, you get a full refund.
Already know you need help? Quick Fix, $49 (one bug, 24h) · Standard Rescue, $129 · Deploy-Ready, from $199