Documentation site
Purpose
Section titled “Purpose”This document defines how the private documentation website is built, deployed, protected, and maintained.
The GitHub repo remains the source of truth. The website is the delivery surface for teammates who should consume the docs in a browser instead of directly in GitHub.
- Static site generator: Astro + Starlight
- Source content:
docs/** - Generated site content:
src/content/docs/** - Hosting: Cloudflare Pages
- Access control: Cloudflare Access
- Identity providers: Google Workspace for
oneagency.comandconversioniq.ai
Source-of-truth rule
Section titled “Source-of-truth rule”- Edit canonical docs only in
docs/**. - Do not hand-edit
src/content/docs/**. src/content/docs/**is regenerated bynpm run sync-docs.docs/obsidian/**is intentionally excluded from the website build.
Repo-owned site files
Section titled “Repo-owned site files”package.jsonastro.config.mjstsconfig.json.node-versionpublic/_headersscripts/sync-docs.mjssrc/content.config.ts
Local development
Section titled “Local development”Install
Section titled “Install”npm installRun locally
Section titled “Run locally”npm run devBuild locally
Section titled “Build locally”npm run buildBuild behavior
Section titled “Build behavior”The site build uses scripts/sync-docs.mjs before dev and build.
That sync step:
- mirrors
docs/**intosrc/content/docs/** - converts
README.mdfiles intoindex.mdroutes - rewrites internal markdown links for website routing
- adds generated frontmatter titles without mutating the source docs
- creates the docs site homepage
Cloudflare Pages configuration
Section titled “Cloudflare Pages configuration”Create one Cloudflare Pages project connected to the private ciq-mvp2-docs GitHub repository.
Recommended settings:
- Production branch:
main - Build command:
npm run build - Build output directory:
dist - Node version:
22.12.0or newer Node 22 LTS - Framework preset:
Astro
Recommended environment variables:
CIQ_DOCS_SITE_URL- Set this to the final production URL, for example
https://docs.conversioniq.ai - This becomes the Astro
sitevalue for canonical metadata and sitemap generation
- Set this to the final production URL, for example
Preview deployment guidance:
- Leave preview deployments enabled for pull requests if the docs team wants review URLs
- Protect preview URLs with Cloudflare Access as well if they contain sensitive internal material
Cloudflare Access configuration
Section titled “Cloudflare Access configuration”Protect the docs hostname with one Cloudflare Access application.
Recommended model:
- Application type: self-hosted
- Application domain: the Pages project domain or your custom docs domain
- Session duration: start with
24 hours - Policy baseline: default deny unless an allow policy matches
Identity providers
Section titled “Identity providers”Add two Google identity providers in Cloudflare Zero Trust:
- Google Workspace for
oneagency.com - Google Workspace for
conversioniq.ai
Each IdP requires its own Google OAuth client in the corresponding Google admin/console context.
Access policies
Section titled “Access policies”Start with a small allowlist policy set:
- Allow users with email domain
oneagency.com - Allow users with email domain
conversioniq.ai - Optionally replace domain allowlists with specific emails or Google groups later
Keep an implicit deny for everyone else.
Operating model
Section titled “Operating model”- Writers and product/engineering maintain content in
docs/** - GitHub remains the review and version-control system
- Cloudflare Pages rebuilds the website from
main - Cloudflare Access is the auth boundary for the website
- The website should not be treated as an editable source
Updating the site
Section titled “Updating the site”When adding new documentation:
- Create or update the canonical markdown under
docs/** - Use relative markdown links to other docs when possible
- Commit and merge the change
- Cloudflare Pages rebuilds the site automatically
When adding a new top-level docs section:
- Add the folder under
docs/ - Update the sidebar config in
astro.config.mjs - Verify the section builds and appears in navigation
Troubleshooting
Section titled “Troubleshooting”A page exists in GitHub but not on the website
Section titled “A page exists in GitHub but not on the website”- Run
npm run sync-docs - Run
npm run build - Check whether the doc lives under
docs/obsidian/**or another intentionally excluded path - Confirm the new top-level folder is included in the Starlight sidebar config
Internal links are broken
Section titled “Internal links are broken”- Prefer standard markdown links, not raw filesystem references in prose
- Rebuild locally to verify the rewritten output
- Confirm the target file still exists under
docs/**
The homepage was edited and changes disappeared
Section titled “The homepage was edited and changes disappeared”- The homepage is generated by
scripts/sync-docs.mjs - Make homepage changes in the generator script, not in
src/content/docs/**
Users cannot log in
Section titled “Users cannot log in”- Verify both Google identity providers are active in Cloudflare Zero Trust
- Verify the Access application includes the correct hostname
- Verify the allow policies match the intended domains, users, or groups
- Verify the Google OAuth redirect URIs match the Cloudflare-generated values
The build passes locally but Cloudflare fails
Section titled “The build passes locally but Cloudflare fails”- Confirm Cloudflare is using Node
22.12.0or newer - Confirm the build command is
npm run build - Confirm
CIQ_DOCS_SITE_URLis present if you expect production metadata to use the final hostname - If Cloudflare logs show Astro rejecting Node
20.x, update theNODE_VERSIONenvironment variable and retry the deployment