Skip to content

fix(angular RouterLinkDelegateDirective): Make routerLink respect target and keyboard modifiers#28976

Closed
j-oppenhuis wants to merge 1 commit into
ionic-team:mainfrom
j-oppenhuis:main
Closed

fix(angular RouterLinkDelegateDirective): Make routerLink respect target and keyboard modifiers#28976
j-oppenhuis wants to merge 1 commit into
ionic-team:mainfrom
j-oppenhuis:main

Conversation

@j-oppenhuis

Copy link
Copy Markdown
Contributor

Issue number: resolves #26394


What is the current behavior?

This fixes using routerLink in combination with a target different than _self. It also fixes a bug where CTRL + click or shift + click does not work like expected in combination with routerLink in Angular.

What is the new behavior?

When using a target other than _self and keyboard modifiers we are now stopping execution of navigating by routeDirection. This is not needed because the app will reload either way.

Does this introduce a breaking change?

  • Yes
  • No

Other information

@github-actions github-actions Bot added the package: angular @ionic/angular package label Feb 5, 2024

@thetaPC thetaPC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for submitting a PR to the project! We appreciate your contribution.

There are a few things that need to be addressed before we can move forward with the PR.

  1. Command clicking is not following expected browser behavior. While I’m able to CMD + click on the button and the link opens in a new tab, the active page navigates to the same url.
  2. The OPTION key is not being taken into account when clicking on the button if the user is using a Mac. The user shouldn't be able to open the link in a new tab and the page should not redirect to the link passed to routerLink.
  3. As a noted in the first item, the page should not redirect to the link passed to routerLink. The redirection is happening because of a behavior that is implemented in ion-button. We would want to prevent Ionic's click listener from triggering when a new tab is opened.
  4. We also want to check the operating system of the user to tie the correct key to the correct action. The OPTION key should only be taken into account when the user is using a Mac.

Let me know if you have any questions! Thank you for your time and effort!

@j-oppenhuis

Copy link
Copy Markdown
Contributor Author

Thank you for your feedback. I understand that it is more complex than my initial idea. Instead of changing routerLink functionality, we should probably change the openURL function. Am I correct? If that is the case than we should indeed also pass in the operating system and the target. But is that a good solution?

@j-oppenhuis

Copy link
Copy Markdown
Contributor Author

I have looked into the code and I think my suggestion is incorrect. But it seems we are not able to prevent the button or item navigation by using stoppropagation. The only thing I can think of is adding a routerLink prop to the button and item components. Then we could make a distinction between desktop and mobile. When the current OS is desktop, the anchor could handle navigation. Otherwise, we could use openURL like we use now. Is that something that could work?

@thetaPC

thetaPC commented Apr 1, 2024

Copy link
Copy Markdown
Contributor

We've checked out the problem, and it's a tough one. But because we're short on time, our team can't really dig into it right now. However, we're up for bouncing around ideas together. We might not have all the answers, but we'll do what we can to help out.

I agree that passing an operating system is not the way to go. We want ion-button to not have strict checks like what OS the user has.

@sean-perkins sean-perkins removed their request for review April 26, 2024 20:20
@ShaneK

ShaneK commented Jun 18, 2026

Copy link
Copy Markdown
Member

Hey, thanks for your PR!

We've addressed this issue in another PR ( #31230 ), but have given you co-author credit for it thanks to your work on this one. This issue's fix will be deployed in the next release of Ionic Framework.

@ShaneK ShaneK closed this Jun 18, 2026
wheakerd pushed a commit to wheakerd/ionic-framework that referenced this pull request Jun 18, 2026
Issue number: resolves ionic-team#26394

---------

## What is the current behavior?

When `routerLink` is applied to a non-anchor Ionic component
(`ion-item`, `ion-button`), `RouterLinkDelegateDirective` always routes
in-app on click. A ctrl/meta/shift/alt click, or a host with
`target="_blank"`, gets swallowed by the in-app navigation, so the
browser never opens the link in a new tab. A plain `<a routerLink>`
honors these intents, but the Ionic delegate doesn't, even though these
components render a native anchor in their shadow DOM that's capable of
the native new-tab behavior.

## What is the new behavior?

`RouterLinkDelegateDirective` now adds a capture-phase click listener so
it runs before Angular's `RouterLink` handler and the directive's own
bubble-phase `onClick`. When the click should be handled natively (a
ctrl/meta/shift/alt modifier is held, or the host `target` is set to
anything other than `_self`), it calls `stopImmediatePropagation()` to
cancel the in-app navigation but leaves `preventDefault` alone, so the
shadow-DOM anchor can still open the tab. This mirrors the modifier set
Angular's own `RouterLink` guards on. Normal clicks are unaffected and
continue to navigate in-app. The listener is removed in `ngOnDestroy`.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

This supersedes ionic-team#28976 by @j-oppenhuis, which first surfaced the target
and modifier-click gap. Credited as co-author below.

To verify manually in the Angular preview, ctrl/cmd-click the two
`ion-item` rows (a plain one and a `target="_blank"` one) and confirm
each opens a new tab instead of navigating in place:

https://ionic-framework-git-fix-angular-routerlink-modifi-896c58-ionic1.vercel.app/angular/standalone/router-link

If you compare that against the main version of the same component,
you'll be able to see how it's fixed:

https://ionic-framework-git-main-ionic1.vercel.app/angular/standalone/router-link

Co-authored-by: Jelle Oppenhuis <jelle@siyou.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: ion-item href prop causes hard refresh when clicked, and routerLink prop disallows ctrl+click to open in new tab

3 participants