Skip to content

GitHub Pages

GitHub Pages is a common static host for Astro projects. It works well for project docs, portfolios, small product sites, and public documentation. The main detail to get right is whether the site is served from the domain root or from a repository subpath.

GitHub Pages has two common shapes:

Page typeExample URLAstro siteAstro base
User or organization sitehttps://user.github.io/https://user.github.io/
Project sitehttps://user.github.io/repo/https://user.github.io/repo/
Custom domainhttps://docs.example.com/https://docs.example.com/

Most broken GitHub Pages deployments come from using / locally and forgetting that a project site lives under /<repo>/.

For a project site:

import { defineConfig } from 'astro/config';
export default defineConfig({
site: 'https://user.github.io',
base: '/repo/',
});

For a custom domain:

import { defineConfig } from 'astro/config';
export default defineConfig({
site: 'https://docs.example.com',
base: '/',
});

Commit the config before setting up the workflow. The build output must be generated with the same path shape that GitHub Pages will serve.

A typical workflow lives at .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: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: dist
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

In the repository settings, set Pages to deploy from GitHub Actions.

After the workflow finishes, open:

  • the homepage
  • one deep route
  • one route with code blocks or images
  • sitemap-index.xml if sitemap generation is enabled

For a project site, inspect the page source or network panel. CSS and JavaScript should load from /repo/_astro/..., not from /_astro/....

When using a custom domain, add the domain in GitHub Pages settings and configure DNS as GitHub instructs. In Astro, set site to the custom domain and usually set base to /.

If the site previously used a project subpath, remove the old base. Leaving base: '/repo/' after moving to a custom domain will make links and assets point to the wrong place.

SymptomLikely fix
Page loads without CSSSet base to /<repo>/ for project sites
Homepage works but nested pages do notConfirm output paths and Pages source
Sitemap uses wrong domainSet site correctly
Workflow cannot deployCheck Pages permissions and repository settings
Build fails in Actions but works locallyAlign Node version and use npm ci with the lockfile