1

I am building an Angular app with navigation using routerLink

Everything works fine, but what I want to be able to do, is have functionality to open something in a new tab by clicking CTRL+Click or mouse middleclick.

Can someone please tell me if this is even possible or what is the smartest way to do this? I searched for it a lot in the web but didn't really find a solution.

Thank you guys!

kevla
  • 21
  • 3
  • Does this answer your question? [Angular 2 Routing run in new tab](https://stackoverflow.com/questions/41355830/angular-2-routing-run-in-new-tab) – ruth Mar 27 '20 at 08:13
  • @MichaelD not this is not the answer as this is using a custom link Directive, I want to continue using angular routerLink – kevla Mar 30 '20 at 07:03
  • The custom directive may be the only option because it appears the Angular RouterLink may not be used in the way you want. – ruth Mar 30 '20 at 07:22

3 Answers3

3

The RouterLinkWithHref directive specifically checks for ctrl+click and does nothing: https://github.com/angular/angular/blob/11.2.7/packages/router/src/directives/router_link.ts#L375-L380

To fix this, I added my own directive that extends RouterLinkWithHref making it open in a new window with ctrl+click:

import { Directive } from '@angular/core';
import { RouterLinkWithHref } from '@angular/router';

@Directive({
    selector: 'a[routerLink],area[routerLink]'
})
export class CtrlClickRouterLinkDirective extends RouterLinkWithHref {
    onClick(button: number, ctrlKey: boolean): boolean {
        if (ctrlKey && button === 0) {
            window.open(this.urlTree.toString(), '_blank');
        }
        return true;
    }
}
Jeff Cross
  • 31
  • 2
1

I ran into the same problem and I found that I didn't add the routerLink directive to an a tag. The 'open in new tab' functionaly is provided by the browser, depending on your OS (eg. phones need a long click and in the menu, you can select open in new tab). But this is only happening when you add routerlink to an a tag, since it makes the href attribute only then.

So the solution was simply to put the routerlink onto an a tag, and everything works as expected (and the web crawlers will find the links more easily, I think).

<a routerLink="/my-link" class="button"> ACTION </a>
Ambrus Tóth
  • 552
  • 6
  • 14
0

You could extend the RouterLink and place your custom eventHandlers

import { Directive, HostListener } from '@angular/core';
import { RouterLink } from '@angular/router';

@Directive({
 selector: '[routerLink]'
})
export class RouterLinkDirective extends RouterLink {
 @HostListener('mouseup', ['$event'])
 triggerCustomClick(ev: MouseEvent) {
  if (ev.button  === 1 || (ev.ctrlKey && ev.button === 0)) {
    window.open(this.urlTree.toString(), '_blank')
 }
}
 // Preventing the default scroll by movement
 @HostListener('mousedown', ['$event'])
 preventMiddleClickScroll(ev: MouseEvent) {
  if (ev.button  === 1) {
    ev.preventDefault();
  }
 }
}