- Home
- API Enriched
- Native Starlight API Documentation
Native Starlight API Documentation
Date: 2026-05-27 Status: Draft
Problem
Section titled “Problem”The API reference documentation at /api-reference/ uses iframe-embedded Scalar viewers to render OpenAPI specs. This approach has three issues:
- SEO — Content inside iframes is not indexed by search engines
- UX — The iframe creates a visual boundary that breaks the Starlight theme experience
- Navigation — No deep linking to specific endpoints; no sidebar integration
Solution
Section titled “Solution”Replace iframe+Scalar rendering with the starlight-openapi Starlight plugin, which generates static .astro pages at build time from OpenAPI JSON specs. Pages inherit Starlight’s theme, search indexing, sidebar, and table of contents.
Architecture
Section titled “Architecture”Current flow
Section titled “Current flow”Python pipeline → enriched JSON → Scalar HTML viewer → iframe in MDX → Starlight pageTarget flow
Section titled “Target flow”Python pipeline → enriched JSON → starlight-openapi → native .astro pagesRepo responsibilities
Section titled “Repo responsibilities”api-specs-enriched (this repo):
- Python pipeline continues generating enriched JSON specs at
docs/specifications/api/{domain}.json generate_api_viewer.pyis simplified:- Removes
generate_viewer_html()— no more Scalar HTML files - Removes
generate_domain_mdx()— no more iframe wrapper pages - Keeps
generate_catalog_mdx()— card catalog stays, hrefs updated to plugin routes
- Removes
docs/specifications/api/viewer/directory and its HTML files are deleteddocs/api-reference/{domain}.mdxiframe wrappers are deleted (replaced by plugin-generated pages)
docs-theme (sibling repo):
- Add
starlight-openapitopackage.json - Configure in
astro.config.mjsto read specs dynamically fromindex.json - Each domain gets its own route under
/api-reference/{domain}/
docs-builder: No direct changes — runs npm install during build, which pulls in the plugin from docs-theme’s package.json automatically.
Plugin configuration
Section titled “Plugin configuration”The plugin reads each domain’s enriched JSON spec and generates:
- Overview page per domain — lists all endpoints grouped by tag
- Operation pages — one per endpoint with parameters, request/response schemas, expandable tabbed panels
- Schema pages — dedicated pages for complex types with anchored sections and searchable selector
All pages inherit Starlight theme, dark mode, search indexing, and sidebar navigation.
Dynamic config generation
Section titled “Dynamic config generation”Since there are 38 domains, the astro.config.mjs entry generates the plugin config array dynamically by reading index.json at config load time rather than hardcoding 38 entries:
import { readFileSync } from 'fs';import { starlightOpenAPINavigator } from 'starlight-openapi';
const index = JSON.parse(readFileSync('./docs/specifications/api/index.json', 'utf-8'));const schemas = index.specifications.map(spec => ({ base: `api-reference/${spec.domain}`, schema: `./docs/specifications/api/${spec.domain}.json`, sidebar: { label: spec.title, collapsed: true, }}));
export default defineConfig({ integrations: [ starlight({ plugins: [starlightOpenAPINavigator(schemas)], }), ],});Card catalog
Section titled “Card catalog”The existing docs/api-reference/index.mdx card catalog page stays. Cards link to plugin-generated domain overview pages. The generate_catalog_mdx() function in generate_api_viewer.py continues generating this page, with href values updated if the plugin uses a different route pattern.
Changes to generate_api_viewer.py
Section titled “Changes to generate_api_viewer.py”| Function | Action |
|---|---|
generate_viewer_html() | Remove |
generate_domain_mdx() | Remove |
generate_catalog_mdx() | Keep — update href to match plugin routes |
main() | Simplify — stop generating HTML/MDX per domain, only generate catalog |
| Stale file cleanup | Update to not clean plugin-generated files |
Files removed
Section titled “Files removed”docs/specifications/api/viewer/*.html— 38 Scalar HTML viewersdocs/api-reference/{domain}.mdx— 38 iframe wrapper pages- Scalar CDN reference (
SCALAR_CDN_VERSION,SCALAR_CDN_URLconstants)
Build time considerations
Section titled “Build time considerations”- 38 specs totaling ~77MB of enriched OpenAPI JSON
- ~1,200 total API paths across all domains
- Plugin generates static pages at build time — initial build may take longer
- Subsequent builds benefit from Astro’s incremental build cache
Mitigation: Start with one small spec (vpm_and_node_management.json, 1 path, 17KB) to validate, then scale to the full set.
Verification plan
Section titled “Verification plan”- Proof of concept (docs-theme): Install plugin, configure with one small spec, confirm native page generation
- Scale test: Add a large spec (
sites.json— 133 paths, 1015 schemas) and verify build succeeds in reasonable time - Full integration: Configure all 38 specs, verify card catalog links resolve correctly
- Search verification: Confirm endpoint content appears in Starlight’s search index
- Theme consistency: Verify pages match Starlight’s dark/light mode, typography, and spacing
- Deep linking: Confirm individual operations have stable, bookmarkable URLs
Open questions (resolved during proof-of-concept)
Section titled “Open questions (resolved during proof-of-concept)”- The
astro.config.mjsconfig example is illustrative — exact plugin API (import names, config shape) will be determined during the docs-theme proof-of-concept step - Whether the plugin supports “one page per domain” mode or only “one page per operation” — if it only does per-operation, the domain overview page becomes the entry point from the card catalog and individual operations are sub-pages
- Build time with 38 specs (~77MB total) — may require tuning or a pre-processing step if builds exceed acceptable time
Implementation order
Section titled “Implementation order”- Add
starlight-openapito docs-theme (PR to docs-theme) - Validate with small spec, then full spec set
- Simplify
generate_api_viewer.pyin this repo (remove iframe/HTML generation) - Remove stale files (viewer HTML, domain MDX wrappers)
- Update card catalog hrefs if plugin route pattern differs
- End-to-end test on GitHub Pages deployment