Lovable login works in preview, breaks in production
Guide · October 14, 2026
You can sign in on the Lovable preview. You publish (or put a custom domain in front) and login loops, dumps you on localhost:3000, or comes back with no session. The React is the same. The host is not.
Supabase Auth only sends the browser to URLs it already trusts. Preview was on that list. Production was not.
Sources: Redirect URLs, redirectTo troubleshooting, Sign in with Google (the callback URL pattern is the same for other providers), and Lovable's Supabase integration (auth settings live in the Supabase dashboard on a connected project).
What it looks like
- Preview: Google / GitHub / magic link works. Production: spinner, then the login page again.
- After OAuth you land on
http://localhost:3000or the old*.lovable.apppreview host. - The address bar has
#error=redirect_uri_mismatch,error_description=Unsupported%20redirect, or similar fragments. - Google shows
Error 400: redirect_uri_mismatchnaming a URL you do not recognize. - Email confirm / reset links open the preview app, or they 404 on the live domain.
Open a private window on the live origin. Preview cookies will lie to you.
Three lists, not one
People paste the production URL into one box and call it done. There are three:
- Supabase Site URL (Authentication → URL Configuration). Default redirect when code does not pass
redirectTo. Magic links and password resets use it. Default on a new project ishttp://localhost:3000. - Supabase Redirect URLs (same page, allowlist). Every
redirectTomust match. If it does not, Auth ignores it and uses Site URL, which is how you "set production" and still bounce to localhost. Documented in the redirectTo FAQ. - OAuth provider Authorized redirect URI (Google Cloud, GitHub, etc.). This is not your app. It is Supabase's callback:
https://YOUR_PROJECT.supabase.co/auth/v1/callback, copied from Authentication → Providers. Publishing the Lovable app does not change this URL. Getting it wrong isredirect_uri_mismatchat the provider, which looks like a Lovable bug.
On a connected Supabase project, those first two live in the Supabase dashboard. Lovable's docs are blunt: social providers and auth URL settings are not configured from the project chat. (Lovable Cloud, the built-in backend, is the other setup. This guide is the connected-project case.)
The fix
1. Site URL = the live origin
Authentication → URL Configuration → Site URL:
https://myapp.com
Or https://your-app.lovable.app if that is the published host. Include https://. No path unless you really serve the app under one. Save.
Leave preview out of Site URL. Site URL is the default for emails. Preview can stay on the Redirect URLs list.
2. Redirect URLs include production, preview, and the callback path
Same page, Redirect URLs. Add the origins you actually use. Wildcards are documented; ** matches across /:
https://myapp.com/**
https://myapp.com/auth/callback
https://*.lovable.app/**
http://localhost:5173/**
http://localhost:3000/**
Use the path your client passes as redirectTo. If the code sends https://myapp.com/auth/callback, that exact URL (or a wildcard that covers it) must be on the list. A trailing-slash mismatch is enough to fall back to Site URL.
The docs recommend an exact production path, and ** for preview hosts. That split is the right one.
3. Provider callback = the supabase.co URL
Google Cloud Console (or GitHub → Developer settings → OAuth app):
- Authorized JavaScript origins:
https://myapp.com, plus the preview origin if you still test there. Localhost only while you still run locally. - Authorized redirect URIs: copy from Supabase → Authentication → Providers → Google (or GitHub). Production hosted Auth is:
https://YOUR_PROJECT.supabase.co/auth/v1/callback
Do not put https://myapp.com/auth/callback in Google's redirect URI list. Google returns to Supabase. Supabase then returns to your app using Site URL / redirectTo.
4. redirectTo in the app
Hardcoding the preview host is how production "randomly" returns to preview. Use the current origin, or a production env var:
const redirectTo = `${window.location.origin}/auth/callback`;
const { error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: { redirectTo },
});
Same idea for resetPasswordForEmail and signInWithOtp. Whatever string you pass must be on Redirect URLs. No redirectTo means Site URL, which is why setting Site URL to production also fixes magic links.
If you customized auth email templates, {{ .SiteURL }} always points at Site URL. Use {{ .RedirectTo }} when the link should follow the redirectTo you passed. That is in the same redirect-URLs guide.
Quick checklist
- Private window, live hostname, not the preview URL.
- Site URL is the production origin, not
localhostand not only the preview host. - Redirect URLs include that origin (and
/auth/callbackif you use it). Preview can stay as a wildcard. - Google/GitHub Authorized redirect URI is
https://YOUR_PROJECT.supabase.co/auth/v1/callback. redirectToin code iswindow.location.origin(plus path), not a pasted preview URL.- Read hash/query
error/error_descriptionon the landing page. Auth still redirects on failure; the error is in the fragment.
Questions
Why does Lovable login work in preview but fail after publish?
Preview and production are different origins. Auth only returns to allowlisted URLs. If Site URL and Redirect URLs still name the preview host or localhost, production sign-in is rejected or sent to the wrong place.
What is the difference between Site URL and Redirect URLs?
Site URL is the default when you omit redirectTo (emails, some OAuth fallbacks). Redirect URLs is the allowlist for every redirectTo. Production needs both. A redirectTo that is not on the list is ignored.
Where does the Google or GitHub callback URL go?
In the provider console, Authorized redirect URI is the Supabase callback https://YOUR_PROJECT.supabase.co/auth/v1/callback. Your app URL goes in Supabase Site URL / Redirect URLs, and as a JavaScript origin at the provider. Publishing does not change the supabase.co callback.
I set Site URL. Why do I still land on localhost?
redirectTo is missing from Redirect URLs, so Auth falls back, or the client still hardcodes localhost/preview. Add the exact production callback and pass window.location.origin.
Do I configure this in Lovable or in Supabase?
Connected project: Supabase Dashboard → Authentication → URL Configuration, plus the provider console. Lovable Cloud (built-in backend) is configured in Lovable. The two backends are not interchangeable in one click.
If the session exists and Save still no-ops, that is RLS, not redirects: saved but nothing saved. If production checkout 401s at the webhook, see Stripe webhook 401.
Login dead on the live domain? That is an auth fix. $149, you test the PR before you pay. No fix, no pay.
Get this fixed for $149