OAuth Providers
Add social login with Google, GitHub, Discord, and more using Clerk.
Prerequisites#
- Clerk account with application created
- Clerk + Next.js setup complete
Google OAuth#
1. Create Google OAuth Credentials#
- Go to Google Cloud Console
- Create a new project or select existing
- Navigate to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Select Web application
- Add authorized redirect URI:
https://your-app.clerk.accounts.dev/v1/oauth_callback
2. Configure in Clerk Dashboard#
- Go to Clerk Dashboard > User & Authentication > Social Connections
- Enable Google
- Enter your Client ID and Client Secret
3. Use in Your App#
1// components/SocialLogin.tsx
2'use client';
3
4import { useSignIn } from '@clerk/nextjs';
5
6export function GoogleButton() {
7 const { signIn } = useSignIn();
8
9 const handleGoogleSignIn = () => {
10 signIn?.authenticateWithRedirect({
11 strategy: 'oauth_google',
12 redirectUrl: '/sso-callback',
13 redirectUrlComplete: '/dashboard',
14 });
15 };
16
17 return (
18 <button
19 onClick={handleGoogleSignIn}
20 className="flex items-center gap-2 px-4 py-2 border rounded-lg hover:bg-gray-50"
21 >
22 <GoogleIcon className="w-5 h-5" />
23 Continue with Google
24 </button>
25 );
26}
27
28function GoogleIcon({ className }: { className?: string }) {
29 return (
30 <svg className={className} viewBox="0 0 24 24">
31 <path
32 fill="#4285F4"
33 d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
34 />
35 <path
36 fill="#34A853"
37 d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
38 />
39 <path
40 fill="#FBBC05"
41 d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
42 />
43 <path
44 fill="#EA4335"
45 d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
46 />
47 </svg>
48 );
49}GitHub OAuth#
1. Create GitHub OAuth App#
- Go to GitHub Developer Settings
- Click New OAuth App
- Set Authorization callback URL:
https://your-app.clerk.accounts.dev/v1/oauth_callback
2. Configure in Clerk#
- Enable GitHub in Social Connections
- Enter Client ID and Client Secret
3. Use in Your App#
1// components/SocialLogin.tsx
2'use client';
3
4import { useSignIn } from '@clerk/nextjs';
5import { Github } from 'lucide-react';
6
7export function GitHubButton() {
8 const { signIn } = useSignIn();
9
10 const handleGitHubSignIn = () => {
11 signIn?.authenticateWithRedirect({
12 strategy: 'oauth_github',
13 redirectUrl: '/sso-callback',
14 redirectUrlComplete: '/dashboard',
15 });
16 };
17
18 return (
19 <button
20 onClick={handleGitHubSignIn}
21 className="flex items-center gap-2 px-4 py-2 bg-gray-900 text-white rounded-lg hover:bg-gray-800"
22 >
23 <Github className="w-5 h-5" />
24 Continue with GitHub
25 </button>
26 );
27}Discord OAuth#
1. Create Discord Application#
- Go to Discord Developer Portal
- Click New Application
- Go to OAuth2 section
- Add redirect:
https://your-app.clerk.accounts.dev/v1/oauth_callback
2. Configure in Clerk#
- Enable Discord in Social Connections
- Enter Client ID and Client Secret
3. Use in Your App#
1// components/SocialLogin.tsx
2export function DiscordButton() {
3 const { signIn } = useSignIn();
4
5 const handleDiscordSignIn = () => {
6 signIn?.authenticateWithRedirect({
7 strategy: 'oauth_discord',
8 redirectUrl: '/sso-callback',
9 redirectUrlComplete: '/dashboard',
10 });
11 };
12
13 return (
14 <button
15 onClick={handleDiscordSignIn}
16 className="flex items-center gap-2 px-4 py-2 bg-[#5865F2] text-white rounded-lg hover:bg-[#4752C4]"
17 >
18 <DiscordIcon className="w-5 h-5" />
19 Continue with Discord
20 </button>
21 );
22}Complete Social Login Component#
1// components/SocialLogin.tsx
2'use client';
3
4import { useSignIn } from '@clerk/nextjs';
5import { Github } from 'lucide-react';
6
7type OAuthStrategy = 'oauth_google' | 'oauth_github' | 'oauth_discord';
8
9interface SocialButtonProps {
10 strategy: OAuthStrategy;
11 icon: React.ReactNode;
12 label: string;
13 className?: string;
14}
15
16function SocialButton({ strategy, icon, label, className }: SocialButtonProps) {
17 const { signIn, isLoaded } = useSignIn();
18
19 const handleClick = () => {
20 if (!isLoaded) return;
21
22 signIn.authenticateWithRedirect({
23 strategy,
24 redirectUrl: '/sso-callback',
25 redirectUrlComplete: '/dashboard',
26 });
27 };
28
29 return (
30 <button
31 onClick={handleClick}
32 disabled={!isLoaded}
33 className={`flex items-center justify-center gap-2 w-full px-4 py-3 rounded-lg font-medium transition-colors ${className}`}
34 >
35 {icon}
36 {label}
37 </button>
38 );
39}
40
41export function SocialLogin() {
42 return (
43 <div className="space-y-3">
44 <SocialButton
45 strategy="oauth_google"
46 icon={<GoogleIcon className="w-5 h-5" />}
47 label="Continue with Google"
48 className="border border-gray-300 hover:bg-gray-50 dark:border-gray-600 dark:hover:bg-gray-800"
49 />
50
51 <SocialButton
52 strategy="oauth_github"
53 icon={<Github className="w-5 h-5" />}
54 label="Continue with GitHub"
55 className="bg-gray-900 text-white hover:bg-gray-800 dark:bg-gray-700 dark:hover:bg-gray-600"
56 />
57
58 <SocialButton
59 strategy="oauth_discord"
60 icon={<DiscordIcon className="w-5 h-5" />}
61 label="Continue with Discord"
62 className="bg-[#5865F2] text-white hover:bg-[#4752C4]"
63 />
64
65 <div className="relative my-6">
66 <div className="absolute inset-0 flex items-center">
67 <div className="w-full border-t border-gray-300 dark:border-gray-600" />
68 </div>
69 <div className="relative flex justify-center text-sm">
70 <span className="px-2 bg-white dark:bg-gray-900 text-gray-500">
71 Or continue with email
72 </span>
73 </div>
74 </div>
75 </div>
76 );
77}SSO Callback Page#
1// app/sso-callback/page.tsx
2import { AuthenticateWithRedirectCallback } from '@clerk/nextjs';
3
4export default function SSOCallback() {
5 return <AuthenticateWithRedirectCallback />;
6}Access OAuth Tokens#
1// Access user's OAuth tokens for API calls
2import { auth, clerkClient } from '@clerk/nextjs/server';
3
4export async function getGitHubToken() {
5 const { userId } = await auth();
6
7 if (!userId) {
8 throw new Error('Not authenticated');
9 }
10
11 const client = await clerkClient();
12 const response = await client.users.getUserOauthAccessToken(
13 userId,
14 'oauth_github'
15 );
16
17 const token = response.data[0]?.token;
18 return token;
19}
20
21// Use the token to call GitHub API
22export async function getGitHubRepos() {
23 const token = await getGitHubToken();
24
25 const response = await fetch('https://api.github.com/user/repos', {
26 headers: {
27 Authorization: `Bearer ${token}`,
28 },
29 });
30
31 return response.json();
32}Customization Tips#
Require Specific OAuth Scopes#
Configure additional scopes in Clerk Dashboard under each provider's settings.
Restrict to Specific Domains#
1// middleware.ts - Restrict Google to specific domain
2import { clerkMiddleware } from '@clerk/nextjs/server';
3
4export default clerkMiddleware(async (auth, request) => {
5 const { userId, sessionClaims } = await auth();
6
7 if (userId) {
8 const email = sessionClaims?.email as string;
9 if (!email?.endsWith('@yourcompany.com')) {
10 // Redirect unauthorized domain
11 return Response.redirect(new URL('/unauthorized', request.url));
12 }
13 }
14});