Capsa

Documentation
API Reference
Changelog
guides/API Reference

API Reference

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.

Add your spec

  1. Drop your OpenAPI document at public/openapi/v1.yaml (replacing the example spec).
  2. That's it — visit /docs/api.

The API Reference tab in the top bar links there; it's defined in src/navigation.ts:

TypeScript
{ tab: 'API Reference', icon: 'code', href: '/docs/api' }

Versions

Register each version in src/apiVersions.ts:

TypeScript
export const apiVersions: ApiVersion[] = [
  { label: 'v1.0', url: '/openapi/v1.yaml' },
  // { label: 'v2.0', url: '/openapi/v2.yaml' },
];

With a single entry there's no switcher. Add a second and a version dropdown appears on the reference page automatically.

"Try it"

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.

Customizing the reference

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.

Dark mode (wired for you)

Scalar keeps its own dark-mode state in localStorage, which drifts out of sync with the site. Capsa forces it from the app theme:

TSX
const { isDark } = useThemeController();
// ...
<ApiReferenceReact
  key={version.url} // NOT keyed on isDarkthat would remount and flash
  configuration={{
    url: version.url,
    forceDarkModeState: isDark ? 'dark' : 'light',
    hideDarkModeToggle: true,
  }}
/>

Hiding chrome

OptionHides
showToolbar: 'never'The Developer Tools / Configure / Share / Deploy toolbar (Capsa sets this)
showSidebar: falseScalar's whole left sidebar
hideSearch: trueScalar's search bar
hideModels: trueThe schema/models section
hideDownloadButton: true"Download OpenAPI spec"
hideTestRequestButton: trueThe "Test Request" buttons
hideClientButton: trueThe 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.

Theming (wired for you)

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:

TSX
const theme = useTheme();
const tok = (k: string) => theme[k]?.get?.() as string | undefined;

const customCss = `
  .light-mode, .dark-mode {
    --scalar-color-1: ${tok('color12')};
    --scalar-color-2: ${tok('color11')};
    --scalar-color-3: ${tok('color10')};
    --scalar-color-accent: ${tok('accent')};
    --scalar-background-1: ${tok('background')};
    --scalar-background-2: ${tok('color2')};
    --scalar-background-3: ${tok('color3')};
    --scalar-border-color: ${tok('borderColor')};
  }
`;

<ApiReferenceReact key={version.url} configuration={{ url: version.url, customCss, /* ... */ }} />

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.

Keep the spec in sync

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:

Bash
OPENAPI_SOURCE=../api/openapi.yaml pnpm dev

A common pattern: the API repo commits its spec to this repo (or triggers a rebuild) on change, so the reference is always current.

Inline references in prose

Use the <ApiMethod> component in any guide to link to an endpoint:

POST

/v1/widgets

Create a widget

Was this page helpful?
© Capsa