Skip to content
Guides
Build guide

Login that works after you publish: the live-site checklist for a vibe-coded app

Sign-in works in the preview and loops, lands on localhost or hangs on the live site. Six checks, in the order a stranger hits them, with the exact error strings and the setting behind each one.

Dharmendra Jagodana15 min read

In short

Login that works in the preview and fails on the published site comes down to an address: the sign-in provider only returns to URLs it was told about, and the live one was never added. Six checks in order: the redirect address, the Google client, the confirmation email, the session, sign-out, a second browser.

A Replit review from 17 October 2026 reads, in full: "Users can't log in." A paid-fix vendor advertises on Mastodon with the exact symptom: "lovable login works in preview, then loops or dumps you on localhost after publish?" And on dev.to, the largest troubleshooting cluster we found for any builder, ten posts in thirty days, is Lovable sign-in that works for the builder and fails for everyone else.

It is nearly always the same thing. Sign-in happens on a page somebody else hosts (Supabase, Lovable Cloud, Bolt Cloud, Google, BuildBase's hosted page), and that page only sends people back to addresses it has been told about. The preview address was told about. The published one, and the custom domain you added on Friday, were not. Nothing in the app is broken, which is why no amount of prompting fixes it, and why a loop of fixes is how the credits go.

This is a checklist, not a tutorial: six checks in the order a stranger hits them, each with the symptom, the error string if there is one, the setting behind it, and how to prove it is fixed. Run every one on the published site, in a private window, as a second person, never as yourself in the editor's preview. The settings and limits quoted were read from each vendor's own docs on 27 October 2026.

Before you start

A published app with a sign-in of any kind (the builder's built-in, your own Supabase project, or BuildBase), a second email address you control, and a second browser or a private window. For the Google check, access to the Google Cloud Console project that holds the OAuth client.

First, find out who does your sign-in

Before any check, name the thing that signs people in, because every setting below lives in a different place depending on the answer. Most builders have given you one of four:

Who signs people inHow to tellWhere the allow list lives
The builder's built-in backend (Lovable Cloud, Bolt Cloud, Replit Auth)The Users list is inside the builder, and you never created a Supabase or BuildBase account for this appThe builder's own auth settings; Lovable and Bolt manage most of it when you publish
Your own Supabase projectThere is a Supabase dashboard for this app and the code calls supabase.authSupabase, Authentication, URL Configuration: the Site URL and the Redirect URLs
BuildBase's hosted pageThe code has a SaaSOSProvider, three /api/auth/* routes and a bb-session cookieThe auth client in the BuildBase console, under User Management, Authentication
Something the agent wrote itselfA users table, a password hash, a jsonwebtoken or iron-session dependencyNowhere; the redirect is whatever the code does, and the code is the setting

The fourth row is the one to worry about. There is no allow list because the agent wrote its own sign-in, and the checks below still apply, but the "setting" is a line of code the agent chose. What a coding agent builds when nobody tells it otherwise is what that line usually looks like.

1. The redirect address: where sign-in sends people back

Symptom: sign-in works in the preview; on the live site it loops back to the sign-in page, lands on localhost:3000, or shows "redirect URL not allowed". Cause: the live address is not on the provider's allow list, so the provider falls back to its default, which is the preview or localhost.

A published app has more addresses than it looks. Lovable gives you a preview address, a published something.lovable.app address, and your custom domain if you added one; v0 and Vercel give you a preview address per deployment and a production domain; Bolt gives you a Netlify address and your domain. Each is a different string to the provider, and an allow list that holds one of them holds one of them. Register the published address and the custom domain as a matter of course, and the preview only if you test sign-in there.

The settings, by provider:

Supabase (your own project, or the one a builder created for you). The Site URL is the default redirect when no redirectTo is given, and the docs tell you to change it "from http://localhost:3000 to your production URL". Redirect URLs live on the URL Configuration page; the redirectTo your code passes must match that list. Wildcards exist (* matches within one path segment, ** across them), and the docs keep them for local and preview work: "we recommend setting the exact redirect URL path for your site URL in production".

Lovable Cloud. The built-in sign-in allows up to 50 redirect addresses per app. If the app uses your own Supabase project instead, Lovable's sign-in docs say it does not update that project's Site URL or redirect URLs for you; you add the published address and the custom domain in the Supabase dashboard yourself.

Bolt Cloud. Bolt's auth settings carry a Site URL ("the primary live URL of your app") and a URI allow list; new projects default to localhost:3000, which the docs say "does not work for live applications". Bolt usually updates these when you publish, and the docs add that you may need to edit them by hand, "especially with multiple domains".

BuildBase. Each auth client has a list of redirect URLs, and the hosted sign-in page returns only to one of them, path included. A wildcard can stand in for one leftmost subdomain on a domain you own (https://*.app.example.com/sign-in), and never on a public suffix, so *.lovable.app and *.vercel.app are refused. Register the published address, the custom domain, and localhost for local work, each once. Auth clients, redirect URLs and environments is the pattern for keeping preview, staging and production apart without sharing a client.

How to prove it: open the published site in a private window, start sign-in, and read the address bar when it fails. If it says localhost, the Site URL is the default. If it says "not allowed" or "mismatch", the address differs from the registered one by a trailing slash, www, http versus https, or the path. Fix the one character, and try again from a fresh private window, because the old one may have cached the failure.

The four ways an address differs, because every one of them has cost someone an afternoon: https://app.example.com/sign-in is not https://app.example.com/sign-in/ (the slash), not https://www.app.example.com/sign-in (the www), not http://app.example.com/sign-in (the scheme), and not https://app.example.com/ (the path). Allow lists compare strings, not intentions.

If you want the agent to do the registering, give it the strings rather than the job, because an agent asked to "fix login on the live site" will change code, and the code was never wrong:

Do not change any sign-in code. In the sign-in provider's settings, set the Site URL to https://<published address> and add these redirect URLs exactly, with no wildcard: https://<published address>/sign-in, https://<custom domain>/sign-in, http://localhost:3000/sign-in. Then tell me which settings page you changed and what it now contains.

Correcting potential issues. If the agent answers by editing the sign-in code anyway, paste: "Revert that change. The problem is the provider's allow list, not the code; show me the current Site URL and redirect list before changing anything else." On a builder that manages the list for you (Lovable Cloud, Bolt Cloud), publishing again after adding a custom domain is often the whole fix, because the builder updates the list on publish; Bolt's docs say exactly that, with the caveat about multiple domains.

2. The Google client: redirect_uri_mismatch

Symptom: the Google button opens Google's page, which shows "Error 400: redirect_uri_mismatch", or returns to the app with nothing signed in. Cause: the address Google was asked to return to is not one of the authorized redirect URIs on your OAuth client, exactly.

This one has a second allow list, and it is Google's, not your provider's. Whoever handles the sign-in (Supabase, Bolt Cloud, BuildBase) has one callback address that Google must know; Bolt's docs, for example, show the origin and redirect URIs to paste into Google Cloud Console when you turn Google on. That address does not change when you publish, which is why this check passes for most people. It fails when the client was created for a different provider, when a second provider was added later, or when someone pasted the app's address instead of the provider's callback.

The Figma Make community thread that opened on 22 July 2025, "Google signup works but no access to app", stayed open into September with no root cause given; the symptom in it is this check and the one before it together: Google succeeded, then the provider returned to an address the app did not expect.

How to prove it: read the redirect_uri in Google's error page, copy it character for character into the OAuth client's authorized redirect URIs, save, wait a few minutes, retry from a private window. If your sign-in is BuildBase, social login in Next.js shows the one callback address to register and the two values to paste back.

3. The confirmation email that only you receive

Symptom: you signed up fine; a stranger signs up and the confirmation email never arrives, or arrives an hour later, or lands in spam. Cause: the sender is a development sender with limits you never hit, because you were inside them.

Supabase's docs on custom SMTP say it plainly about the built-in sender: "Supabase Auth will refuse to deliver messages to addresses that are not part of the project's team", the limit is "2 messages per hour", and the server "is not meant for production use". You are on the team. Your customers are not. The dev.to writer who put it best: "Then a real person signs up, never gets the confirmation email, and you never hear from them again."

The fix on Supabase is a custom SMTP sender (Resend, SES, Postmark, SendGrid and others are named in the docs) set in the project's auth settings, after which mail goes to everyone, with a limit of 30 an hour until you raise it on the rate-limits page. On BuildBase, sign-in emails go out through your organization's sending domain (Google, Mailgun, Amazon SES or your own SMTP), which you set once for every email the platform sends, and the guide on email landing in spam covers the domain records that keep it out of the junk folder.

How to prove it: sign up with an address at a provider you do not use for work (a Gmail account if you build on Outlook, or the reverse), and time the email. Then open it on a phone and look at the sender name and address. "[email protected]" is the development sender; your own domain is the fix.

4. The session after a reload, and after a week

Symptom: sign-in works; reloading the page signs you out, or everything is fine until a week later when every user is signed out at once. Cause: the session is held in the wrong place, or on the wrong host.

The right place is a cookie the browser cannot read, set by your server after the sign-in code is exchanged, with a lifetime you chose. On BuildBase that cookie is 30 days by default, which is the default session length, and the Vite, Next.js and Lovable guides all set it the same way. A session kept in localStorage by the browser survives reloads but can be read by any script on the page, which is the thing the 2025 Lovable exposure and the 2026 Moltbook leak had in common: a key the browser held.

The wrong host is subtler. A cookie set on app.example.com is not sent to example.com, and a cookie set on the published *.lovable.app address does not follow you to the custom domain. If sign-in works on one address and not the other, that is the cookie, and a session cookie not shared across subdomains is the two-line fix.

How to prove it: sign in, close the browser entirely, open the published site again. Still signed in. Then open the same site on the custom domain in the same browser. Still signed in, or you have the subdomain problem. And if your app uses Next.js middleware to guard pages, the symptom "the page reloads forever after sign-in" has its own guide: middleware redirect loop after login.

5. Sign-out that actually signs out

Symptom: a user signs out, presses back, and is still inside. Or signs out on a laptop and stays signed in on a phone. Cause: sign-out cleared a value in the browser and told the server nothing.

A sign-out has to end the session where it lives, on the server, so that the cookie, the phone and the tab that was left open all stop working at once. On BuildBase, onSignOut calls your sign-out route, which clears the cookie, and the SDK revokes the session on the platform, so a device list shows it gone and the other devices lose it too. A generated sign-out usually does only the first half.

How to prove it: sign in on two browsers as the same person. Sign out on one. Reload the other. If it is still signed in, the server was never told. The device list on the account screen is the honest check: a session that is signed out should not be listed.

The same list is the answer to the first support email every app gets, "I think someone else is logged into my account". Every BuildBase user has a list of their devices and can sign out one or all of them, and so can you, as the owner, from the console; a generated app has neither, because nobody asked, and the only way to end a stolen session is to change the password and hope. If your sign-in is the builder's built-in, check whether the Users view offers the same; as of 27 October 2026, Lovable's shows sign-up and last sign-in times and the methods used, and Replit's Users tab lists people and last sign-in, and neither documents a way to end a session from there.

6. The second person, and the second browser

Symptom: none yet, because nobody has tried. This is the check that finds the five above before a customer does.

Every check on this list fails for a stranger first and for you last, because your browser carries the preview's cookies, your email is on the project's team, and your Google account already consented. So the last check is the first one to run: a private window, a second email address, a phone on mobile data rather than your Wi-Fi, and the published address typed by hand rather than clicked from the editor.

Walk the whole path: sign up, confirm, sign out, sign in, close the browser, reopen, forgot password. Then do it once more on the custom domain. Ten minutes, and it is the same ten minutes a stranger will spend before deciding whether your app is real.

What prompting it instead costs

The reason this is a checklist and not a prompt: the fix is a setting, and an agent asked to fix it will change code. Lovable's own pricing page gives 1.20 credits as the example cost of adding authentication in build mode (read 27 October 2026), and the complaint that dominates every builder's reviews is the loop: "repeated 'fixes' that did not fix the problem", as one 1-star Lovable review from 12 October 2026 puts it, and "You will then spend DAYS and credits telling it to do the same thing 15 times", from another in September. Fifteen attempts at 1.20 credits is a fifth of a Pro plan's monthly 100, spent on code that was never wrong. The six checks above cost nothing but ten minutes, and the one prompt worth sending is the one in check 1 that names the addresses and forbids code changes.

Key takeaway

Sign-in that works in preview and fails live is an address problem, not a code problem. Find the allow list, add the exact live address, test as a stranger from a private window. Prompting the agent to "fix login" will spend credits on code that was never wrong.

Where the built-in sign-in is the better pick

If your app has one user per account and the built-in sign-in works for strangers after the six checks above, keep it. Lovable Cloud, Bolt Cloud and Replit Auth manage their own redirect addresses when you publish, and Lovable's built-in sign-in adds SAML SSO and OIDC of its own, where BuildBase's enterprise SSO runs through your own WorkOS account on the Enterprise plan. An external sign-in adds a client to register and an address to keep in step, and for a single-user app that is work for nothing.

Choose a hosted sign-in on your own domain when you want one address to register per environment instead of one per builder preview, methods that are switches rather than code (passkeys, magic links, Google, GitHub, Microsoft, Apple and the rest), a device list and a sign-out that ends the session everywhere, and the teams and plans layer on top. Should you run auth on your own domain is the decision in full, and the launch checklist is the other nineteen things to check before strangers arrive.

What breaks, and how you can tell

Loops to the sign-in page on the live site. Check 1. The live address is not on the allow list, or differs by one character.

Lands on localhost:3000 after sign-in. Check 1. The Site URL is still the default. Supabase's and Bolt's docs both name that default.

Error 400: redirect_uri_mismatch. Check 2. Google's authorized redirect URIs do not include the provider's callback address exactly.

Confirmation email arrives for you and nobody else. Check 3. The development sender delivers only to the project's team, at two an hour.

Signed out on every reload. Check 4. The session route is not deployed, or the cookie is set on another host.

Signed out, pressed back, still inside. Check 5. Sign-out never reached the server.

"Users can't log in", and you cannot reproduce it. Check 6. You are testing as yourself. Private window, second email, phone on mobile data.

Install

If the fix for your app is a hosted sign-in page with one address to register, the SDK and the CLI write the sign-in routes for you:

npm i @buildbase/sdk
npx buildbase init --org-id <your 24-character org id>
vibe-coding
auth
troubleshooting
lovable
supabase

Frequently Asked Questions

Why does login work in preview but not on my published site?

Because the preview address was registered with your sign-in provider and the published one was not. Supabase, Lovable Cloud, Bolt Cloud and BuildBase all return only to addresses on an allow list, and a new Supabase project ships with localhost:3000 as its site URL. Add the live address, with the exact path, and test from a private window.

What does redirect_uri_mismatch mean?

Google refused the sign-in because the address your app asked it to return to is not one of the authorized redirect URIs on your Google client, character for character. It is not a bug in your code. Add the live address to the client in Google Cloud Console, including the exact path and https, and wait a few minutes for it to apply.

Why do strangers never get the confirmation email when I did?

The default sender behind many AI-built apps is a development sender. Supabase's docs say its built-in sender only delivers to addresses on your project's team, at two messages an hour, and is not meant for production. You got the email because you are on the team. Connect a real sender and a real domain before the second user.

Is a wildcard redirect URL safe?

Supabase's docs recommend the exact redirect URL in production and keep wildcards for local and preview addresses. BuildBase allows a wildcard for one leftmost subdomain on a domain you own and refuses it on a public suffix such as vercel.app or lovable.app, so each preview address you actually use has to be registered on its own.

Ship it

Create a project and run this guide against your own workspace.

Free plan7-day free trial on paid plansNo credit card required