Repository navigation
fix: Improve hash scrolling restoration logic for better user experience - #2952
Merged
Merged
Conversation
renejeglinsky
requested review from
chgeo,
danjoa and
swaldmann
as code owners
October 19, 2026 18:32
Contributor
Control PanelHi, I'm an AI-powered Review Bot that helps you with summarizing and reviewing pull requests.
|
chgeo
approved these changes
Oct 20, 2026
chgeo
left a comment
Member
There was a problem hiding this comment.
Would have taken me ages to figure this out. Thanks!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here's what I found and fixed.
Why the anchor disappears
The culprit is the inline head script restoreCodeGroupPreferences.js, which is injected into every page via config.js:93.
Its job is to restore code-group tab preferences before Vue hydrates. Because re-selecting tabs changes layout height, it can't let the browser scroll to the hash natively, so on load it strips the hash from the URL (87), remembers it, and plans to put it back and scroll manually once the tabs are applied.
The bug: every path that restores the hash was gated on code-groups being present:
initialCodeGroupCount > 0.MutationObserverrestores only when a.vp-code-groupnode is added.DOMContentLoadedrestore is registered only whenreadyState === 'loading', but this inline script actually runs atreadyStateinteractive/complete, so that branch never registers.I confirmed this with a hash timeline: the hash is present until ~500ms, then gets stripped and never comes back on
/docs/java/ai. A page with code-groups (/docs/cds/aspects#separation-of-concerns) kept its hash, which matched the theory exactly:java/aihas zero.vp-code-groupelements, so nothing ever triggers the restore.The fix
Two changes in restoreCodeGroupPreferences.js:
restoreHashScrollnow puts the hash back immediately and only marks itself done once the target element actually exists, so late-hydrating content (dev mode especially) still gets scrolled.pollRestorefallback that runs viarequestAnimationFramewhenever a hash is pending, independent of code-groups. It retries each frame until the target hydrates (3s cap), then stops. This covers pages with no code-groups and anyreadyState.--- AI-supported ---