Complete guide to set up Google OAuth authentication.
- Go to Google Cloud Console
- Create a new project (or select existing)
- Click "Select a project" dropdown at the top
- Click "New Project"
- Enter project name (e.g., "Better Auth App")
- Click "Create"
- In your project, go to APIs & Services → Library
- Search for "Google+ API"
- Click on it and click "Enable"
- This is required for OAuth to work
- Gives access to basic profile information
- Go to APIs & Services → OAuth consent screen
- Choose External (unless you have Google Workspace)
- Click "Create"
- App name: Your app name (e.g., "My Auth App")
- User support email: Your email
- App logo: Optional
- App domain: Leave blank for development
- Authorized domains: For production, add your domain
- Add your email address
- Click "Save and Continue"
- Click "Add or Remove Scopes"
- Select these scopes:
userinfo.emailuserinfo.profileopenid
- Click "Update" → "Save and Continue"
-
Click "Add Users"
-
Add your Gmail address(es) for testing
-
Click "Save and Continue"
-
Review and click "Back to Dashboard"
- Go to APIs & Services → Credentials
- Click "Create Credentials" → "OAuth client ID"
- Choose Web application
Name: "Better Auth Web Client" (or any name)
Authorized JavaScript origins (for CORS):
- Development:
http://localhost:4000 - Production:
https://yourdomain.com
Authorized redirect URIs:
- Development:
http://localhost:8787/api/auth/callback/google(Cloudflare Workers) - Development:
http://localhost:4200/api/auth/callback/google(Node.js) - Production:
https://api.yourdomain.com/api/auth/callback/google
Important: The redirect URI must match exactly, including:
- Protocol (http vs https)
- Domain
- Port (for localhost)
- Path
- Click "Create"
After creating:
- You'll see a modal with your credentials
- Copy the Client ID (looks like:
xxxxx.apps.googleusercontent.com) - Copy the Client Secret
- Click "OK"
You can always view these later from the Credentials page.
For Cloudflare Workers, add to .dev.vars:
GOOGLE_CLIENT_ID=your_client_id_here.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secret_hereFor Node.js, add to .env:
GOOGLE_CLIENT_ID=your_client_id_here.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secret_herecd backend
bun run dev # Cloudflare Workers
# or
bun run dev:node # Node.js- Start your app:
http://localhost:4000 - Click "Continue with Google"
- You should be redirected to Google's login page
- Sign in with a test user account
- Grant permissions
- You'll be redirected back to your app, logged in!
Problem: OAuth consent screen not configured properly
Solution:
- Go back to OAuth consent screen
- Ensure all required fields are filled
- Add yourself as a test user
- Save changes
Problem: Redirect URI doesn't match exactly
Solution:
- Check the error message for the exact URI being used
- Go to Credentials → Edit OAuth client
- Add the EXACT URI shown in the error
- Include protocol, domain, port, and path
Common mistakes:
http://localhost:8787/api/auth/callback/google✅http://localhost:4200/api/auth/callback/google✅http://localhost:8787/api/auth/callback/google/❌ (trailing slash)http://127.0.0.1:8787/api/auth/callback/google❌ (use localhost, not 127.0.0.1)
If your app is opened through a tunnel domain, also set:
APP_URLto that exact frontend tunnel URLTRUSTED_ORIGINSto include that URL
Problem: App is in testing mode
For Development:
- Click "Advanced" → "Go to [App name] (unsafe)"
- This is normal for apps in testing mode
- Only shows up for users not in the test users list
For Production:
- Submit app for verification through Google Cloud Console
- Or stay in testing mode and manually add users
Problem: Missing required OAuth scopes
Solution:
- Go to OAuth consent screen → Edit app
- Add required scopes in the Scopes section
- Save changes
- Clear browser cache/cookies
- Try again
Symptoms: Login works but session not persisted
Solutions:
- Ensure Vite proxy is configured (should be by default)
- Check
credentials: "include"in auth client - Verify CORS settings in backend
- Clear browser cookies and try again
Add your production domain:
https://yourdomain.com
Add production callback:
https://api.yourdomain.com/api/auth/callback/google
For Cloudflare Workers:
wrangler secret put GOOGLE_CLIENT_ID
wrangler secret put GOOGLE_CLIENT_SECRETFor Node.js, edit .env:
GOOGLE_CLIENT_ID=your_client_id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your_client_secretFor public apps, verify your app with Google:
- Go to OAuth consent screen
- Click "Publish App"
- Click "Prepare for verification"
- Follow the verification process:
- Add privacy policy URL
- Add terms of service URL
- Explain why you need each scope
- Submit for review
Note: Verification can take several weeks. You can use unverified apps, but users will see a warning.
- Never commit Client Secret to git
- Use environment variables
- Rotate secrets if exposed
- Only add URIs you control
- Use HTTPS in production
- Don't use wildcards
- Only request scopes you need
- More scopes = more permissions users must grant
- Users trust apps that request fewer permissions
- In testing mode, manually add users
- For production, get verified or keep limited user base
You can create separate OAuth clients for each environment:
- Name: "My App (Development)"
- Origins:
http://localhost:4000 - Redirect:
http://localhost:4200/api/auth/callback/google
- Name: "My App (Staging)"
- Origins:
https://staging.yourdomain.com - Redirect:
https://api.staging.yourdomain.com/api/auth/callback/google
- Name: "My App (Production)"
- Origins:
https://yourdomain.com - Redirect:
https://api.yourdomain.com/api/auth/callback/google
Then use different Client IDs/Secrets in each environment's .env file.
Google automatically provides email in the user profile:
const { user } = useTwitterAuth(); // Works for Google too
console.log(user.email); // User's Gmail addressconsole.log(user.avatar); // Profile picture URLBetter Auth automatically handles account linking. If a user signs in with Twitter, then later with Google using the same email, they'll be linked to the same account.
If you encounter issues:
- Check this troubleshooting guide
- Review Google's error messages carefully
- Check browser console for errors
- Review backend logs
- Open an issue on GitHub
✅ Google OAuth configured 📖 Add more providers (GitHub, Discord, etc.) 🔐 Implement email/password authentication 👤 Add user profile management 🚀 Deploy to production