Short answer: if sign-in works in the Lovable preview but fails, loops, or sends people to localhost on your real domain, Supabase is almost always redirecting to a URL it was never told about. Fix the Site URL and Redirect URLs in Supabase, and (for Google sign-in) the callback URL in Google Cloud.
Symptoms
- Magic link or confirmation email opens
localhost:3000or the old preview link. - Google sign-in shows
Error 400: redirect_uri_mismatch. - You sign in, land back on the login page, and it repeats (a login loop).
- Password reset link says it is invalid or expired straight away.
Why it happens
Every sign-in has up to two hops:
- Provider to Supabase. Google (or GitHub etc.) sends the user back to your Supabase project's callback URL:
https://<project-ref>.supabase.co/auth/v1/callback. If that is not in your Google OAuth client, you getredirect_uri_mismatch. - Supabase to your app. Supabase then sends the user to your app. It only goes to the Site URL or an address on the Redirect URLs allow list. If your live domain is missing, Supabase falls back to the Site URL, which is often still localhost or the preview link.
Fix, step by step
- Supabase Dashboard > Authentication > URL Configuration.
- Set Site URL to your live domain, for example
https://yourapp.com. - Under Redirect URLs, add each address you use:
https://yourapp.com/**,https://www.yourapp.com/**, and your Lovable preview URL if you still test there. - Google sign-in only: Google Cloud Console > APIs & Services > Credentials > your OAuth client > Authorised redirect URIs. Add the exact callback URL shown on Supabase's Google provider page. It must match exactly.
- In your code, check any
redirectTo/emailRedirectTovalue. It should use the current site (window.location.origin), not a hard-coded localhost. - Test in a private window on your live domain: sign up, confirm email, sign out, sign in, reset password.
Still looping?
- A login loop after a successful sign-in can also be a page that checks the session before Supabase has finished reading it from the URL. Wait for
onAuthStateChangeorgetSession()before redirecting away from protected pages. - Old email links keep the old redirect. Send a fresh one after changing settings.