GitHub OAuth Apps allow only one Authorization callback URL per app, so register a separate app per environment if you run staging + production on different domains.
Sign in to github.com, click your profile picture in the top-right corner, then go to Settings → Developer settings → OAuth Apps. (Direct link: github.com/settings/developers.)
Click "New OAuth App". GitHub will ask for four fields. The labels are exact, the values can be anything that describes your app.
Application name: anything that identifies your app to end users (they see this on the GitHub consent screen). Homepage URL: your deployed app URL (https://<your-deployed-domain>). Application description (optional): a one-liner about what your app does, also shown on the consent screen. Authorization callback URL: paste your DontCode redirect URL exactly as shown above (https://<your-deployed-domain>/api/auth/oauth/callback).
Unlike Google or Kakao, GitHub OAuth Apps allow exactly one callback URL per app. You cannot register multiple variants in the same app. If you run separate staging and production domains, register two separate OAuth Apps (one per domain) and paste each Client ID into the matching DontCode environment. The DontCode dashboard shows the redirect URL for each verified domain.
GitHub creates the app and lands you on its settings page. You should see your Client ID near the top of the page (a 20-character hex string).
On the same settings page, find the "Client secrets" section and click "Generate a new client secret". GitHub may ask you to confirm with sudo or 2FA. The secret appears once, copy it immediately, you cannot view it again after you leave the page. Treat it like a password.
Back in your DontCode project, go to Users → Sign-in → GitHub. Paste the Client ID and the Client Secret into the matching fields and click Save. DontCode redeploys automatically and the GitHub login button goes live in a few seconds.
DontCode automatically asks GitHub for the user:email scope on every sign-in. This lets us pull the user's primary verified email from /user/emails so accounts always have an email address, even when the user has their email set to private on their public GitHub profile. You do not need to configure this manually.
Also check the troubleshooting section on the main guide for issues that apply to all providers.
GitHub is strict, the callback URL has to match character-for-character. Re-check protocol (http vs https), trailing slash, and host. If your deployed domain changed (custom domain swap, environment switch), update the OAuth App's Authorization callback URL on GitHub. If you need multiple URLs (staging + production), register a separate OAuth App per environment, GitHub does not support multiple callback URLs on one app.
Usually means the Client Secret stored in DontCode is wrong, GitHub rotated the secret, or you have not pasted it back in after rotating. Open the OAuth App on GitHub, generate a new client secret, then paste it back into DontCode and click Save. Old secrets are revoked the moment you rotate.
That is the synthetic email DontCode falls back to when GitHub does not return an email. With the user:email scope (which DontCode requests automatically), this should not happen, every GitHub user has at least one verified email. If you see it, the user probably revoked their email permission mid-flow, ask them to retry and approve all consent items.
Expected behavior the first time a user signs in, and any time you add new scopes. GitHub does not show the consent screen on subsequent logins for the same scope set. If you change scopes (e.g. add read:user later), users will be re-prompted once.