Skip to content

Help center (Starlight)

The user-facing help center lives in docs/user/ and renders per-product guides plus the VPAT Parser API reference. It’s built with Starlight (Astro); the API reference is rendered by starlight-openapi from docs/api/vpat-parse-openapi.yaml.

Migrated off Docusaurus/Redoc β†’ Starlight on 2026-09-11. Redoc’s API reference produced WCAG AA violations that could only be fixed inside Redoc’s source (keyboard traps, aria-hidden focusables, clipped-at-200%-zoom tables β€” see docs/admin/help-site-redoc-a11y-debt.md). starlight-openapi renders the same spec as native semantic markup, so the whole site β€” including the API reference β€” passes the pa11y WCAG2AA gate (49/49 pages) with no override CSS. Content is authored in Markdown as before; admonitions (:::note) carried over unchanged.

Where it’s served

It has its own hostname:

https://help.gevell.com β†’ help center home
https://help.gevell.com/pdf/ β†’ Gevell PDF section
https://help.gevell.com/api/vpat-parse β†’ API reference

docs/user/astro.config.mjs sets site: https://help.gevell.com. The site is served by a dedicated assets-only Cloudflare Worker defined in docs/user/wrangler.toml (Workers Static Assets over ./dist) on the help.gevell.com custom domain.

Old location (redirected)

The help center used to be mounted at acr.gevell.com/docs, served by the apps/vpat worker. That worker now 301-redirects \/docs and \/docs/* to help.gevell.com, preserving the sub-path. The pre-reorg PDF guides are additionally covered by the redirects map in astro.config.mjs β€” the three that moved under /pdf/ (e.g. /convert-by-email β†’ /pdf/convert-by-email) and the two retired ones (canvas-lti-setup, custom-gpt), which fall back to the /pdf/ hub rather than 404.

PDF app docs (pdf.gevell.com/docs). The converter’s own public help β€” 17 guides in apps/web/content/guides/*.md plus apps/web/content/faqs.md β€” was folded into this help center (Phase 2). The guides now live under /pdf/* (usage), /account-billing/* (account, billing, refunds), and /getting-started/getting-support; the FAQs became /pdf/faq; the four automation guides (MCP server, Claude Desktop skill, CI/CD, shared folder) were consolidated into /pdf/integrations. apps/web/public/_redirects 301s every old /docs/* URL to its new help-center home (per-slug rules first, a /docs/* catch-all to /pdf/getting-started/ last). /docs/internal stays served locally (admin-gated) via a passthrough rule placed before the catch-all. The Canvas LTI and ChatGPT Custom GPT guides were intentionally not migrated; their old URLs redirect to the /pdf/ hub. The apps/web/content/guides sources remain in the app repo (now shadowed by the redirects) and can be pruned in a follow-up.

Structure

Top-level sidebar sections are generated from the product registry (packages/accessible-org-ui/src/products.ts) so the help center can’t drift product-incomplete:

  • src/content/docs/getting-started/ β€” landing + cross-product intro (first); its index.md carries slug: /-equivalent placement as the site root
  • src/content/docs/<product-id>/ β€” one section per registry product, in order
  • src/content/docs/account-billing/ β€” sign-in, credits, plans, workshops (last)

scripts/sync-sidebar.mjs writes src/sidebar.generated.mjs (imported by astro.config.mjs) β€” one Starlight sidebar group per section, label = canonical product name, order = registry order, with the non-product sections SSO (90) and Guides (99) interleaved. npm run build runs it first; npm run check:sidebar (CI) fails if a registry product has no docs section or the generated sidebar has drifted from the registry. The pure logic is unit-tested in scripts/sync-sidebar.test.mjs (npm test).

Build & deploy

Terminal window
cd docs/user
npm ci # note: .npmrc pins legacy-peer-deps (vitest 4 + Astro's Vite)
npm run deploy # sync:sidebar β†’ astro build β†’ wrangler deploy

The docs build is validated in CI by .github/workflows/docs.yml on any PR touching docs/user/** or docs/api/**: unit tests, the check:sidebar coverage check, the Astro build, and a pa11y WCAG2AA scan of every built page (served via astro preview, driven off dist/sitemap-0.xml).

A post-build integration, src/integrations/dedupe-ids.mjs, renames any duplicate element id in the output (astro:build:done). It exists because starlight-openapi emits two <h4 id="headers"> per operation page (request + response Headers); without it the pa11y duplicate-id rule fails.

Adding a new product’s help

  1. Add the product to packages/accessible-org-ui/src/products.ts.
  2. Create docs/user/src/content/docs/<id>/index.md (a short, accurate overview is enough).
  3. npm run sync:sidebar to regenerate src/sidebar.generated.mjs.

Skipping step 2 makes check:sidebar fail in CI β€” by design.

To keep a registry product OUT of the help center (it stays in the footer / cross-promo but gets no help section), add its id to EXCLUDED_FROM_HELP in scripts/sync-sidebar.mjs and delete its src/content/docs/<id>/ directory. The check then stops requiring a section for it β€” and fails if a leftover one reappears.

Screenshots (visual walkthroughs)

PDF-section pages embed screenshots from docs/user/public/img/pdf/, referenced via <figure> + <img>. Light/dark pairs use two <img> tags with Starlight’s dark:sl-hidden (the light image) and light:sl-hidden (the dark image) utility classes β€” both carry the same alt (the display:none one is ignored by assistive tech). Single-variant shots use one plain <img>. Images live in public/ so they publish at /img/pdf/<file>; alt text lives in the referencing .md.

These are copied from the PDF app’s curated set at apps/web/public/docs/screenshots/ (hand-captured β€” there is no automated generator yet). To refresh after a UI change: recapture in apps/web (light and dark for a themed pair), copy the file(s) into public/img/pdf/ keeping the same names, and confirm the alt text still matches. npm run build plus the pa11y CI gate (fails on a missing alt) catch broken or unlabeled images.

File(s)Used onThemed?
dashboard-empty.png (+ -dark)pdf/getting-started (upload area)yes
dashboard-row-expanded.png (+ -dark)pdf/getting-started, pdf/downloadingyes
compare.pngpdf/downloading (Compare view)no
documentsettings.jpgpdf/downloading (Header & Footer)no
documentstyling.jpgpdf/downloading (Styling)no

The sign-in screenshot was intentionally not used β€” the captured version showed retired β€œPDF Converter” branding and a stale β€œSend Magic Link” flow. Recapture on-brand (Gevell PDF, one-time email code) before adding one. Other products (OrgChart, Audit) have no help-center screenshots yet.