From 2e182fd111e1f65fec64319367e9f52772b990e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 13:49:37 +0000 Subject: [PATCH] Make GitBook the sole scroll authority so cross-page anchors land on target (RND-11844) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Browser diagnostics on the reported n8n case showed two cooperating causes, which is why the earlier single-sided attempts failed: 1. The scroll hooks fire when the hash is set (on link click, still on the previous page), so the target heading isn't in the DOM yet and scrollToHash missed and never retried. Fixed in the previous commit by retrying scrollToHash across frames. 2. With the retry in place, our scrollIntoView *does* fire once the heading commits — but Next's own post-navigation scroll (its hash scrollIntoView plus a scroll-to-top, see useHash / vercel/next.js#49465) runs after us and wins, snapping back to the top. Set `scroll={false}` on the internal NextLink so Next stops managing scroll on client-side navigation and GitBook's ScrollPage/useScrollToHash own it exclusively: retry to the hash when present, scroll to top otherwise. Neither change works alone — the retry needs Next to stop overriding it, and scroll={false} needs the retry to find the late-committing element. Still needs a browser check: rerunning the console diagnostic should now show our scrollIntoView fire without a following scroll-to-top, landing on the heading. Because scroll={false} routes all navigation scroll through ScrollPage, also regression-check plain page-to-page nav (top), same-page anchors, and back/forward. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01TpGe6QkAF4Y1HDGUD4vbke --- packages/gitbook/src/components/primitives/Link.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/gitbook/src/components/primitives/Link.tsx b/packages/gitbook/src/components/primitives/Link.tsx index 33324cd70..292731c54 100644 --- a/packages/gitbook/src/components/primitives/Link.tsx +++ b/packages/gitbook/src/components/primitives/Link.tsx @@ -171,6 +171,12 @@ export function Link(props: LinkProps) { ref={ref} href={href} prefetch={_prefetch} + // GitBook is the sole scroll authority on client-side navigation (`ScrollPage` / + // `useScrollToHash` → `scrollToHash`, which retries until the target commits). Next's + // own post-navigation scroll (see `useHash`, vercel/next.js#49465) otherwise fires its + // own `scrollToHash` and a scroll-to-top that override ours, leaving cross-page anchor + // links stuck at the top. Opt out so only our handlers scroll. + scroll={false} className={tcls(...forwardedClassNames, className)} {...domProps} onClick={onClick}