Documentation

OAuth Setup

Step-by-step Google and GitHub OAuth setup for Motoko Base — create provider apps, configure callback URLs, and fill in .env.

Open inChatGPT (opens in a new tab)Claude (opens in a new tab)Cursor (opens in a new tab)Step-by-step Google and GitHub OAuth setup for Motoko Base — create provider apps, configure callback URLs, and fill in .env.

Google and GitHub sign-in are optional. Leave the OAuth env vars unset and the app boots normally — social buttons on /sign-in and /sign-up stay disabled.

Once configured, Better Auth handles the OAuth flow and stores linked accounts in the account table. Callback URLs must exactly match your BETTER_AUTH_URL.

Before you start

Make sure these auth env vars are already set:

# .env or .env.local
DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=your-generated-secret
BETTER_AUTH_URL=http://localhost:3000
NEXT_PUBLIC_APP_URL=http://localhost:3000

For local development, use http://localhost:3000 for both URL variables. In production, set them to your public HTTPS origin (e.g. https://app.example.com).

Generate BETTER_AUTH_SECRET if you have not already:

openssl rand -base64 32

Restart the dev server after changing any env var:

pnpm dev

Google OAuth

Step 1 — Create a Google Cloud project

  1. Open Google Cloud Console
  2. Create a new project (or select an existing one)
  3. Go to APIs & Services → OAuth consent screen
  4. Choose External (or Internal for Workspace-only apps)
  5. Fill in the app name, support email, and developer contact
  6. Add scopes: email, profile, and openid (defaults are usually enough)
  7. Add test users if the app is in Testing mode

Step 2 — Create OAuth credentials

  1. Go to APIs & Services → Credentials
  2. Click Create Credentials → OAuth client ID
  3. Application type: Web application
  4. Name it (e.g. Motoko Base local)

Step 3 — Set the redirect URI

Under Authorized redirect URIs, add:

{BETTER_AUTH_URL}/api/auth/callback/google

Examples:

EnvironmentRedirect URI
Localhttp://localhost:3000/api/auth/callback/google
Productionhttps://app.example.com/api/auth/callback/google

The path must be exactly /api/auth/callback/google — Better Auth registers this route automatically.

Optionally add Authorized JavaScript origins for local dev:

http://localhost:3000

Step 4 — Copy credentials to .env

After creating the client, Google shows a Client ID and Client secret. Add them to .env:

GOOGLE_CLIENT_ID=123456789-abcdef.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxx

Both values are server-only — never put them on NEXT_PUBLIC_*.

Step 5 — Verify locally

  1. Restart the dev server: pnpm dev
  2. Open http://localhost:3000/sign-in
  3. The Sign in with Google button should be enabled (not greyed out)
  4. Click it — you should be redirected to Google, then back to /dashboard

If the button stays disabled, check that both GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set and non-empty.

Google troubleshooting

ProblemFix
redirect_uri_mismatchRedirect URI in Google Console must match {BETTER_AUTH_URL}/api/auth/callback/google exactly (scheme, host, port, path)
Button disabledBoth GOOGLE_* vars must be set; restart dev server
access_denied in Testing modeAdd your Google account as a test user on the consent screen
Works locally, fails in productionAdd production redirect URI and set BETTER_AUTH_URL to your live domain

GitHub OAuth

Step 1 — Create a GitHub OAuth App

  1. Open GitHub Developer Settings → OAuth Apps
  2. Click New OAuth App
  3. Fill in:
    • Application name — e.g. Motoko Base
    • Homepage URL — your app URL (local: http://localhost:3000)
    • Authorization callback URL — see Step 2

Step 2 — Set the callback URL

The Authorization callback URL must be:

{BETTER_AUTH_URL}/api/auth/callback/github

Examples:

EnvironmentCallback URL
Localhttp://localhost:3000/api/auth/callback/github
Productionhttps://app.example.com/api/auth/callback/github

Click Register application.

Step 3 — Generate a client secret

  1. On the OAuth app page, click Generate a new client secret
  2. Copy the Client ID and Client secret immediately — the secret is shown only once

Step 4 — Copy credentials to .env

GITHUB_CLIENT_ID=Iv1.xxxxxxxxxxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Both values are server-only.

Step 5 — Verify locally

  1. Restart the dev server: pnpm dev
  2. Open http://localhost:3000/sign-in
  3. The Sign in with GitHub button should be enabled
  4. Click it — authorize the app, then land on /dashboard

GitHub Apps vs OAuth Apps

Motoko Base uses a standard OAuth App (not a GitHub App). If you use a GitHub App instead, ensure Account permissions → Email addresses is set to Read-only so Better Auth can read the user's verified email.

GitHub troubleshooting

ProblemFix
redirect_uri mismatchCallback URL must be {BETTER_AUTH_URL}/api/auth/callback/github exactly
Button disabledBoth GITHUB_* vars must be set; restart dev server
Missing email / sign-in failsFor GitHub Apps, enable Email addresses read permission; OAuth Apps include email by default
Works locally, fails in productionUpdate callback URL in GitHub settings and set production BETTER_AUTH_URL

Production checklist

Use this checklist when deploying OAuth to staging or production:

  1. Set canonical URLs

    BETTER_AUTH_URL=https://app.example.com
    NEXT_PUBLIC_APP_URL=https://app.example.com
  2. Add production callback URLs in Google Console and GitHub OAuth app settings (keep local URIs if you still develop locally)

  3. Optional — extra origins for preview deployments:

    BETTER_AUTH_TRUSTED_ORIGINS=https://staging.example.com,https://*.vercel.app
  4. Restart / redeploy after env changes

  5. Test both providers on the live URL — sign in, sign out, and confirm the session persists


Where OAuth is wired in code

You usually only need env vars. To customize behavior, edit these files:

FilePurpose
src/lib/auth/auth.tsRegisters socialProviders.google and socialProviders.github
src/lib/auth/social.tsisGoogleAuthConfigured() / isGitHubAuthConfigured()
src/app/sign-in/sign-in-form.tsxGoogle/GitHub sign-in handlers
src/app/sign-up/sign-up-form.tsxGoogle/GitHub sign-up handlers
src/app/sign-in/page.tsxPasses enabled flags to the form

OAuth secrets never belong in TypeScript config files — only in .env.


Next steps

Better Auth — Full auth overview, sessions, protected routes, and file map.

Environment Variables — All auth-related env vars in one place.