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?

Prerequisites

You need a users table with an auth extension. The default teeny create template includes one. If you started from a blank template, see the Config Reference for how to add the auth extension.

1. Get Google Auth Client ID and Secret

  1. Go to the Google Auth Platform Clients Page
  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 (run teeny status after deploying to get this)
  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.

TIP

The CLI prints your exact callback URLs when you run teeny dev or teeny deploy --remote. You don't need to construct them manually.

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 the URL from teeny status.

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.

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
teeny deploy --remote
teeny secrets --remote --upload
bash
npx teeny deploy --remote
npx teeny secrets --remote --upload

Make sure the callback URLs in Google Cloud Console match your production URL. Check it with:

bash
teeny status
bash
npx teeny status