mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Fix anchor links not scrolling to target on client-side navigation (RND-11844)
Cross-page anchor links (e.g. a homepage card linking to `/page#heading`) landed at the top of the destination page on soft navigation, while the same URL loaded directly scrolled to the heading correctly. `useScrollToHash` (the per-page safety net in PageClientLayout that scrolls once the page blocks are rendered) only depended on the navigation hash. The hash is set at click time while the previous page is still mounted, so the effect fired before the target element existed. Because sibling pages share the same `[pagePath]` route, PageClientLayout is reused rather than remounted, so the effect never re-ran once the destination content committed to the DOM. Add `pathname` as a dependency so the scroll is re-attempted when the destination page commits and the target heading is present. The `if (hash)` guard is unchanged, so hash-less navigations still scroll to top via ScrollPage and back/forward restoration is unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TpGe6QkAF4Y1HDGUD4vbke
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Fix anchor links (e.g. `/page#heading`) not scrolling to the target heading during client-side navigation between pages.
|
||||
@@ -69,12 +69,20 @@ export function ScrollPage() {
|
||||
*/
|
||||
export function useScrollToHash() {
|
||||
const hash = useHash();
|
||||
const pathname = usePathname();
|
||||
|
||||
// Depend on `pathname` as well as `hash`: on a soft navigation to another page
|
||||
// (e.g. a homepage card linking to `/page#heading`), the hash is set on click while
|
||||
// the previous page is still mounted, so a hash-only effect fires before the target
|
||||
// element exists. Because sibling pages share the same `[pagePath]` route, this hook's
|
||||
// host component is reused rather than remounted, so it would otherwise never re-run
|
||||
// once the destination content commits. Re-running on `pathname` re-attempts the scroll
|
||||
// when the target heading is finally in the DOM.
|
||||
React.useEffect(() => {
|
||||
if (hash) {
|
||||
scrollToHash(hash);
|
||||
}
|
||||
}, [hash]);
|
||||
}, [hash, pathname]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user