Issue number: resolves #19566, resolves #19365
What is the current behavior?
Clicking an ion-router-link whose href contains a #fragment (e.g. /catalog#pens) fails to navigate and logs not part of the routing set. parsePath in core/src/components/router/utils/path.ts only splits on ?, so the fragment gets folded into the last path segment and no registered route matches. Even when navigation succeeds, the matching anchor is never scrolled into view.
What is the new behavior?
parsePath extracts the fragment as a separate field, and writeSegments writes it back onto the URL via pushState. Routes match against the path segments alone, so /catalog#pens resolves to the /catalog route as expected.
After writeNavStateRoot resolves, the router polls a few animation frames for an element matching the fragment inside the active page, then smooth-scrolls to it via ion-content.scrollToPoint, falling back to Element.scrollIntoView when the target sits outside ion-content. A fragmentScrollToken cancels any in-flight scroll the moment a newer setSegments runs.
Does this introduce a breaking change?
- Yes
- No
Other information
The fragment lookup scopes to the last .ion-page:not(.ion-page-hidden) in the document. Nested outlets can have multiple non-hidden pages mounted at once, and an identically-named anchor on a parent page would otherwise win over the leaf the user is viewing.
Preview pages: