# Redirected to the wrong URL after sign-in (redirectTo)

> After OAuth or an email link, users land on localhost:3000 or your Site URL instead of the redirectTo page. How the Redirect URLs allow list and wildcards work on SupaHost.

Source: https://supahost.app/kb/redirect-to-wrong-url · Updated 2026-11-11

## What you see

You pass a `redirectTo` (OAuth, password reset) or `emailRedirectTo` (sign-up, magic link), but after signing in the user ends up somewhere else:

- `http://localhost:3000` in production
- the home page of your Site URL instead of `/auth/callback`
- production when you were testing on a preview deployment

## Why it happens

Auth only sends users to URLs you've allowed. When the URL you pass matches neither the **Site URL** nor an entry in **Redirect URLs**, Auth ignores it and uses the Site URL. No error is shown. On SupaHost, if the Site URL was never set, it is `http://localhost:3000`.

## How to fix it

1. **Set the Site URL.** Dashboard → your project → **Auth** tab → **Auth** card → **Site URL**. Use your production address, e.g. `https://bookings.example.com`.

2. **Add every redirect target** to **Redirect URLs**, one per line:

   ```
   http://localhost:3000/**
   https://bookings.example.com/**
   https://*-bookings-team.vercel.app/**
   ```

   Click **Save Auth settings**. Changes apply within about a minute.

3. **Use wildcards correctly.**
   - `*` matches characters within one part of the URL. It stops at `.` and `/`, so `https://*.example.com` matches `https://staging.example.com` but not `https://a.b.example.com`.
   - `**` matches anything, including `/`. Add `/**` to allow every path on a host.
   - Protocol and port must match exactly: `http://localhost:3000` doesn't cover `http://localhost:5173` or `https://localhost:3000`.

4. **Pass a full, absolute URL** built from where the app is actually running:

   ```ts
   await supabase.auth.signInWithOAuth({
     provider: "github",
     options: { redirectTo: `${window.location.origin}/auth/callback` },
   });

   await supabase.auth.signUp({
     email,
     password,
     options: { emailRedirectTo: `${window.location.origin}/welcome` },
   });
   ```

   On the server there's no `window`; build the origin from the request or from an environment variable such as `NEXT_PUBLIC_SITE_URL`.

5. **Check the URL Auth received.** For OAuth, look at the `redirect_to` parameter on the `/auth/v1/authorize` request in your browser's network tab. For email links, hover over the button in the email; the link carries `redirect_to=` as well. If it's missing or different, the problem is in your code, not the allow list.

6. **Mobile apps.** The Redirect URLs field only accepts `http://` and `https://` URLs. Use an https app link or universal link, or let users enter the one-time code from the email instead of following a link.

## On SupaHost

- Email links point at your project's Auth (`https://app-one.acme.supahost.space/auth/v1/verify`, or your custom domain), which then redirects to the allowed URL.
- The provider callback URL (`https://app-one.acme.supahost.space/auth/v1/callback`) is a different thing: it goes in the OAuth provider's console, not in Redirect URLs.
- Only the instance owner can change these settings.

## Related

- [Site URL and redirect URLs](/docs/auth/redirect-urls)
- [OAuth sign-in not redirecting on the server](/kb/oauth-server-side-redirect)
- [OAuth broke after adding a custom domain](/kb/oauth-after-custom-domain)
- [Deploying your app on Vercel](/docs/integrations/vercel)
