@@ -7,9 +7,19 @@ import type { ActivatedRouteSnapshot, Event, RouterState } from '@angular/router
77// eslint-disable-next-line @typescript-eslint/consistent-type-imports 
88import  {  NavigationCancel ,  NavigationError ,  Router  }  from  '@angular/router' ; 
99import  {  NavigationEnd ,  NavigationStart ,  ResolveEnd  }  from  '@angular/router' ; 
10- import  {  WINDOW ,  getCurrentScope  }  from  '@sentry/browser' ; 
11- import  {  SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,  spanToJSON  }  from  '@sentry/core' ; 
12- import  type  {  Span ,  Transaction ,  TransactionContext  }  from  '@sentry/types' ; 
10+ import  { 
11+   WINDOW , 
12+   browserTracingIntegration  as  originalBrowserTracingIntegration , 
13+   getCurrentScope , 
14+ }  from  '@sentry/browser' ; 
15+ import  { 
16+   SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 
17+   getActiveSpan , 
18+   getClient , 
19+   spanToJSON , 
20+   startInactiveSpan , 
21+ }  from  '@sentry/core' ; 
22+ import  type  {  Integration ,  Span ,  Transaction ,  TransactionContext  }  from  '@sentry/types' ; 
1323import  {  logger ,  stripUrlQueryAndFragment ,  timestampInSeconds  }  from  '@sentry/utils' ; 
1424import  type  {  Observable  }  from  'rxjs' ; 
1525import  {  Subscription  }  from  'rxjs' ; 
@@ -23,6 +33,8 @@ let instrumentationInitialized: boolean;
2333let  stashedStartTransaction : ( context : TransactionContext )  =>  Transaction  |  undefined ; 
2434let  stashedStartTransactionOnLocationChange : boolean ; 
2535
36+ let  hooksBasedInstrumentation  =  false ; 
37+ 
2638/** 
2739 * Creates routing instrumentation for Angular Router. 
2840 */ 
@@ -49,6 +61,23 @@ export function routingInstrumentation(
4961
5062export  const  instrumentAngularRouting  =  routingInstrumentation ; 
5163
64+ /** 
65+  * A custom BrowserTracing integration for Angular. 
66+  */ 
67+ export  function  browserTracingIntegration ( 
68+   options ?: Parameters < typeof  originalBrowserTracingIntegration > [ 0 ] , 
69+ ) : Integration  { 
70+   instrumentationInitialized  =  true ; 
71+   hooksBasedInstrumentation  =  true ; 
72+ 
73+   return  originalBrowserTracingIntegration ( { 
74+     ...options , 
75+     instrumentPageLoad : true , 
76+     // We handle this manually 
77+     instrumentNavigation : false , 
78+   } ) ; 
79+ } 
80+ 
5281/** 
5382 * Grabs active transaction off scope. 
5483 * 
@@ -74,7 +103,44 @@ export class TraceService implements OnDestroy {
74103        return ; 
75104      } 
76105
106+       if  ( this . _routingSpan )  { 
107+         this . _routingSpan . end ( ) ; 
108+         this . _routingSpan  =  null ; 
109+       } 
110+ 
77111      const  strippedUrl  =  stripUrlQueryAndFragment ( navigationEvent . url ) ; 
112+ 
113+       const  client  =  getClient ( ) ; 
114+       if  ( hooksBasedInstrumentation  &&  client  &&  client . emit )  { 
115+         if  ( ! getActiveSpan ( ) )  { 
116+           client . emit ( 'startNavigationSpan' ,  { 
117+             name : strippedUrl , 
118+             op : 'navigation' , 
119+             origin : 'auto.navigation.angular' , 
120+             attributes : { 
121+               [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' , 
122+             } , 
123+           } ) ; 
124+         } 
125+ 
126+         // eslint-disable-next-line deprecation/deprecation 
127+         this . _routingSpan  = 
128+           startInactiveSpan ( { 
129+             name : `${ navigationEvent . url }  ` , 
130+             op : ANGULAR_ROUTING_OP , 
131+             origin : 'auto.ui.angular' , 
132+             tags : { 
133+               'routing.instrumentation' : '@sentry/angular' , 
134+               url : strippedUrl , 
135+               ...( navigationEvent . navigationTrigger  &&  { 
136+                 navigationTrigger : navigationEvent . navigationTrigger , 
137+               } ) , 
138+             } , 
139+           } )  ||  null ; 
140+ 
141+         return ; 
142+       } 
143+ 
78144      // eslint-disable-next-line deprecation/deprecation 
79145      let  activeTransaction  =  getActiveTransaction ( ) ; 
80146
@@ -90,9 +156,6 @@ export class TraceService implements OnDestroy {
90156      } 
91157
92158      if  ( activeTransaction )  { 
93-         if  ( this . _routingSpan )  { 
94-           this . _routingSpan . end ( ) ; 
95-         } 
96159        // eslint-disable-next-line deprecation/deprecation 
97160        this . _routingSpan  =  activeTransaction . startChild ( { 
98161          description : `${ navigationEvent . url }  ` , 
0 commit comments