---
title: "Google Sign In (Custom Frontend)"
description: "Add a “Continue with Google” button with the OAuth redirect flow: Google Cloud credentials, secrets, authProviders config and the auth cookie."
url: https://teenybase.com/docs/guides/google-oauth-custom
last_updated: 2026-10-26
---

> Documentation index: https://teenybase.com/llms.txt lists every teenybase docs page with a link to its Markdown version. All docs in one file: https://teenybase.com/llms-full.txt

# Google Sign In (Custom Frontend)

Add a "Continue with Google" button to your frontend using the OAuth redirect flow. After login, the browser redirects back to your app with an auth cookie set.

> **Using a coding agent?** Paste this prompt:
>
> Add Google OAuth redirect flow to my teenybase app with a custom frontend..

## Prerequisites

You need a `users` table with an `auth` extension. The default `npx teenybase create` template includes one. If you started from a blank template, see the [Config Reference](https://teenybase.com/docs/reference/config-reference#auth-extension-tableauthextensiondata) for how to add the auth extension.

## 1. Get Google Auth Client ID and Secret

1. Go to the [Google Auth Platform Clients Page](https://console.developers.google.com/auth/clients)
2. Select your project. Create one if you don't have one.
3. Click **Create client**
4. Application type: **Web application**
5. Add authorized JavaScript origins:
   - `http://localhost:8787` (local dev)
   - Your production URL (the URL `npx teenybase deploy --remote` prints, also saved as `apiRoute` in `infra.jsonc`)
6. Add authorized redirect URIs:
   - `http://localhost:8787/api/v1/table/users/auth/oauth/google/callback`
   - `https://{your-production-url}/api/v1/table/users/auth/oauth/google/callback`
7. Copy the **Client ID** and **Client Secret**

For the full Google setup walkthrough, see the [official guide](https://support.google.com/cloud/answer/15549257?hl=en).

> **Tip**
>
> The callback URL is your base URL + `/api/v1/table/users/auth/oauth/google/callback`. `npx teenybase dev` runs at `http://localhost:8787`; `npx teenybase deploy --remote` prints the production base URL and saves it as `apiRoute` in `infra.jsonc`.

## 2. Add secrets

In `.dev.vars`, add:

```env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
```

## 3. Add config

In `teenybase.ts`:

```ts
export default {
  // ...existing config...

  authProviders: [
    {
      name: 'google',
      clientId: '$GOOGLE_CLIENT_ID',
      clientSecret: '$GOOGLE_CLIENT_SECRET',
      redirectUrl: '/dashboard',  // where to send user after login
    },
  ],

  // authCookie is required for the redirect flow.
  // it sets a cookie after login so the browser stays authenticated.
  authCookie: { name: 'teeny_auth' },

} satisfies DatabaseSettings
```

## 4. Start the OAuth flow

Link your "Continue with Google" button to the OAuth endpoint:

```
http://localhost:8787/api/v1/table/users/auth/oauth/google
```

In production, replace `http://localhost:8787` with your production URL (`apiRoute` in `infra.jsonc`).

You can override the post-login destination per request:

```
http://localhost:8787/api/v1/table/users/auth/oauth/google?redirect=/settings
```

Teenybase redirects to Google, handles the callback, creates or finds the user, sets the auth cookie, and 302-redirects to your `redirectUrl`.

Redirect URLs are validated against your `appUrl` hostname. Relative paths (like `/dashboard`) are resolved against `appUrl`. Add `allowedRedirectUrls` in your config if you need to redirect to a different domain.

## 5. Use the auth cookie in your frontend

The redirect flow delivers auth via a cookie. Your frontend sends it automatically with `credentials: 'include'`:

```js
const API = 'http://localhost:8787/api/v1'

const res = await fetch(`${API}/table/posts/select`, {
  credentials: 'include',
})
const posts = await res.json()
```

### Example: login button

```html
<a href="http://localhost:8787/api/v1/table/users/auth/oauth/google">
  Continue with Google
</a>
```

### Example: logout

```js
await fetch(`${API}/table/users/auth/logout`, {
  method: 'POST',
  credentials: 'include',
})
```

### Example: get current user

```js
const res = await fetch(`${API}/table/users/select?limit=1`, {
  credentials: 'include',
})
const [user] = await res.json()
```

## 6. Deploy to production

Add the same secrets to `.prod.vars`:

```env
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
```

Update `appUrl` in `teenybase.ts` to your production frontend URL.

```bash
npx teenybase deploy --remote --yes
npx teenybase secrets --remote --upload
```

Make sure the callback URLs in Google Cloud Console match your production URL (`apiRoute` in `infra.jsonc`).
