Skip to content

Comments

fix(docs-infra): preserve text fragment highlights during initial navigation#67216

Closed
yogeshwaran-c wants to merge 1 commit intoangular:mainfrom
yogeshwaran-c:fix/preserve-text-fragment-highlight
Closed

fix(docs-infra): preserve text fragment highlights during initial navigation#67216
yogeshwaran-c wants to merge 1 commit intoangular:mainfrom
yogeshwaran-c:fix/preserve-text-fragment-highlight

Conversation

@yogeshwaran-c
Copy link

What kind of change does this PR introduce?

Bug fix

What is the current behavior?

When using the browser's "Copy link to highlight" feature on the Angular documentation site (angular.dev), the text highlight briefly appears but then disappears as the page finishes loading. The #:~:text=... fragment is also removed from the URL.

This happens because Chrome and other browsers clear text fragment highlights whenever history.pushState or history.replaceState is called. During Angular's initial client-side navigation (after SSR hydration), the router calls replaceState to update the history state with a navigationId, which strips the highlight.

Closes #65119

What is the new behavior?

Text fragment highlights are preserved when navigating to an angular.dev URL that contains a #:~:text=... fragment. The browser's native "Copy link to highlight" feature works as expected.

This is achieved by adding a new environment initializer (preserveTextFragmentHighlight) that:

  1. Detects text fragment support via document.fragmentDirective
  2. Temporarily suppresses history.pushState/history.replaceState calls during the initial navigation
  3. Restores the original methods after the first NavigationEnd, NavigationCancel, or NavigationError

The suppression only affects the very first navigation (the initial page load) and only activates in browsers that support text fragment directives. Subsequent navigations work normally.

Additional context

  • Prior PR fix(adev): guard History API usage during NavigationStart #66491 attempted to fix this by adding SSR guards around the history.replaceState call, but was correctly rejected by the reviewer because window is already injected via the WINDOW token and the guards did not address the root cause.
  • The root cause is that any call to pushState/replaceState strips text fragment highlights per the Text Fragments spec, including the router's own state management call.
  • Reproduction: Open https://angular.dev/guide/signals#:~:text=signal%20is%20a-,wrapper,-around%20a%20value - the highlight appears briefly then vanishes.

…igation

Chrome and other browsers clear text fragment highlights (#:~:text=...)
whenever history.pushState or history.replaceState is called. During
Angular's initial navigation, the router calls replaceState to update
the history state with a navigationId, which strips the highlight and
breaks the browser's native "Copy link to highlight" feature.

This adds a new environment initializer that temporarily suppresses
pushState/replaceState calls during the initial navigation when text
fragment support is detected via document.fragmentDirective. The
original methods are restored after the first navigation completes.

Fixes angular#65119
@pullapprove pullapprove bot requested a review from MarkTechson February 23, 2026 18:14
@angular-robot angular-robot bot added the area: docs-infra Angular.dev application and infrastructure label Feb 23, 2026
@ngbot ngbot bot added this to the Backlog milestone Feb 23, 2026
@JeanMeche
Copy link
Member

This just doesn't works.

@JeanMeche JeanMeche closed this Feb 23, 2026
yogeshwaran-c added a commit to yogeshwaran-c/angular that referenced this pull request Feb 24, 2026
…igation

Chromium-based browsers clear text fragment highlights whenever
history.pushState or history.replaceState is called. During the initial
navigation, Angular's Router and the navigation adapter both call
replaceState, which strips the text highlight and removes the :~:text=
fragment from the URL.

The previous approach (PR angular#67216) suppressed replaceState/pushState
entirely via a separate environment initializer, but this conflicted
with the navigation adapter which also calls replaceState during
NavigationStart. The adapter's replaceState call triggers a Navigation
API intercept for browser loading indicators.

This fix resolves the conflict by:
1. Checking whether the current URL contains a text fragment directive
   (:~:) instead of checking the fragmentDirective browser feature
2. Registering the suppression initializer BEFORE the navigation
   adapter, so replaceState/pushState are already no-ops when the
   adapter fires on NavigationStart
3. Restoring the originals after the first navigation completes

The navigation adapter's replaceState call being suppressed during the
initial navigation is acceptable because the browser already shows a
loading indicator for the initial page load.

Fixes angular#65119
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: docs-infra Angular.dev application and infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

“Copy link to highlight” not working — text highlight and URL fragment removed after page load on Angular Docs

2 participants