Documentation Index
Fetch the complete documentation index at: https://mintlify.com/MomenSherif/react-oauth/llms.txt
Use this file to discover all available pages before exploring further.
useGitHubLogin gives you two primitives: a function to start the OAuth flow and a boolean for loading state. How you render your button is entirely up to you.
The minimal implementation — a plain button that disables itself while the popup is open:
import { useGitHubLogin } from '@react-oauth/github';
function LoginButton() {
const { initiateGitHubLogin, isLoading } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
onSuccess: response => {
console.log('Authorization code:', response.code);
},
onError: error => {
console.error('Authentication failed:', error);
},
});
return (
<button onClick={initiateGitHubLogin} disabled={isLoading}>
{isLoading ? 'Loading...' : 'Sign in with GitHub'}
</button>
);
}
Use isLoading to show a spinner or change the button label while waiting for the popup:
import { useGitHubLogin } from '@react-oauth/github';
function LoginButton() {
const { initiateGitHubLogin, isLoading } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
onSuccess: response => { /* send response.code to your backend */ },
onError: error => { console.error(error); },
});
return (
<button
onClick={initiateGitHubLogin}
disabled={isLoading}
style={{ display: 'flex', alignItems: 'center', gap: '8px' }}
>
{isLoading ? (
<>
<span className="spinner" aria-hidden="true" />
Connecting to GitHub...
</>
) : (
'Sign in with GitHub'
)}
</button>
);
}
Pass any styling library’s classes or styled components — the hook has no opinions about rendering:
import { useGitHubLogin } from '@react-oauth/github';
const githubButtonStyle: React.CSSProperties = {
display: 'inline-flex',
alignItems: 'center',
gap: '10px',
padding: '10px 20px',
backgroundColor: '#24292e',
color: '#ffffff',
border: 'none',
borderRadius: '6px',
fontSize: '14px',
fontWeight: 600,
cursor: 'pointer',
opacity: 1,
transition: 'opacity 0.2s',
};
function StyledLoginButton() {
const { initiateGitHubLogin, isLoading } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
return (
<button
onClick={initiateGitHubLogin}
disabled={isLoading}
style={{ ...githubButtonStyle, opacity: isLoading ? 0.7 : 1 }}
>
<GitHubIcon />
{isLoading ? 'Connecting...' : 'Continue with GitHub'}
</button>
);
}
Render only an icon, with a tooltip or aria-label for accessibility:
import { useGitHubLogin } from '@react-oauth/github';
function GitHubIconButton() {
const { initiateGitHubLogin, isLoading } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
return (
<button
onClick={initiateGitHubLogin}
disabled={isLoading}
aria-label="Sign in with GitHub"
title="Sign in with GitHub"
>
<GitHubIcon size={24} />
</button>
);
}
Pass popupOptions to control the size and position of the OAuth popup:
const { initiateGitHubLogin } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
popupOptions: {
width: 600, // popup width in pixels (default: 500)
height: 800, // popup height in pixels (default: 700)
left: 200, // distance from left edge of screen in pixels
top: 100, // distance from top edge of screen in pixels
},
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
When left and top are not specified, the popup is centered on the screen automatically.
Tracking requests with onRequest
The onRequest callback fires when the OAuth flow starts — before the popup opens. Use it for analytics, logging, or to update UI state:
const { initiateGitHubLogin } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
onRequest: () => {
analytics.track('github_login_started');
},
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
Controlling sign-up with allowSignup
By default, the GitHub authorization page lets users create a new GitHub account if they don’t have one. Set allowSignup to false to require an existing account:
const { initiateGitHubLogin } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
allowSignup: false, // hides the "Create an account" option on GitHub's page
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
Requesting scopes
The default scope is user:email. Pass scope to request additional permissions as a comma-separated string:
const { initiateGitHubLogin } = useGitHubLogin({
clientId: 'your-github-client-id',
redirectUri: 'http://localhost:3000/callback',
scope: 'user:email,read:org',
onSuccess: response => { /* handle response */ },
onError: error => { console.error(error); },
});
Common scopes:
| Scope | Access granted |
|---|
user:email | Read user email addresses (default) |
repo | Full control of private repositories |
read:org | Read org and team membership |
gist | Create gists |
notifications | Access notifications |
Request only the scopes your application actually needs. GitHub shows users a list of the permissions you are requesting on the authorization screen — fewer scopes build more trust.
See GitHub’s OAuth scopes documentation for the complete list.