Home / Fix guides
LovableBoltv0CursorSupabase

Supabase confirmation and magic-link emails redirect to localhost after deploy

Updated 2026-11-11

Email link opens http://localhost:3000/#access_token=… (or "This site can’t be reached")

What you see

A new user signs up on your live site, clicks the confirmation email, and lands on http://localhost:3000 with a long #access_token=… in the address bar. Or GitHub/Google login bounces back to localhost. Password reset links do the same.

Why it happens

Supabase Auth builds those links from your project’s Site URL whenever your code doesn’t pass a redirectTo. On a fresh project the Site URL is http://localhost:3000. Supabase’s docs single it out as the setting to change for production, because email confirmations and password resets depend on it.

If your code does pass redirectTo, that URL must also be on the project’s Redirect URLs allow list, or Supabase falls back to the Site URL.

Fix it

  1. In the Supabase dashboard, open Authentication → URL Configuration.
  2. Set Site URL to your real production URL, e.g. https://yourapp.com.
  3. Under Redirect URLs, add every URL you redirect to:
    • your production URL: https://yourapp.com/**
    • local development: http://localhost:3000/**
    • Vercel previews: https://*-<your-team-or-account-slug>.vercel.app/**
    • Netlify previews: https://**--<your-site>.netlify.app/**
  4. Pass redirectTo explicitly in code so previews and production both work:
const getURL = () => {
  let url =
    process?.env?.NEXT_PUBLIC_SITE_URL ??   // set this in production
    process?.env?.NEXT_PUBLIC_VERCEL_URL ?? // set automatically by Vercel
    'http://localhost:3000/';
  url = url.startsWith('http') ? url : `https://${url}`;
  return url.endsWith('/') ? url : `${url}/`;
};

await supabase.auth.signInWithOAuth({
  provider: 'github',
  options: { redirectTo: getURL() },
});

For a Vite app (Lovable, Bolt), use window.location.origin or an import.meta.env.VITE_SITE_URL variable in place of the NEXT_PUBLIC_ ones.

  1. Email templates: if you rely on redirectTo, Supabase notes you may need to replace {{ .SiteURL }} with {{ .RedirectTo }} in your confirmation and magic-link templates.

Gotchas

Check it worked

Sign up with a new email address on the live site. The confirmation link should open your production domain and leave you signed in.

Sources

Tools mentioned

Auth

Supabase Auth

The auth service built into every Supabase project: email/password, magic links, OAuth providers and anonymous sign-ins, tied directly to Row Level Security.

Free: 50,000 monthly active users on the Free plan
Hosting

Vercel

Git-connected hosting with a global CDN, serverless functions and preview deployments for every push. The default target for Next.js and v0 projects, and it also deploys Vite apps exported from Bolt or Lovable.

Free: Hobby plan: $0/month, 1 developer seat
Hosting

Netlify

Static and serverless hosting with deploy previews, functions, forms and a CDN. Popular for Vite/React SPAs exported from AI builders.

Free: Free plan: $0 forever with a 300-credit monthly limit