Skip to content

ApiDoc: add a layout switch and optionally enable side bar - #98

Merged
cmil merged 2 commits into
mainfrom
api-doc-layout-switch
Oct 11, 2026
Merged

cmil merged 2 commits into
mainfrom
api-doc-layout-switch

Conversation

@cmil

@cmil cmil commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Scalar's classic layout never updates the URL hash for individual operations, so it is not obvious to readers how to link to a specific endpoint. The modern layout does. This PR lets readers switch between the two layouts, and hides Scalar's promotional sidebar buttons.

Layout switch

<ApiDoc
  url="/api/v1/openapi.yaml"
  layoutSwitch={{ modern: { showSidebar: true } }}
  configuration={{ layout: 'modern' }}
/>
  • layoutSwitch (true or an options object) shows a Modern / Classic switch in the top right corner.
    • The choice is saved in localStorage under dracor.apiDocLayout by default. storageKey changes the key.
    • configuration.layout sets the layout used until the reader picks one.
    • Switching layouts rebuilds the Scalar view from scratch rather than changing the running instance.
  • layoutSwitch.modern / layoutSwitch.classic apply extra configuration only while that layout is active. Each is merged on top of configuration, and its customCss is added rather than replacing the base CSS.
    • The main use is a sidebar in the modern layout only. On wide screens the modern layout has no search button outside the sidebar.
  • Narrow screens: below Scalar's lg breakpoint, the modern layout shows a sticky header. To keep it clear of the switch:
    • its search button is capped at the classic layout's width (max-w-64);
    • the sidebar breadcrumb is truncated;
    • the header gets some space below its bottom border.

The sidebar is still off by default (showSidebar: false).

Scalar promo buttons

  • New defaults: mcp: { disabled: true } and hideClientButton: true. These remove the "Generate MCP" button (shown on localhost) and the "Open API Client" button (shown elsewhere) from the sidebar footer. The per-endpoint "Test Request" buttons have their own option and are not affected.
  • New hidePoweredBy prop: hides the "Powered by Scalar" link with CSS, since Scalar has no option for it. It is off by default.

Notes

  • Depends on Scalar internals: the narrow-header and powered-by rules use selectors from Scalar's DOM (.t-doc__header, .darklight-reference). They may need updating when Scalar changes its markup.
  • Version bump not included: package.json is still on 1.9.0. Since this only adds props, it can go out as 1.10.0.

Testing

  • Unit tests cover the switch (default, switching, saving, restoring, bad saved value, custom key), per-layout configuration, the sidebar default, the hidden buttons, and the hidePoweredBy CSS. All 16 ApiDoc tests pass, as do pnpm lint and pnpm build.
  • New LayoutSwitch Storybook story.
  • Tested in dracor-frontend (/doc/api) with a packed tarball.

🤖 Generated with Claude Code

Scalar's classic layout never updates the URL hash for individual
operations, so there is no way to link to an endpoint; the modern
layout does. Let readers pick between the two:

- New `layoutSwitch` prop renders a Modern / Classic switch in the top
  right corner and remembers the choice in localStorage (key
  `dracor.apiDocLayout`, configurable via `storageKey`).
  `configuration.layout` is the starting layout. Switching remounts
  Scalar rather than reconfiguring the live instance.
- `layoutSwitch.configurations` takes per-layout configuration merged
  on top of `configuration` (`customCss` is appended), e.g.
  `{ modern: { showSidebar: true } }` -- on wide screens the modern
  layout only offers search inside the sidebar.
- Below Scalar's `lg` breakpoint the modern layout's sticky header is
  kept clear of the switch: the search button is capped at the classic
  width, a sidebar breadcrumb is truncated, and the header gets some
  space below its border.

Also disable the "Generate MCP" (`mcp.disabled`) and "Open API Client"
(`hideClientButton`) sidebar buttons by default, and add a
`hidePoweredBy` prop that hides the "Powered by Scalar" link via CSS,
since Scalar has no option for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.33333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.41%. Comparing base (952dc90) to head (dc41140).

Files with missing lines Patch % Lines
src/components/ApiDoc/ApiDoc.tsx 93.33% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #98      +/-   ##
==========================================
- Coverage   95.62%   95.41%   -0.21%     
==========================================
  Files          34       34              
  Lines         320      349      +29     
  Branches      109      122      +13     
==========================================
+ Hits          306      333      +27     
- Misses          3        4       +1     
- Partials       11       12       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cmil cmil changed the title ApiDoc: add a layout switch and hide Scalar's promo buttons ApiDoc: add a layout switch and optionally enable side bar Oct 11, 2026
`layoutSwitch={{ modern: { showSidebar: true } }}` reads better than
nesting the layouts under a `configurations` key. The layout names and
the switch's own options (`storageKey`) don't overlap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cmil
cmil merged commit b8dadd2 into main Oct 11, 2026
3 of 5 checks passed
@cmil
cmil deleted the api-doc-layout-switch branch October 11, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant