# Sign in with Google

> Add Google sign-in to a SupaHost project: create an OAuth client in Google Cloud, paste the Client ID and secret into the Auth tab, and call signInWithOAuth from your app.

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

Google sign-in uses a standard OAuth 2.0 web client from Google Cloud. You create the client, point it at your project's Auth callback URL, and paste its credentials into SupaHost. It takes about ten minutes, most of it in Google's console.

## What you need

- A Google account with access to the [Google Cloud console](https://console.cloud.google.com/apis/credentials).
- Your project's callback URL. Copy it from *Dashboard → your project → **Auth** tab → **OAuth providers*** ("Callback URL for every provider"). For project `app-one` on instance `acme` it's:

```
https://app-one.acme.supahost.space/auth/v1/callback
```

If the project has an active custom domain, the card shows that domain instead. Use exactly what the card shows.

## 1. Set up the consent screen

In the Google Cloud console, pick or create a project for your app, then open **Google Auth Platform** (shown as "OAuth consent screen" in some accounts).

1. Under **Branding**, enter the app name users will see, a support email, and your app's home page and privacy policy links.
2. Under **Audience**, choose **External** for a public app. While the app is in "Testing", only the test users you list can sign in. Publish it when you go live.
3. Under **Data access**, the default `openid`, `email` and `profile` scopes are all Auth needs. Adding sensitive scopes (Drive, Gmail and so on) triggers Google's verification review.

## 2. Create the OAuth client

1. Go to **Clients** (or **Credentials → Create credentials → OAuth client ID**).
2. Application type: **Web application**. Name it after the project, for example "Recipe box (production)".
3. **Authorized JavaScript origins**: add the origins your app runs on, such as `https://recipes.example.com` and `http://localhost:3000`.
4. **Authorized redirect URIs**: add the callback URL from SupaHost. This one must match exactly, including `https` and the `/auth/v1/callback` path.
5. Click **Create** and copy the **Client ID** and **Client secret**.

Use separate Google clients for separate SupaHost projects (for example production and a staging branch), because each project has its own callback URL.

## 3. Turn on Google in SupaHost

1. *Dashboard → your project → **Auth** tab → **OAuth providers***, click **Google**.
2. Switch on **Enabled**.
3. Paste the **Client ID** and **Client secret**. The secret is stored encrypted and never shown again.
4. Click **Save Google**.

Then, on the **Auth** card, add the pages Google sign-in should return to under **Redirect URLs** (for example `https://recipes.example.com/**` and `http://localhost:3000/**`) and click **Save Auth settings**. Changes apply within a minute.

## 4. Add the button

Browser app:

```ts
async function signInWithGoogle() {
  const { error } = await supabase.auth.signInWithOAuth({
    provider: 'google',
    options: { redirectTo: `${window.location.origin}/auth/callback` },
  })
  if (error) showError(error.message)
}
```

Server-rendered app (PKCE): start the flow on the server, redirect to `data.url`, and exchange the code in your callback route. See [Auth in Next.js](/docs/auth/nextjs) for a full example.

After sign-in, `user.user_metadata` contains Google's profile fields, such as `full_name`, `avatar_url` and `email`.

## Getting a Google refresh token

If your app calls Google APIs for the user (say, adding a cooking session to their calendar), ask Google for offline access and save the tokens at sign-in, because Auth doesn't keep them:

```ts
await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    redirectTo,
    scopes: 'https://www.googleapis.com/auth/calendar.events',
    queryParams: { access_type: 'offline', prompt: 'consent' },
  },
})
```

The session returned right after sign-in includes `provider_token` and `provider_refresh_token`. Store them server-side.

## Google One Tap and native apps

One Tap on the web and the native Google Sign-In SDKs on Android and iOS give you a Google **ID token** instead of a redirect. Pass it to Auth with `signInWithIdToken`:

```ts
const { data, error } = await supabase.auth.signInWithIdToken({
  provider: 'google',
  token: googleIdToken,
  nonce: rawNonce, // the unhashed nonce, if you gave Google a hashed one
})
```

Auth checks that the token was issued for one of your configured client IDs. One Tap on the web uses the same web client ID, so nothing else is needed. Native apps use their own Android or iOS client IDs. Upstream Supabase Auth accepts several client IDs in the Client ID field, separated by commas with the web client first, for example `1234-web.apps.googleusercontent.com,1234-ios.apps.googleusercontent.com`. SupaHost has no "skip nonce check" setting, so if the SDK sets a nonce, pass the matching raw nonce.

## Your domain on Google's screens

Google shows users which app they're signing in to, and the callback domain appears in some places. With the default callback, that's a `supahost.space` hostname. If you want your own domain there, or you need Google's brand verification (which asks you to prove you own the domains involved), add a [custom domain](/docs/platform/custom-domains) to the project first, then use the custom-domain callback URL in the Google client.

## Troubleshooting

| Problem | Fix |
|---|---|
| `Error 400: redirect_uri_mismatch` | The redirect URI in Google doesn't match the SupaHost callback exactly. Copy it again from the OAuth providers card |
| "Access blocked: app has not completed verification" | The app is in Testing and the user isn't a test user, or you requested sensitive scopes |
| You land on the Site URL, not your page | Add your `redirectTo` to Redirect URLs |
| Sign-in broke after adding a custom domain | Add the new callback URL to the Google client. See [OAuth after a custom domain](/kb/oauth-after-custom-domain) |

For more, see [Google sign-in fails for some users](/kb/google-auth-fails).
