Guide for AI agents and contributors working on the openinfer documentation site.
Static documentation site for openinfer, built with Astro and Starlight, deployed to Cloudflare Workers as static assets.
- Production URL: https://open-infer.org
- Node: 22+
- Package manager: npm
npm install
npm run dev # http://localhost:4321If routes 404 unexpectedly after config or content changes, clear the Astro cache and restart:
rm -rf .astro && npm run devsrc/
content/docs/ # All doc pages (Markdown / MDX)
styles/custom.css # Site-wide theme overrides (light + dark)
assets/ # Logo and other bundled assets
content.config.ts # Starlight content collection
public/ # Static files served as-is (images, favicon)
tests/
routes.mjs # Canonical list of public routes (shared by tests)
static.test.mjs # Post-build static output checks
pages.spec.mjs # Playwright E2E smoke tests
astro.config.mjs # Astro + Starlight config (sidebar, SEO, code blocks)
wrangler.jsonc # Cloudflare Workers static asset deploy
All pages live under src/content/docs/:
| Path | Purpose |
|---|---|
index.mdx |
Homepage |
getting-started.md |
Build and first request |
blog/*.md |
Blog posts |
models/*.md |
Per-model benchmark and usage pages |
Benchmark images go in public/ (e.g. public/blog/openinfer-010/qps.png, public/models/qwen3-4b/perf.png) and are referenced with absolute paths in Markdown:
- Create the file under
src/content/docs/. - Add a sidebar entry in
astro.config.mjs— uselink:(notslug:) with a trailing slash, e.g.link: '/models/qwen3-8b/'. - Update
tests/routes.mjs:- Add the URL to
SITE_ROUTES. - Add the corresponding
dist/HTML path toDIST_PAGES.
- Add the URL to
- Run the full test suite (see below).
The site uses trailingSlash: 'always'. Internal links and sidebar entries must include the trailing slash.
- Doc-first, minimal — inspired by uv docs: plain typography, flat borders, no marketing chrome.
- Fonts: Roboto + Roboto Mono (loaded in
astro.config.mjshead). - Code blocks: plain by default (no terminal frame). The
openinfer-plain-codeExpressive Code plugin setsframe: 'none'unlessframe=is explicitly set in a fence meta string. - Theme tweaks belong in
src/styles/custom.css. Avoid one-off inline styles in content files. - Logo: configured as a string path in
astro.config.mjs(logo: { src: './src/assets/logo.png', ... }). Do not pass an importedImageMetadataobject.
npm run build # output → dist/
npm run preview # serve dist/ at http://localhost:4321Tests are split into static (filesystem) and E2E (browser) layers. The default test script runs all of them in order.
npm test # build + static + e2e
npm run test:static # Node built-in test runner only (requires prior build)
npm run test:e2e # Playwright only (starts preview server automatically)Run after npm run build. They verify:
- Every expected HTML file exists under
dist/. sitemap-0.xmlincludes all routes fromSITE_ROUTES.404.htmlis the Starlight-styled page, not a bare error.
Playwright starts astro preview on port 4321 (see playwright.config.mjs). They verify:
- Each route in
SITE_ROUTESreturns HTTP 200 and renders a real page (not the 404 content). - Unknown paths return 404 with the expected message.
- Sidebar navigation works (Getting Started link).
First-time Playwright setup:
npx playwright install chromiumWhen adding or removing pages, always update tests/routes.mjs — both test files import from it.
Production deploys via Cloudflare Workers static assets:
npm run build
npx wrangler deploywrangler.jsonc sets html_handling: "auto-trailing-slash" so paths without a trailing slash still resolve in production.
For CI/CD, connect the repo in the Cloudflare dashboard with build command npm run build.
| Issue | Cause | Fix |
|---|---|---|
| All routes 404 in dev | Stale .astro cache or old dev server |
rm -rf .astro, restart npm run dev |
| Sidebar build error: slug does not exist | Using slug: in sidebar |
Use link: '/path/' instead |
getImage / logo path error |
Hero image.file or imported logo object |
Use string path in logo.src; avoid hero image imports in frontmatter |
| New page passes locally but fails CI | Route not in tests/routes.mjs |
Add URL + dist path, rerun npm test |
| E2E port conflict | Another process on 4321 | Stop other dev/preview servers before npm run test:e2e |
- Do not switch back to
template: splashor heavy marketing layouts on the homepage — the site is doc-first. - Do not add interactive chart libraries for benchmark tables; use summary images plus Markdown tables.
- Do not commit secrets (
.env, credentials). - Do not skip git hooks or force-push to
mainunless explicitly requested.
- Human-oriented overview: README.md
- Choosing blog titles / topics: .claude/skills/seo-keyword-eval/SKILL.md — measure keyword demand and competition before writing
- Starlight docs: https://starlight.astro.build/
- Astro content collections: https://docs.astro.build/en/guides/content-collections/