Capsa renders a full interactive API reference from an OpenAPI document using Scalar. It lives at /docs/api and is lazy-loaded, so it stays out of the main bundle until visited.
public/openapi/v1.yaml
(replacing the example spec)./docs/api.The API Reference tab in the top bar links there; it's defined in
src/navigation.ts:
Register each version in src/apiVersions.ts:
With a single entry there's no switcher. Add a second and a version dropdown appears on the reference page automatically.
Scalar's built-in API client is enabled — readers can execute requests with a
key they paste (Scalar stores it locally). To point it at a live sandbox, add a
servers entry to your spec and enable CORS for the docs origin on that server.
Everything below is configured in src/pages/ApiReference.tsx, in the
configuration object passed to <ApiReferenceReact>. <ApiReferenceReact> is
reactive — it applies config changes in place via updateConfiguration, so
theme changes update without a remount (no flash). Only key it on the spec
version, never on the theme.
Scalar keeps its own dark-mode state in localStorage, which drifts out of
sync with the site. Capsa forces it from the app theme:
| Option | Hides |
|---|---|
showToolbar: 'never' | The Developer Tools / Configure / Share / Deploy toolbar (Capsa sets this) |
showSidebar: false | Scalar's whole left sidebar |
hideSearch: true | Scalar's search bar |
hideModels: true | The schema/models section |
hideDownloadButton: true | "Download OpenAPI spec" |
hideTestRequestButton: true | The "Test Request" buttons |
hideClientButton: true | The API-client button |
layout: 'classic' | Switches from the default 'modern' layout |
showToolbar and showDeveloperTools take 'localhost' | 'always' | 'never' —
they default to showing on localhost, so set 'never' to hide them everywhere.
Scalar is a self-contained component and can't take Tamagui props directly —
it themes through its own --scalar-* CSS variables. Capsa bridges them: it
resolves your Tamagui tokens with useTheme() and feeds them in through
customCss, recomputed on every theme change:
Note
This is a bridge, not real integration — you're copying resolved token values
into Scalar's variables, layered on top of Scalar's default theme. Map more
--scalar-* variables (buttons, method colors, sidebar) to go further; anything
you leave out keeps Scalar's default. For full control instead, set
theme: 'none' and define every variable yourself.
If your spec is generated by an API repo, you don't have to copy it by hand. The
included scripts/sync-openapi.mjs copies a spec into public/openapi/v1.yaml
when OPENAPI_SOURCE is set — wire it into your build or a CI step:
A common pattern: the API repo commits its spec to this repo (or triggers a rebuild) on change, so the reference is always current.
Use the <ApiMethod> component in any guide to link to an endpoint:
POST
/v1/widgets
Create a widget