Skip to main content

GitHub Pages

GitHub Pages hosts static websites directly from a GitHub repository. It is free, fast, and perfect for documentation sites, portfolios, and project landing pages. In this guide, you will deploy a site and configure it with a custom domain and automated deployments.

Quick Start

Deploying from a Branch

The simplest approach deploys directly from a gh-pages or main branch:

  1. Create a repository with an index.html in the root or docs/ folder
  2. Go to Settings → Pages
  3. Under "Source", select Deploy from a branch
  4. Choose main and / (root) or /docs
  5. Click Save

Your site will be available at https://<username>.github.io/<repo>/.

For build-step sites (Docusaurus, Next.js, MkDocs), use GitHub Actions to build and deploy:

yaml
# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm

- name: Install dependencies
run: npm ci

- name: Build site
run: npm run build

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./build

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Docusaurus configuration

For Docusaurus sites, set url and baseUrl in docusaurus.config.ts:

typescript
const config = {
url: 'https://yourusername.github.io',
baseUrl: '/your-repo-name/',
// ...
};

If deploying to https://<username>.github.io/ (user/org site), set baseUrl to '/'.

Custom Domains

Configure DNS

Point your domain to GitHub Pages:

For apex domains (example.com):

code
A @ 185.199.108.153
A @ 185.199.109.153
A @ 185.199.110.153
A @ 185.199.111.153

For subdomains (www.example.com):

code
CNAME www <username>.github.io

Configure GitHub

  1. In your repository, go to Settings → Pages → Custom domain
  2. Enter your domain and click Save
  3. Check Enforce HTTPS (wait for DNS to propagate first)
  4. GitHub creates a CNAME file in your repository root — do not delete it

Verify in Workflow

Add a step to your GitHub Actions to ensure the CNAME file is included in the build output:

yaml
- name: Add CNAME
run: echo "www.example.com" > ./build/CNAME
HTTPS enforcement

Always enable HTTPS. GitHub provides free SSL certificates via Let's Encrypt. It may take up to 15 minutes after configuring your custom domain for the certificate to be issued.

Preview Deployments

You can configure GitHub Actions to deploy previews for pull requests:

yaml
# Add to your deploy.yml workflow
preview:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- run: npm ci
- run: npm run build
- name: Deploy preview
uses: rossjrw/pr-preview-action@v1
with:
source-dir: ./build

This deploys every PR to a unique URL so reviewers can see the rendered site before merging.

Troubleshooting

ProblemSolution
Site shows 404Check that the branch and folder in Settings → Pages are correct
CSS/JS not loadingVerify baseUrl in your config matches the repository path
Custom domain not workingCheck DNS propagation with dig example.com
HTTPS not availableWait 15 minutes after adding custom domain, then re-check
Build failsCheck the Actions tab for error logs
GitHub Pages limits
  • Repositories: 1 GB max
  • Builds: 10 minutes max
  • Sites: 100 per account
  • Bandwidth: 100 GB/month
  • These limits are generous for most projects but not suitable for large data hosting.