Skip to content

Deploying Docs to GitHub Pages

Deploying to GitHub Pages

The Patro documentation site is built with Astro + Starlight and auto-deploys to GitHub Pages on every push to main.

Live site: thaparoyal.github.io/calendar


How It Works

The deployment is handled by .github/workflows/docs.yml:

  1. Trigger — runs on push to main when files change in apps/site/ or the workflow itself
  2. Build — installs dependencies and builds the Astro site
  3. Deploy — uploads apps/site/dist to GitHub Pages using the official actions/deploy-pages action
name: Deploy to GitHub Pages
on:
push:
branches: [main]
paths:
- 'apps/site/**'
- '.github/workflows/docs.yml'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm --filter site build
- uses: actions/upload-pages-artifact@v3
with:
path: apps/site/dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deployment

GitHub Repository Setup

1. Enable GitHub Pages

Go to your repo Settings > Pages and set:

SettingValue
SourceGitHub Actions

Do not select a branch — the workflow handles deployment via the actions/deploy-pages action.

2. Verify permissions

The workflow needs these permissions (already configured in the YAML):

  • contents: read — to check out the repo
  • pages: write — to deploy to Pages
  • id-token: write — required by the Pages deployment action

3. Trigger a deploy

Either push to main or manually trigger:

Terminal window
gh workflow run docs.yml

Astro Configuration

The site is configured for GitHub Pages in apps/site/astro.config.mjs:

export default defineConfig({
site: 'https://thaparoyal.github.io',
base: '/calendar',
// ...
});
SettingPurpose
siteThe full URL of your GitHub Pages domain
baseThe repository name — GitHub Pages serves repos at username.github.io/repo-name

All links in custom pages (landing page, playground) use import.meta.env.BASE_URL to stay base-path-aware:

---
const base = import.meta.env.BASE_URL;
---
<a href={`${base}/getting-started/introduction/`}>Docs</a>

Starlight handles the base path automatically for its own docs pages and sidebar links.


Building Locally

To preview the production build locally:

Terminal window
# Build only the site
pnpm --filter site build
# Preview the built site
cd apps/site && pnpm preview

The preview server serves the site with the /calendar base path, matching the production deployment.


Manual Deployment

If you need to deploy without CI:

Terminal window
# Build
pnpm --filter site build
# The static site is in apps/site/dist/
ls apps/site/dist/

You can upload apps/site/dist/ to any static hosting provider (Netlify, Vercel, Cloudflare Pages, etc.). Just make sure to set the base path if your deployment isn’t at the root.


Custom Domain


Package Resolution

The docs site consumes the published npm packages — not the local workspace packages. This is achieved through two settings:

1. .npmrc (in apps/site/)

link-workspace-packages=false
prefer-workspace-packages=false

This tells pnpm to not link or prefer the local workspace versions of @thaparoyal/calendar-* packages.

2. npm: Specifier in package.json

{
"dependencies": {
"@thaparoyal/calendar-angular": "npm:@thaparoyal/calendar-angular@2.0.0",
"@thaparoyal/calendar-core": "npm:@thaparoyal/calendar-core@2.0.0",
"@thaparoyal/calendar-react": "npm:@thaparoyal/calendar-react@2.0.0",
"@thaparoyal/calendar-svelte": "npm:@thaparoyal/calendar-svelte@2.0.0",
"@thaparoyal/calendar-vanilla": "npm:@thaparoyal/calendar-vanilla@2.0.0",
"@thaparoyal/calendar-vue": "npm:@thaparoyal/calendar-vue@2.0.0"
}
}

The npm: prefix is a pnpm-supported alias that explicitly resolves from the npm registry. This ensures:

  • The docs site always uses the latest published version (currently 2.0.0)
  • Local changes to the workspace packages don’t break the docs site
  • The docs accurately reflect what users will experience when they npm install the packages

When to update: After publishing a new version to npm, bump the version in the npm: specifier (e.g., npm:@thaparoyal/calendar-core@2.1.0).


Custom Domain

To use a custom domain instead of thaparoyal.github.io/calendar:

  1. Go to Settings > Pages > Custom domain and enter your domain
  2. Update astro.config.mjs:
export default defineConfig({
site: 'https://your-domain.com',
base: '/', // root path with custom domain
});
  1. Update import.meta.env.BASE_URL references — with base: '/', the base URL becomes / so links work without a prefix.

Troubleshooting

Build fails with “Cannot find module ‘@thaparoyal/calendar-core‘“

The site consumes published npm packages. Ensure dependencies are installed before building:

Terminal window
pnpm install
pnpm --filter site build

Pages deploy shows 404

  • Verify Settings > Pages > Source is set to “GitHub Actions” (not “Deploy from a branch”)
  • Check that the workflow completed successfully in the Actions tab
  • Make sure base: '/calendar' matches your repository name

Sitemap errors during build

The site uses a no-op sitemap integration to work around an incompatibility between astro@4.16 and @astrojs/sitemap@3.x. This is already configured — if you see sitemap errors after upgrading Astro, check astro.config.mjs for the noopSitemap integration.