feat: persist sidebar scroll position across page navigations
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29
- Forks
- 165
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 2
Description
Problem
The sidebar navigation currently resets to the top every time the user navigates between pages.
For readers working through content in sections deep in the sidebar (e.g. Node-API, Diagnostics,
or Asynchronous Work), this means manually scrolling back down after every page visit — which creates
a frustrating and disorienting experience.
Additionally, SideBar from @node-core/ui-components does not support forwardRef, so passing
ref={sidebarRef} to it is silently ignored. This means the scroll restoration logic in
useScrollToElement and useScroll never receives a valid DOM reference to attach the scroll listener to.
Proposed Solution
-
Fix ref acquisition – Use
useLayoutEffectinSidebar/index.jsxto manually assignsidebarRef.current
to the rendered<aside>element beforeuseEffects run, ensuring the scroll listener is properly attached. -
Persist scroll position – Extend
useScrollToElementto:- Save the sidebar scroll position to
localStorageon every scroll event (debounced). - On mount, restore from
NavigationStateContext(same-session navigation) or fall back tolocalStorage
(full page refresh), whichever is available.
- Save the sidebar scroll position to
Files Changed
components/Sidebar/index.jsx– useuseLayoutEffectto acquire ref to<aside>hooks/useScrollToElement.js– add localStorage read on mount and write on scrollhooks/useScroll.js– useonScrollRefpattern to avoid stale closure ononScrollcallback
Expected Behaviour
| Action | Before | After |
|---|---|---|
| Navigate to another page | Sidebar resets to top | Sidebar stays at last scroll position |
| Hard refresh (F5) | Sidebar resets to top | Sidebar restores from localStorage |
Notes
SideBarfrom@node-core/ui-componentsneeds to supportforwardReffor this to work without
theuseLayoutEffectworkaround. A separate issue/PR upstream on that package may be worth considering.- The
useScrollhook dependency onref.current(instead ofref) ensures the listener is attached
after the DOM element is available.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading components/Sidebar/index.jsx, hooks/useScrollToElement.js, and hooks/useScroll.js to understand the existing ref and scroll handling. Verify that navigation preserves the sidebar position and that a hard refresh restores it from localStorage, covering the Node-API, Diagnostics, or Asynchronous Work sections.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend, web-dev
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100