@@ -4,6 +4,42 @@ import type {
44 Analytics as SegmentAnalytics ,
55} from '@segment/analytics-next'
66
7+ // Check if a user is opening the link in a new tab
8+ function userNewTab ( event : Event ) : boolean {
9+ const typedEvent = event as Event & {
10+ ctrlKey : boolean
11+ shiftKey : boolean
12+ metaKey : boolean
13+ button : number
14+ }
15+ if (
16+ typedEvent . ctrlKey ||
17+ typedEvent . shiftKey ||
18+ typedEvent . metaKey ||
19+ ( typedEvent . button && typedEvent . button === 1 )
20+ ) {
21+ return true
22+ }
23+
24+ return false
25+ }
26+
27+ // Check if the link opens in new tab
28+ function linkNewTab (
29+ element : HTMLAnchorElement ,
30+ href : string | null | undefined ,
31+ ) : boolean {
32+ if ( element . target === '_blank' && href ) {
33+ return true
34+ }
35+
36+ return false
37+ }
38+
39+ export type JQueryShim < TElement = HTMLElement > = {
40+ toArray ( ) : TElement [ ]
41+ }
42+
743export type TrackLink = SegmentAnalytics [ 'trackLink' ]
844
945/**
@@ -13,7 +49,46 @@ export type TrackLink = SegmentAnalytics['trackLink']
1349export const trackLink =
1450 ( analytics : RudderAnalytics ) =>
1551 ( ...args : Parameters < SegmentAnalytics [ 'trackLink' ] > ) => {
16- const [ , event , properties ] = args
52+ const [ links , event , properties ] = args
53+ let elements : Element [ ] = [ ]
54+ // always arrays, handles jquery
55+ if ( ! links ) {
56+ return this
57+ }
58+ if ( links instanceof Element ) {
59+ elements = [ links ]
60+ } else if ( 'toArray' in links ) {
61+ elements = links . toArray ( )
62+ } else {
63+ elements = links
64+ }
65+
66+ elements . forEach ( ( el : Element ) => {
67+ el . addEventListener (
68+ 'click' ,
69+ ( elementEvent : Event ) => {
70+ const href =
71+ el . getAttribute ( 'href' ) ||
72+ el . getAttributeNS ( 'http://www.w3.org/1999/xlink' , 'href' ) ||
73+ el . getAttribute ( 'xlink:href' ) ||
74+ el . getElementsByTagName ( 'a' ) [ 0 ] ?. getAttribute ( 'href' )
75+
76+ if (
77+ ! linkNewTab ( el as HTMLAnchorElement , href ) &&
78+ ! userNewTab ( elementEvent )
79+ ) {
80+ if ( href ) {
81+ elementEvent . preventDefault ( )
82+
83+ analytics . track ( event as string , properties as EventProperties )
84+
85+ window . location . href = href
86+ }
87+ }
88+ } ,
89+ false ,
90+ )
91+ } )
1792
18- return analytics . track ( event as string , properties as EventProperties )
93+ return this
1994 }
0 commit comments