Skip to content
On This Page

Deploy to GitHub Pages

GitHub Pages project sites normally live at https://owner.github.io/repository/. Doctrine supports that subpath when the build receives the final public URL.

1. Verify the production build locally

Use the same public shape before adding CI:

Shell
doctrine build docs --site-url https://owner.github.io/repository/

Open the generated dist/index.html through a static server if you want to exercise navigation and search. Do not open it with a file: URL; module scripts and Pagefind expect HTTP serving.

2. Enable Actions deployment

In the repository, open Settings → Pages and set Source to GitHub Actions.

3. Add the workflow

Create .github/workflows/deploy-docs.yml:

YAML
name: Deploy documentation

on:
  push:
    branches: [main]
  workflow_dispatch:

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

concurrency:
  group: pages
  cancel-in-progress: true

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - id: pages
        uses: actions/configure-pages@v6
      - run: doctrine build docs --site-url "${{ steps.pages.outputs.base_url }}"
      - uses: actions/upload-pages-artifact@v5
        with:
          path: dist
      - id: deployment
        uses: actions/deploy-pages@v5

The versions match this repository's tested Pages toolchain. Change the branch, package manager, content directory, or output directory to match the consuming project. Keep the upload path aligned with --out-dir or outDir.

Why base_url matters

actions/configure-pages returns the configured Pages URL, including /repository/ for a project site or the custom domain when present. Doctrine normalizes that URL and uses its pathname for:

  • CSS and JavaScript assets
  • default MDX links and navigation
  • locale routes and language switching
  • Pagefind requests and result links
  • canonical and alternate metadata
  • scripts and styles referenced by 404.html

The artifact still contains dist/index.html, not dist/repository/index.html. GitHub Pages adds the repository prefix while serving the artifact.

Custom domains and other static hosts

The same workflow works after Pages is configured with a custom domain because base_url reflects that setting. For another static host, run the same build with its final HTTP(S) URL and upload the contents of the output directory. No production Node.js process is required.

Troubleshooting

  • Workflow cannot deploy: confirm Pages uses GitHub Actions and the job has pages: write plus id-token: write.
  • Assets, navigation, or search return 404: ensure --site-url includes the complete repository pathname and ends at the public site root.
  • Artifact upload finds no files: align path with --out-dir or configured outDir.
  • Build rejects outDir: keep it inside the project root, outside the content directory, and do not use the root itself.
  • Native binding cannot load: run on a platform supported by @amamo/mdx and install dependencies on that target instead of copying node_modules from another machine.
copyright © 2026 白熱。