The callback URL still points at the dev domain
In development your app runs on a replit.dev address. A deployment gets a replit.app address or your custom domain. Google, GitHub and other OAuth providers only redirect to URLs you have registered, so a login that worked in the editor fails with a redirect mismatch once deployed.
Add the deployed callback URL (and your custom domain, if you use one) in the provider's console. Make sure the app builds the callback from the real public host. Replit sets REPLIT_DEV_DOMAIN to the dev address only, so a callback built from it will be wrong once published.
Secrets are missing in the published app
Replit keeps editor secrets and published app secrets in separate places, and changing a secret in the editor does not change the live app. Open Publishing, then Adjust settings, and check Production app secrets for everything the app reads (session secret, OAuth client secret, database URL). Then publish again so the new values load.
Check that DATABASE_URL in production points at your production database, not the development one. Users who signed up in the preview may simply not exist there.
Not sure which of these it is? We'll tell you in 24 hours, free.
Get a free health checkLogin loops in the preview pane but works in a new tab
The workspace preview shows your app inside a frame on another site. Browsers often refuse to send cookies set with SameSite=Lax or Strict inside that frame, so the session never sticks. Test sign-in by opening the app in its own tab. If the app must work inside a frame, the session cookie needs SameSite=None and Secure.
Secure cookies never get set behind the proxy
Replit serves your app through a proxy that terminates HTTPS. An Express app with secure session cookies has to trust that proxy, or it thinks the request is plain HTTP and skips the cookie.
// Express behind a proxy
app.set("trust proxy", 1);
app.use(session({
secret: process.env.SESSION_SECRET,
cookie: { secure: true, sameSite: "lax" },
resave: false,
saveUninitialized: false,
}));
Questions people ask
Why does Google say redirect_uri_mismatch on my deployed Replit app?
The redirect URI your app sends doesn't exactly match one registered in Google Cloud Console. Add the deployed URL's callback path there, including the protocol and any trailing path, and save.
Do I need to publish again after changing a secret on Replit?
Yes. Published app secrets are separate from editor secrets, and new values apply when a new deployment starts. Update them under Publishing, then publish again.