docs
The ClassroomIO documentation site, built with Blume (Astro + Vite). Served at classroomio.com/docs.
Requirements
Node >= 22.12 (see .nvmrc). The rest of the monorepo is still on Node 20, so switch versions
before working here:
nvm use
Develop
pnpm dev # fetches the OpenAPI spec, then starts the dev server
pnpm build # builds to dist/, then packages to build/ for the worker
pnpm preview # builds, then serves through the worker on :4173
pnpm validate # checks internal links and heading anchors
Use pnpm preview before deploying anything that touches routing. pnpm dev serves pages straight
from Blume and never sees Cloudflare's asset server, so it cannot show you the _redirects rules, the
404 page, or the trailing-slash handling — only preview runs the site the way production does.
How it's served
The site is fully static. classroomio.com/docs/* is proxied by the marketing site
(apps/website/src/hooks.server.ts) to the cio-docs worker, which serves the build as static
assets — there is no server-side rendering.
Two things follow from being mounted at /docs:
- Links are authored root-relative (
/course-enrollment). Blume prepends the base at build time. - Images must be written with the base (
/docs/certificates-rules.webp). Blume deliberately does not rebase images, so an unprefixed path would 404.
scripts/package-assets.mjs moves dist/ under build/docs/ to match the served path and writes the
_redirects file (/docs → /docs/home, and the legacy /docs/how-to-guides/* → /docs/*).
API reference
/docs/api is the Scalar API reference, rendered at build time (the old /docs/api/reference path
301s here). scripts/fetch-openapi.mjs pulls the spec from R2 and injects the bearer auth scheme via
@cio/utils/openapi/public-api. Because it is static, a new spec reaches the site only on a rebuild —
.github/workflows/upload-openapi-spec.yml triggers one automatically.