Social authentication (OAuth) for React with Convex Auth. Enable users to sign in with GitHub or Google with a single click.
Installation
npx shadcn@latest add https://convex-ui.vercel.app/r/social-auth-react
This installs:
Social login form with GitHub and Google
Convex auth configuration for OAuth
User management backend
Convex client setup
What’s Included
GitHub Sign-In One-click GitHub OAuth authentication
Google Sign-In One-click Google OAuth authentication
User Management Automatic user profile creation and management
Full Backend Complete Convex auth setup with OAuth providers
Setup
Set up OAuth credentials in each provider’s dashboard:
GitHub
Go to GitHub Developer Settings
Create a new OAuth App
Set callback URL: https://your-deployment.convex.cloud/api/auth/callback/github
Copy Client ID and Client Secret
Google
Go to Google Cloud Console
Create a new project or select existing
Enable Google+ API
Create OAuth 2.0 credentials
Add authorized redirect URI: https://your-deployment.convex.cloud/api/auth/callback/google
Copy Client ID and Client Secret
Set Environment Variables
Add credentials to Convex dashboard (Settings > Environment Variables):
AUTH_GITHUB_ID = Iv1.your_github_id
AUTH_GITHUB_SECRET = your_github_secret
AUTH_GOOGLE_ID = your_google_id.apps.googleusercontent.com
AUTH_GOOGLE_SECRET = your_google_secret
At least one OAuth provider must be configured for authentication to work.
Set VITE_CONVEX_URL in your .env file:
VITE_CONVEX_URL = https://your-deployment.convex.cloud
CONVEX_DEPLOYMENT = your-deployment-name
Component
A card-based form with social sign-in buttons.
import { SocialLoginForm } from "@/components/login-form" ;
function LoginPage () {
return (
< div className = "flex items-center justify-center min-h-screen" >
< SocialLoginForm providers = { [ 'github' , 'google' ] } />
</ div >
);
}
Props
providers
('github' | 'google')[]
default: ["github","google"]
Array of OAuth providers to display. Defaults to both GitHub and Google.
Usage Examples
GitHub Only
Custom Layout
With Auth Check
import { SocialLoginForm } from '@/components/login-form' ;
function GitHubLogin () {
return (
< div className = "flex items-center justify-center min-h-screen" >
< SocialLoginForm providers = { [ 'github' ] } />
</ div >
);
}
Authentication Flow
Clicking a provider button calls signIn(provider) which redirects to the OAuth provider.
The user authorizes your app on GitHub or Google.
The provider redirects back to your Convex deployment with an authorization code.
Convex Auth automatically creates or updates the user profile with information from the OAuth provider.
The user is redirected back to your application, now authenticated.
Backend Functions
User Queries
Get current user:
import { useQuery } from 'convex/react' ;
import { api } from '@/convex/_generated/api' ;
const user = useQuery ( api . users . current );
// Returns: { _id, name, email, image } | null
Get user by ID:
const publicProfile = useQuery ( api . users . get , {
userId: "j97..."
});
// Returns: { _id, name, image } | null
User Mutations
Update profile:
import { useMutation } from 'convex/react' ;
import { api } from '@/convex/_generated/api' ;
const updateProfile = useMutation ( api . users . updateProfile );
await updateProfile ({
name: "Jane Doe" ,
image: "https://example.com/avatar.jpg"
});
Sign Out
Use the useAuthActions hook to sign out:
import { useAuthActions } from "@convex-dev/auth/react" ;
function SignOutButton () {
const { signOut } = useAuthActions ();
return (
< button onClick = { () => signOut () } >
Sign Out
</ button >
);
}
Component Source
The login form component uses Convex Auth’s useAuthActions hook:
components/login-form.tsx
"use client" ;
import { useAuthActions } from "@convex-dev/auth/react" ;
import { Button } from "@/components/ui/button" ;
import { Card , CardContent , CardHeader , CardTitle } from "@/components/ui/card" ;
import { useState } from "react" ;
type Provider = "github" | "google" ;
interface SocialLoginFormProps {
providers ?: Provider [];
}
export function SocialLoginForm ({
providers = [ "github" , "google" ],
} : SocialLoginFormProps ) {
const { signIn } = useAuthActions ();
const [ loadingProvider , setLoadingProvider ] = useState < Provider | null >( null );
const handleSocialLogin = async ( provider : Provider ) => {
setLoadingProvider ( provider );
try {
await signIn ( provider );
} catch ( err ) {
setLoadingProvider ( null );
}
};
return (
< Card className = "w-full max-w-md" >
< CardHeader >
< CardTitle > Welcome </ CardTitle >
</ CardHeader >
< CardContent className = "space-y-4" >
{ providers . map (( provider ) => (
< Button
key = { provider }
onClick = { () => handleSocialLogin ( provider ) }
disabled = { loadingProvider !== null }
>
Continue with { provider }
</ Button >
)) }
</ CardContent >
</ Card >
);
}
Environment Variables
Required (Your App)
Your Convex deployment URL from npx convex dev
Your Convex deployment name
Required (Convex Dashboard)
At least one OAuth provider must be configured:
GitHub OAuth Client Secret
Google OAuth Client Secret
Customization
The social login form uses shadcn/ui components:
// Customize button appearance
< Button
variant = "outline"
size = "lg"
className = "w-full"
>
< GitHubIcon className = "mr-2" />
Continue with GitHub
</ Button >
Modify the component in your components/ directory to customize icons, layout, or styling.
Troubleshooting
Verify your callback URLs in GitHub/Google match your Convex deployment URL exactly. The URL should be https://your-deployment.convex.cloud/api/auth/callback/[provider].
No providers configured error
Ensure you’ve added AUTH_GITHUB_ID and AUTH_GITHUB_SECRET (or Google equivalents) to your Convex dashboard environment variables. At least one provider must be configured.
Button stays in loading state
Check browser console for errors. This usually indicates an OAuth configuration issue or network error during the redirect.
Next Steps
Current User Avatar Display the authenticated user’s avatar
Password Auth Add email/password authentication
Realtime Chat Build authenticated chat rooms