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:
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:
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@v5The 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: writeplusid-token: write. - Assets, navigation, or search return 404: ensure
--site-urlincludes the complete repository pathname and ends at the public site root. - Artifact upload finds no files: align
pathwith--out-diror configuredoutDir. - 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/mdxand install dependencies on that target instead of copyingnode_modulesfrom another machine.