Skip to content

Documentation site

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.com and conversioniq.ai
  • Edit canonical docs only in docs/**.
  • Do not hand-edit src/content/docs/**.
  • src/content/docs/** is regenerated by npm run sync-docs.
  • docs/obsidian/** is intentionally excluded from the website build.
  • package.json
  • astro.config.mjs
  • tsconfig.json
  • .node-version
  • public/_headers
  • scripts/sync-docs.mjs
  • src/content.config.ts
Terminal window
npm install
Terminal window
npm run dev
Terminal window
npm run build

The site build uses scripts/sync-docs.mjs before dev and build.

That sync step:

  • mirrors docs/** into src/content/docs/**
  • converts README.md files into index.md routes
  • rewrites internal markdown links for website routing
  • adds generated frontmatter titles without mutating the source docs
  • creates the docs site homepage

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.0 or 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 site value for canonical metadata and sitemap generation

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

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

Add two Google identity providers in Cloudflare Zero Trust:

  1. Google Workspace for oneagency.com
  2. Google Workspace for conversioniq.ai

Each IdP requires its own Google OAuth client in the corresponding Google admin/console context.

Start with a small allowlist policy set:

  1. Allow users with email domain oneagency.com
  2. Allow users with email domain conversioniq.ai
  3. Optionally replace domain allowlists with specific emails or Google groups later

Keep an implicit deny for everyone else.

  • 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

When adding new documentation:

  1. Create or update the canonical markdown under docs/**
  2. Use relative markdown links to other docs when possible
  3. Commit and merge the change
  4. Cloudflare Pages rebuilds the site automatically

When adding a new top-level docs section:

  1. Add the folder under docs/
  2. Update the sidebar config in astro.config.mjs
  3. Verify the section builds and appears in navigation

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
  • 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/**
  • 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.0 or newer
  • Confirm the build command is npm run build
  • Confirm CIQ_DOCS_SITE_URL is present if you expect production metadata to use the final hostname
  • If Cloudflare logs show Astro rejecting Node 20.x, update the NODE_VERSION environment variable and retry the deployment