Add OAuth
Learn how to add OAuth providers like Google, GitHub, and Microsoft to Plainform
Learn how to add OAuth authentication providers to your Plainform application for one-click sign-in.
Goal
By the end of this recipe, you'll have added OAuth providers (Google, GitHub, Microsoft, etc.) to your sign-in and sign-up pages.
Prerequisites
- A working Plainform installation
- Clerk account with application configured
- Access to Clerk Dashboard
Plainform's custom sign-in/sign-up forms already include OAuth button components. You just need to enable providers in Clerk Dashboard.
Steps
Enable OAuth Provider in Clerk
Navigate to your Clerk Dashboard:
- Go to User & Authentication → Social Connections
- Find the provider you want to enable (Google, GitHub, Microsoft, etc.)
- Toggle the provider ON
- Click Save
Start with Google and GitHub as they're the most commonly used and easiest to set up.
Configure Provider Credentials
Each OAuth provider requires credentials (Client ID and Secret). Clerk provides two options:
Option 1: Use Clerk's Development Credentials (Recommended for Testing)
Clerk provides pre-configured credentials for development. No additional setup needed.
Option 2: Use Your Own Credentials (Required for Production)
- Click Use custom credentials for your provider
- Follow the provider-specific setup guide:
- Google: Create OAuth app in Google Cloud Console
- GitHub: Create OAuth app in GitHub Settings
- Microsoft: Create app in Azure Portal
- Copy the Client ID and Client Secret
- Paste them into Clerk Dashboard
- Add the Redirect URI from Clerk to your OAuth app settings
For production, you MUST use your own OAuth credentials. Clerk's development credentials are rate-limited and not suitable for live apps.
Add OAuth Button to Sign-In Form
The SignInForm component already includes the OAuthConnection component for OAuth buttons:
import { OAuthConnection } from '@/components/user/OAuthConnection';
import { useClerk } from '@clerk/nextjs';
export function SignInForm() {
const { client } = useClerk();
const lastStrategy = client?.lastAuthenticationStrategy;
return (
<div>
{/* OAuth buttons */}
<div className="w-full flex flex-col gap-4">
<OAuthConnection
strategy="oauth_google"
lastUsed={lastStrategy}
icon="Google"
>
Continue with Google
</OAuthConnection>
<OAuthConnection
lastUsed={lastStrategy}
strategy="oauth_github"
icon="GitHub"
>
Continue with GitHub
</OAuthConnection>
</div>
{/* Separator */}
<div className="flex gap-3 items-center text-neutral-foreground">
<Separator className="shrink" />
Or continue with email
<Separator className="shrink" />
</div>
{/* Email/password form */}
</div>
);
}The OAuthConnection component props:
Required:
strategy: OAuth provider identifier (e.g.,"oauth_google","oauth_github","oauth_microsoft")icon: Icon name for the button (e.g.,"Google","GitHub","Microsoft")children: Button text content (e.g., "Continue with Google")
Optional:
lastUsed: Last authentication strategy used (shows "Last used" badge when matching)className: Additional CSS classes for custom styling
How it works:
- Uses
signIn.authenticateWithRedirect()on sign-in buttons - Uses
signUp.authenticateWithRedirect()on sign-up buttons whenisSignedUpis set - Handles loading states with local
loadingProviderstate per provider - Shows "Last used" badge for the most recently used OAuth strategy
- Redirects to
/sso-callbackto complete authentication - Displays loading spinner during authentication
If the buttons aren't present, add them using the code above.
Add OAuth Button to Sign-Up Form
Similarly, the SignUpForm includes the OAuthConnection component:
import { OAuthConnection } from '@/components/user/OAuthConnection';
import { useClerk } from '@clerk/nextjs';
export function SignUpForm() {
const { client } = useClerk();
const lastStrategy = client?.lastAuthenticationStrategy;
return (
<div>
{/* OAuth buttons at the top */}
<div className="w-full flex flex-col gap-4">
<OAuthConnection
isSignedUp
strategy="oauth_google"
lastUsed={lastStrategy}
icon="Google"
>
Continue with Google
</OAuthConnection>
<OAuthConnection
isSignedUp
lastUsed={lastStrategy}
strategy="oauth_github"
icon="GitHub"
>
Continue with GitHub
</OAuthConnection>
</div>
{/* Separator */}
<div className="flex gap-3 items-center text-neutral-foreground">
<Separator className="shrink" />
Or sign up with email
<Separator className="shrink" />
</div>
{/* Email/password form */}
</div>
);
}Test OAuth Flow
Start your development server:
npm run devTest the OAuth flow:
- Navigate to
http://localhost:3000/sign-in - Click an OAuth provider button (e.g., "Google")
- Complete the provider's redirect flow
- You should be redirected back to your app and signed in
- Check Clerk Dashboard → Users to see the new OAuth user
In development, Clerk uses test mode. OAuth flows work the same as production but use Clerk's development credentials.
Available OAuth Providers
Clerk supports the following OAuth providers. Enable them in Clerk Dashboard → Social Connections:
oauth_google- Googleoauth_github- GitHuboauth_microsoft- Microsoftoauth_apple- Appleoauth_facebook- Facebookoauth_linkedin- LinkedInoauth_twitter- Twitter (X)oauth_discord- Discordoauth_twitch- Twitchoauth_gitlab- GitLaboauth_bitbucket- Bitbucket
To add a provider:
- Enable it in Clerk Dashboard → Social Connections
- Add the
OAuthConnectioncomponent to your sign-in/sign-up forms with the required props:
<OAuthConnection
strategy="oauth_microsoft" // Required: Must match Clerk's strategy name
icon="Microsoft" // Required: Icon name from SvgFinder
lastUsed={lastStrategy} // Optional: For "Last used" badge
>
Continue with Microsoft {/* Required: Button text */}
</OAuthConnection>Important: The strategy prop must exactly match Clerk's OAuth strategy names (e.g., oauth_google, not google or oauth-google).
The OAuthConnection component handles OAuth with Clerk's redirect-based API. On the sign-in form it calls signIn.authenticateWithRedirect(). On the sign-up form, pass isSignedUp so it calls signUp.authenticateWithRedirect() instead.
Key Props:
strategy(required): Must exactly match Clerk's OAuth strategy names (e.g.,"oauth_google", not"google")icon(required): Icon name that exists in yourSvgFindercomponentchildren(required): Button text contentlastUsed(optional): Shows "Last used" badge when matching the last authentication strategyisSignedUp(optional): Use on sign-up forms to start the sign-up OAuth flow
The component shows a loading spinner during authentication and displays a "Last used" badge for the most recently used OAuth strategy.
Customization Options
Change Button Layout
Display OAuth buttons in a single column (default in Plainform):
<div className="w-full flex flex-col gap-4">
<OAuthConnection
strategy="oauth_google"
lastUsed={lastStrategy}
icon="Google"
>
Continue with Google
</OAuthConnection>
<OAuthConnection
lastUsed={lastStrategy}
strategy="oauth_github"
icon="GitHub"
>
Continue with GitHub
</OAuthConnection>
</div>Or use a grid layout for multiple providers:
<div className="grid grid-cols-2 gap-4">
<OAuthConnection strategy="oauth_google" lastUsed={lastStrategy} icon="Google">
Google
</OAuthConnection>
<OAuthConnection strategy="oauth_github" lastUsed={lastStrategy} icon="GitHub">
GitHub
</OAuthConnection>
<OAuthConnection strategy="oauth_microsoft" lastUsed={lastStrategy} icon="Microsoft">
Microsoft
</OAuthConnection>
<OAuthConnection strategy="oauth_apple" lastUsed={lastStrategy} icon="Apple">
Apple
</OAuthConnection>
</div>OAuth Callback Handling
Plainform includes an OAuth callback page at app/(auth)/sso-callback/page.tsx:
'use client';
import { AuthenticateWithRedirectCallback } from '@clerk/nextjs';
export default function SSOCallback() {
return <AuthenticateWithRedirectCallback />;
}This page handles the OAuth redirect and completes the authentication flow. The OAuthConnection component automatically redirects to this page with:
async function signInWith(strategy: OAuthStrategy) {
setLoadingProvider(strategy);
try {
return signIn?.authenticateWithRedirect({
strategy,
redirectUrl: '/sso-callback',
redirectUrlComplete: '/',
});
} catch (error) {
return error;
}
}
async function signUpWith(strategy: OAuthStrategy) {
setLoadingProvider(strategy);
try {
return signUp?.authenticateWithRedirect({
strategy,
redirectUrl: '/sso-callback',
redirectUrlComplete: '/',
});
} catch (error) {
return error;
}
}No changes needed unless you want to customize the loading state or redirect behavior.
Common Issues
OAuth Button Not Working
- Verify the provider is enabled in Clerk Dashboard
- Check that the strategy name matches exactly (e.g.,
oauth_google) - Ensure
OAuthConnectioncomponent is imported correctly - Check browser console for errors
OAuth Redirect Fails
- Check that redirect URLs are configured correctly in Clerk
- Verify the provider is enabled and configured in Clerk Dashboard
- Test in incognito mode to rule out extension or cookie issues
User Not Created After OAuth
- Verify email verification settings in Clerk Dashboard
- Check that the OAuth provider returns an email address
- Review Clerk Dashboard → Users for pending verifications
Redirect Loop After OAuth
- Check middleware configuration in
proxy.ts - Verify redirect URLs in Clerk Dashboard match your app URLs
- Ensure
sso-callbackroute is accessible (not protected)
Production Setup
When deploying to production:
-
Use Your Own OAuth Credentials
- Create OAuth apps for each provider
- Add production redirect URLs
- Update credentials in Clerk Dashboard
-
Configure Redirect URLs
- Add your production domain to OAuth app settings
- Update Clerk Dashboard with production URLs
- Format:
https://yourdomain.com/sso-callback
-
Test OAuth Flow
- Test each provider in production
- Verify redirects work correctly
- Check that users are created in Clerk Dashboard
OAuth providers require HTTPS in production. Ensure your domain has a valid SSL certificate.
Best Practices
- Offer Multiple Providers: Give users choice (Google, GitHub, Microsoft)
- Clear Labeling: Use "Continue with [Provider]" for clarity
- Consistent Placement: Put OAuth buttons in the same location on sign-in and sign-up
- Error Handling: Show clear error messages if OAuth fails
- Privacy Policy: Link to your privacy policy near OAuth buttons
Next Steps
- Customize Sign-In - Customize the sign-in page
- Implement Roles - Add role-based access control
- Protect Routes - Secure your application routes
Related Documentation
- Authentication Overview - Learn about Clerk integration
- Setup & Configuration - Configure Clerk
- Troubleshooting - Fix common issues
How is this guide ?
Last updated on