Keep the docs sidebar mounted across navigation
Draft
MA
3d ago+215+215+012345678901234567890123456789-199-199-012345678901234567890123456789
Problem
Every docs page built its own copy of the desktop sidebar inside its route component. Each client-side navigation therefore unmounted it and mounted a fresh one, which:
- reset the sidebar's scroll position (most noticeable when switching between package changelogs under API Reference)
- collapsed any groups the reader had expanded
- re-rendered the whole sidebar tree on every page change
Change
- One persistent sidebar. The desktop sidebar is registered once as an app wrap (
extra_app_wraps), outside the page routes, so navigation no longer unmounts it. - Reads the URL in the browser. The sidebar gets the current path from react-router's
useLocationinstead of from values computed per page in Python (calculate_index/normalize_urlare removed). A group is open when the current route is one of its descendant pages. - Spacer slot. Each docpage reserves the column with an empty
.docs-sidebar-slot. The shared sidebar is fixed-positioned over it, and a CSS:hasrule hides it on pages without a slot (404, redirects). - Scrolls only when needed. If the active link is off-screen after navigating (prev/next, in-content links), the sidebar scrolls just enough to show it. This replaces the old
on_mountscript, which added a newpopstatelistener on every mount. - Truncated long labels (
reflex-site-shared): a selected leaf such asreflex-components-react-playerused to wrap past its fixed-height highlight. Leaf labels now truncate with an ellipsis, and the full name shows on hover.
Behavior notes
- A group now opens whenever it contains the current page. The old index logic opened only the first match.
- Groups a reader expands by hand stay open across navigation.
- The mobile drawer still builds its own sidebar per page, which is fine since it closes on navigation.
Testing
- New unit test for URL-driven group expansion; existing sidebar unit tests updated for the new signatures.
- New browser tests: the sidebar keeps the same element and scroll offset across navigation, and a long active label stays on one line.
- All 11 existing sidebar browser tests pass against a local dev server (built from a whitelisted subset of pages).
test_sidebar_offsets_follow_navbar_and_announcementfailed once on a freshly compiled dev server and passed on every re-run. It looks like a pre-existing hydration race on the "Dismiss announcement" click, but I haven't checked it againstmain.
š¤ Generated with Claude Code