Deployment Guide
This guide covers deploying the SF CTA Study Hub to Cloudflare Pages with automatic deploys via GitHub Actions.
CI/CD is pre-configured
The GitHub Actions workflow at .github/workflows/deploy.yml is already committed. You only need to complete the one-time Cloudflare setup below.
Prerequisites
- GitHub repository connected to this project (already done if you’re reading this)
- Cloudflare account — free tier is sufficient (cloudflare.com)
Step 1: Create the Cloudflare Pages Project
- Log in to Cloudflare Dashboard
- Go to Workers & Pages → Create application → Pages → Connect to Git
- Authorize Cloudflare to access your GitHub account
- Select the
sf-cta-studyrepository - Configure the build:
- Framework preset: Astro
- Build command:
npm run build - Build output directory:
dist - Root directory:
app
- Click Save and Deploy — this triggers the first deploy
Root directory matters
Set Root directory to app in the Cloudflare Pages UI. This tells Cloudflare Pages that the Astro project lives in app/, not the repo root.
Step 2: Add GitHub Secrets
The GitHub Actions workflow requires two secrets. Add them at: GitHub repo → Settings → Secrets and variables → Actions → New repository secret
| Secret name | Where to find it |
|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare Dashboard → My Profile → API Tokens → Create Token → use “Edit Cloudflare Workers” template |
CLOUDFLARE_ACCOUNT_ID | Cloudflare Dashboard → Workers & Pages → right sidebar shows Account ID |
API Token scope
When creating the API token, grant it Cloudflare Pages: Edit permission scoped to your account. The “Edit Cloudflare Workers” template includes this scope.
Step 3: Verify CI/CD is Working
- Push any commit to the
mainbranch - Go to GitHub repo → Actions — you should see the “Deploy to Cloudflare Pages” workflow running
- Once complete, your site is live at
https://sf-cta-study.pages.dev(or your custom subdomain)
Pull requests automatically get a preview deployment URL posted as a GitHub check.
Step 4: Update the Site URL (Optional)
After you know your actual Cloudflare Pages subdomain, update app/astro.config.mjs:
export default defineConfig({ site: 'https://YOUR-PROJECT.pages.dev', // ...});This improves sitemap generation and canonical URLs.
Custom Domain (Optional)
- In Cloudflare Dashboard → Workers & Pages → your project → Custom domains
- Click Set up a custom domain and enter your domain
- Follow the DNS instructions (if your domain is already on Cloudflare, this is automatic)
Custom domain requirement
Your domain must use Cloudflare’s nameservers (or have a CNAME record pointing to Cloudflare Pages). Cloudflare provides SSL automatically.
Build Configuration Reference
| Setting | Value |
|---|---|
| Node version | 20 (LTS) |
| Build command | npm run build |
| Output directory | app/dist |
| Root directory | app |
| Framework | Astro (static output) |
Troubleshooting
Build fails with “Cannot find module”
Check that npm ci ran successfully. The workflow uses cache-dependency-path: app/package-lock.json — ensure package-lock.json is committed.
Sitemap warning about missing site config
Update site: in app/astro.config.mjs to your actual Cloudflare Pages URL (see Step 4 above).
Graph edges not visible on deployed site
This is expected in dev mode. The starlight-site-graph plugin builds edges from compiled HTML, so they only appear in production builds — which is what Cloudflare Pages deploys.