Skip to content

Stop route changes from animating scroll position - #1295

Open
DanPiazza-Netwrix wants to merge 1 commit into
devfrom
DanPiazza-Netwrix/fix-anchor-scroll-navbar-overlap
Open

Stop route changes from animating scroll position#1295
DanPiazza-Netwrix wants to merge 1 commit into
devfrom
DanPiazza-Netwrix/fix-anchor-scroll-navbar-overlap

Conversation

@DanPiazza-Netwrix

Copy link
Copy Markdown
Contributor

Summary

  • Global scroll-behavior: smooth (src/css/custom.css) made every page navigation visibly animate scroll-to-top/anchor instead of snapping, since Docusaurus resets scroll position via window.scrollTo/scrollIntoView on each route change
  • Added src/clientModules/scrollBehavior.js, registered via clientModules in docusaurus.config.js, that disables smooth scrolling for cross-page navigation while preserving it for same-page anchor clicks (TOC links, etc.)
  • Also handles a fresh full-page load to a hash URL (target element doesn't exist yet in the dev server's client-rendered shell) and waits for layout to settle before scrolling so anchors land clear of the sticky navbar

Test plan

  • Navigate to a new page with no anchor — lands at top instantly
  • Navigate (fresh load and in-app) to a new page with an anchor — lands at the anchor instantly, clear of the sticky navbar
  • Click a TOC/anchor link while already on the page — still animates smoothly

Global scroll-behavior: smooth caused every page navigation to visibly
glide instead of snap, since Docusaurus resets scroll via
window.scrollTo/scrollIntoView on each route change. Add a client
module that disables smooth scrolling for cross-page navigation
(landing at the top or at an anchor instantly) while keeping it for
same-page anchor clicks like TOC links.

Also handles two edge cases: a fresh full-page load to a hash URL
(where the target element doesn't exist yet in the dev server's
client-rendered shell), and layout settling after the element first
appears so anchors aren't left obscured by the sticky navbar.
@github-actions

Copy link
Copy Markdown
Contributor

Code Review

Reviewed for correctness (bugs, security, build/routing, workflows) — documentation/style excluded per scope.

No issues found. This is a clean, well-contained change.

Notes from the review:

  • docusaurus.config.jsclientModules is a valid top-level config field, and the referenced path ./src/clientModules/scrollBehavior.js exists. No build/routing risk.
  • SSR safety — the module has no top-level side effects (only function declarations), so its SSR import is harmless; onRouteUpdate/onRouteDidUpdate are client-only lifecycle hooks, so document/window are never touched during the build.
  • No temporal-dead-zone bugcleanup() references stopTimer and observer (declared later with const), but it is only ever invoked asynchronously from timer/observer callbacks, after synchronous initialization completes, so the bindings are initialized by then.
  • No leaks — the MutationObserver and both timers are unconditionally torn down by the 2s stopTimer, and attemptScroll cleans up early once the hash matches. The attributes: true, subtree: true observation is broad but bounded to the fresh-hash-load path and capped at 2s.
  • Behavior logicbehavior: 'instant' is a valid ScrollBehavior value, and the smooth/auto inline-style toggling is consistent with the global scroll-behavior: smooth in src/css/custom.css. Same-page anchor nav keeps smooth; cross-page nav snaps.

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