Supabase auth redirect not working after deploy

By BuildUnstuck · · checked against Supabase, Next.js and Vercel docs

Supabase usually isn't broken: the project's Site URL still says http://localhost:3000, or the URL you pass as redirectTo isn't in the Redirect URLs allow-list, so Supabase falls back to the Site URL. Fix those two settings first, then check the OAuth provider's callback, the email templates and the server-side callback route.

What this guide covers

It works on localhost. You deploy, and then one of these happens:

  • After signing in you land on http://localhost:3000 (or an old preview URL) instead of your live site.
  • Confirmation and password-reset emails link to localhost.
  • Google or GitHub sign-in works locally and fails on the live domain, sometimes with redirect_uri_mismatch.
  • You come back from the provider and end up signed out, on a blank page, or on an error page.

These all trace back to a short list of URL settings. Work through them in order; most people are done by step 3.

Step 1: Set the Site URL to your production URL

In the Supabase Dashboard, open Authentication → URL Configuration. The Site URL is the default redirect when your code doesn't pass a redirectTo, and Supabase's docs say to change it from http://localhost:3000 to your production URL because it's critical for email confirmations and password resets (Supabase: Redirect URLs).

The Dashboard also describes it as the URL used when a redirect URL is not specified or doesn't match one from the allow list. That's why a missing allow-list entry usually looks like "it sends me to localhost": you're being sent to the Site URL. Wildcards can't be used in the Site URL field.

Step 2: Add the exact URL you pass as redirectTo to the Redirect URLs list

The URL in redirectTo should match an entry in Redirect URLs (same page). A reply from the Supabase team describes the match as an exact string match: for https://mysite.com/auth/callback you need that URL in the list, and http://mysite.com/auth/callback or just https://mysite.com is not enough (supabase/supabase issue #22242). Check these common slips:

  • Scheme: http vs https.
  • Path: the entry must cover the path you redirect to, like /auth/callback, not only the domain.
  • Host: www.example.com and example.com are different hosts.
  • Slashes: a trailing slash, or a doubled slash from building the URL as window.location.href + '/auth-callback'. One user in that issue hit exactly this.

Wildcards exist (*, **, ?). Supabase's docs show them for local development and preview deployments on hosts like Vercel and Netlify, and recommend setting the exact redirect path for your production site rather than relying on **.

Typical safe setup: Site URL = your production URL. Redirect URLs = your exact production callback path(s), plus http://localhost:3000/** for local development and, if you use preview deployments, a narrow pattern for them (see the Vercel and Netlify sections of the Supabase doc for the pattern syntax).

Step 3: Stop hardcoding the URL in your code

AI-generated auth code often has redirectTo: 'http://localhost:3000' baked in, or builds the URL from whatever page you were on. Build it from an environment variable instead. This is the helper from Supabase's docs, trimmed:

const getURL = () => {
  let url =
    process.env.NEXT_PUBLIC_SITE_URL ?? // set this to your production URL in the production environment
    process.env.NEXT_PUBLIC_VERCEL_URL ?? // set automatically by Vercel
    'http://localhost:3000/'
  // include https:// when not localhost
  url = url.startsWith('http') ? url : `https://${url}`
  // include a trailing slash
  return url.endsWith('/') ? url : `${url}/`
}

Two gotchas that bite right after you add the variable:

  • In Next.js, NEXT_PUBLIC_* values are inlined into the JavaScript at build time, so the running app won't pick up a change until you rebuild (Next.js: environment variables).
  • On Vercel, changing an environment variable applies only to new deployments, so redeploy after you set it, and make sure it's enabled for the Production environment (Vercel: environment variables).

Vite apps do the same thing with VITE_* variables, which are replaced at build time (Vite: env variables and modes).

Step 4: Check the OAuth provider's callback (Google, GitHub, etc.)

With social login there are two separate allow-lists: the one in Supabase (Step 2) and the one in the provider's console. For Google, Supabase's guide says to add your app's URL under Authorized JavaScript origins, and your Supabase project's callback URL under Authorized redirect URIs. It points you to the Google provider page in the Supabase Dashboard to copy the callback URL from (Supabase: Login with Google). A redirect_uri_mismatch error from Google means the redirect URI Supabase sent isn't in that list, so compare them character by character.

The same guide notes that http://localhost:<port> should be removed from the provider's list when you go to production.

Step 5: Fix email confirmation and password-reset links

  • If you pass redirectTo (or emailRedirectTo) in code, you may need to use {{ .RedirectTo }} instead of {{ .SiteURL }} in your email templates (Supabase: Redirect URLs).
  • If the emails never arrive for real users, check your email setup. In September 2024 Supabase announced that, without a custom SMTP server, the default email provider only sends to addresses that belong to your project's organization (Supabase changelog). Set up custom SMTP before launch.
  • Test with a brand-new email address in a private window on the live domain. Your own address may already be a team member and hide the problem.

Step 6: If you use server-side auth (PKCE), check the callback route

With server-side auth, the provider sends the user back with a code, and your app must exchange it for a session. Supabase's guide says to set redirectTo to a callback route (for example /auth/callback), add that URL to your redirect allow-list, and call exchangeCodeForSession in that route. It also warns that signInWithOAuth stores a PKCE code verifier in a cookie, and if that cookie doesn't reach the browser the callback can't complete the exchange (Supabase: Login with Google, "Server-Side Auth" section; Supabase: Next.js server-side auth).

If your app sits behind a load balancer or proxy, Supabase's Next.js example reads x-forwarded-host to rebuild the public origin for the final redirect, rather than trusting the internal origin. If your users land on an internal or wrong hostname after login, compare your callback route with that example.

Step 7: Read the error Supabase sends back

When authentication fails, Supabase still redirects to your redirect URL, with the error details in the URL fragment. Look at the address bar after a failed login, or read them in code, for example new URLSearchParams(window.location.hash.slice(1)) and its error_code and error_description keys (Supabase: Redirect URLs, error handling). A readable error beats another round of "ask the AI to fix login".

Symptom to likely cause

What you seeCheck first
Redirected to localhost after loginSite URL (Step 1), and whether your redirectTo is in the allow-list (Step 2)
Email links point to localhostSite URL, and .SiteURL vs .RedirectTo in the template (Step 5)
redirect_uri_mismatch from GoogleAuthorized redirect URI in Google's console (Step 4)
Works on one URL, not anotherExact match: scheme, host, path, slashes (Step 2)
Signed out right after the callbackCallback route and PKCE cookie (Step 6)
Emails never arrive for new usersCustom SMTP (Step 5)

Quick answers

Why does Supabase redirect to localhost after login on my live site?

Usually your project's Site URL is still http://localhost:3000, or the redirectTo you pass isn't in the Redirect URLs allow-list, so Supabase falls back to the Site URL. Fix both in Authentication → URL Configuration, then retest in a private window.

Do I need to add my Vercel or Netlify preview URLs?

Only if you test login on preview deployments. Supabase documents wildcard patterns for that, and recommends exact paths for production. Keep preview patterns narrow.

Can I use a wildcard in the Site URL?

No. The Dashboard says wildcards cannot be used in the Site URL field. Wildcards are for the Redirect URLs list.

Sources

The vendor-specific claims above come from these docs, read on Oct 23, 2026. Docs change, so check the current wording before you rely on a specific setting.