Skip to main content

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.

Simple button

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>
  );
}

Button with loading state

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>
  );
}

Styled button example

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>
  );
}

Icon button example

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>
  );
}

Configuring the popup window

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:
ScopeAccess granted
user:emailRead user email addresses (default)
repoFull control of private repositories
read:orgRead org and team membership
gistCreate gists
notificationsAccess 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.

Build docs developers (and LLMs) love