# Site URL and redirect URLs

> Set the Site URL and the Redirect URLs allow list for a SupaHost project, write safe wildcard patterns for local, preview and production apps, and handle mobile deep links.

Source: https://supahost.app/docs/auth/redirect-urls · Updated 2026-11-11

After a user clicks an email link or finishes an OAuth sign-in, Auth sends them back to your app. Two settings control where "back" may be:

- **Site URL**: the default destination, used when your code doesn't ask for a specific page, or asks for one that isn't allowed.
- **Redirect URLs**: the allow list of other destinations your code may request with `redirectTo` or `emailRedirectTo`.

The allow list exists because these redirects carry a session (tokens in the URL fragment, or a code that becomes tokens). If Auth redirected anywhere it was asked to, an attacker could craft a link that delivers a user's session to their own site.

## Where to set them

*Dashboard → your project → **Auth** tab → **Auth** card*:

- **Site URL**: one URL, such as `https://bookings.example.com`.
- **Redirect URLs**: one per line. Wildcards are allowed.
- Click **Save Auth settings**. Changes apply within a minute.

Only the instance owner can edit them. Every entry must start with `http://` or `https://`.

If you leave Site URL empty, Auth uses `http://localhost:3000`. That's fine on day one and a common cause of "my confirmation email links to localhost" in production, so set it before real users sign up.

## How Auth picks the destination

1. Your code passes a URL, for example:

```ts
await supabase.auth.signInWithOAuth({
  provider: 'github',
  options: { redirectTo: 'https://bookings.example.com/auth/callback?next=/calendar' },
})

await supabase.auth.signUp({
  email, password,
  options: { emailRedirectTo: 'https://bookings.example.com/auth/callback' },
})
```

2. Auth checks it against the Site URL and the Redirect URLs list.
3. If it's allowed, the user goes there. If it isn't, or you passed nothing, the user goes to the Site URL.

Falling back silently is why a typo in Redirect URLs shows up as "I always land on the home page" rather than as an error. See [Redirected to the wrong URL after sign-in](/kb/redirect-to-wrong-url).

## Wildcard patterns

Patterns use glob matching where `.` and `/` separate segments:

| Pattern | Matches | Doesn't match |
|---|---|---|
| `https://bookings.example.com/**` | Any path and query string on that host | `https://www.bookings.example.com/` |
| `https://*.example.com/**` | `https://staging.example.com/auth/callback` | `https://a.b.example.com/` (`*` stops at a dot) |
| `http://localhost:3000/**` | Any local path on port 3000 | `http://localhost:5173/` |
| `https://bookings.example.com/auth/callback` | Exactly that URL | The same URL with `?next=/calendar` |

- `*` matches any characters except separators.
- `**` matches anything, separators included.
- `?` matches a single character.

End entries with `/**` unless you mean one exact URL. Query strings such as `?next=` count as part of the URL, so an exact entry won't match once you add one.

## A typical setup

Site URL:

```
https://bookings.example.com
```

Redirect URLs:

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

The last line covers Vercel preview deployments for one team. Avoid the broad `https://*.vercel.app/**`: anyone can deploy something to a `vercel.app` subdomain, and a pattern that matches their deployment would let a crafted link deliver a user's session there. Keep wildcards as narrow as your hosting allows.

## Separate projects for separate environments

Each SupaHost project has its own Auth settings, so you can keep production strict and staging loose. A staging project (or a branch) might allow `https://*.staging.example.com/**` and `http://localhost:*/**`, while production allows only the real domain. Remember that a [branch](/docs/platform/branching) doesn't copy Auth settings from its parent; set them on the branch.

## Mobile apps and deep links

Native apps can add their own URL scheme to **Redirect URLs**, for example `com.example.bookings://login-callback` or `bookings://**`. Pass the same URL as `redirectTo` (or `emailRedirectTo`), and the app receives the session when the operating system opens it. The **Site URL** must still be an `http://` or `https://` address. Other options for native apps:

- **Use the email code instead of the link.** Every Auth email includes a one-time code. Verify it in the app with `verifyOtp`, and no redirect is needed. See [Magic links and email OTP](/docs/auth/magic-links-otp).
- **Use native sign-in for OAuth providers that offer it** (Apple, Google) with `signInWithIdToken`, which doesn't redirect at all. See [Apple](/docs/auth/apple) and [Google](/docs/auth/google).
- **Use https deep links**: iOS Universal Links or Android App Links on a domain you own, such as `https://bookings.example.com/app/callback`, added to Redirect URLs like any web URL. The operating system opens your app instead of the browser.

## The Site URL in emails

Auth emails can include `{{ .SiteURL }}`, for example to link to your home page from the message text. The confirmation button itself is added automatically and points at Auth's verify endpoint, which then redirects using the rules above. See [Auth emails and templates](/docs/auth/email-templates).

## Custom domains

Adding a [custom domain](/docs/platform/custom-domains) to the project changes the host Auth runs on (and the OAuth callback URL), not where users land afterwards. Site URL and Redirect URLs describe your app's addresses and stay as they are.

## Checklist

- Site URL is your production app, not localhost.
- Every `redirectTo` and `emailRedirectTo` your code uses is matched by an entry.
- Wildcards are no broader than you need.
- Staging and production projects each have their own list.
