@@ -50,32 +50,15 @@ export function instrumentVueRouter(
5050 } ,
5151 startNavigationSpanFn : ( context : StartSpanOptions ) => void ,
5252) : void {
53- let isFirstPageLoad = true ;
53+ let hasHandledFirstPageLoad = false ;
5454
5555 router . onError ( error => captureException ( error , { mechanism : { handled : false } } ) ) ;
5656
57- router . beforeEach ( ( to , from , next ) => {
58- // According to docs we could use `from === VueRouter.START_LOCATION` but I couldn't get it working for Vue 2
59- // https://router.vuejs.org/api/#router-start-location
60- // https://next.router.vuejs.org/api/#start-location
61- // Additionally, Nuxt does not provide the possibility to check for `from.matched.length === 0` (this is never 0).
62- // Therefore, a flag was added to track the page-load: isFirstPageLoad
63-
64- // from.name:
65- // - Vue 2: null
66- // - Vue 3: undefined
67- // - Nuxt: undefined
68- // hence only '==' instead of '===', because `undefined == null` evaluates to `true`
69- const isPageLoadNavigation =
70- ( from . name == null && from . matched . length === 0 ) || ( from . name === undefined && isFirstPageLoad ) ;
71-
72- if ( isFirstPageLoad ) {
73- isFirstPageLoad = false ;
74- }
57+ router . beforeEach ( ( to , _from , next ) => {
58+ // We avoid trying to re-fetch the page load span when we know we already handled it the first time
59+ const activePageLoadSpan = ! hasHandledFirstPageLoad ? getActivePageLoadSpan ( ) : undefined ;
7560
76- const attributes : SpanAttributes = {
77- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.vue' ,
78- } ;
61+ const attributes : SpanAttributes = { } ;
7962
8063 for ( const key of Object . keys ( to . params ) ) {
8164 attributes [ `params.${ key } ` ] = to . params [ key ] ;
@@ -102,30 +85,33 @@ export function instrumentVueRouter(
10285
10386 getCurrentScope ( ) . setTransactionName ( spanName ) ;
10487
105- if ( options . instrumentPageLoad && isPageLoadNavigation ) {
106- const activeRootSpan = getActiveRootSpan ( ) ;
107- if ( activeRootSpan ) {
108- const existingAttributes = spanToJSON ( activeRootSpan ) . data ;
109- if ( existingAttributes [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] !== 'custom' ) {
110- activeRootSpan . updateName ( spanName ) ;
111- activeRootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , transactionSource ) ;
112- }
113- // Set router attributes on the existing pageload transaction
114- // This will override the origin, and add params & query attributes
115- activeRootSpan . setAttributes ( {
116- ...attributes ,
117- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.vue' ,
118- } ) ;
88+ // Update the existing page load span with parametrized route information
89+ if ( options . instrumentPageLoad && activePageLoadSpan ) {
90+ const existingAttributes = spanToJSON ( activePageLoadSpan ) . data ;
91+ if ( existingAttributes [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] !== 'custom' ) {
92+ activePageLoadSpan . updateName ( spanName ) ;
93+ activePageLoadSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , transactionSource ) ;
11994 }
95+
96+ // Set router attributes on the existing pageload transaction
97+ // This will override the origin, and add params & query attributes
98+ activePageLoadSpan . setAttributes ( {
99+ ...attributes ,
100+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.vue' ,
101+ } ) ;
102+
103+ hasHandledFirstPageLoad = true ;
120104 }
121105
122- if ( options . instrumentNavigation && ! isPageLoadNavigation ) {
123- attributes [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] = transactionSource ;
124- attributes [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] = 'auto.navigation.vue' ;
106+ if ( options . instrumentNavigation && ! activePageLoadSpan ) {
125107 startNavigationSpanFn ( {
126108 name : spanName ,
127109 op : 'navigation' ,
128- attributes,
110+ attributes : {
111+ ...attributes ,
112+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.vue' ,
113+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : transactionSource ,
114+ } ,
129115 } ) ;
130116 }
131117
@@ -138,7 +124,7 @@ export function instrumentVueRouter(
138124 } ) ;
139125}
140126
141- function getActiveRootSpan ( ) : Span | undefined {
127+ function getActivePageLoadSpan ( ) : Span | undefined {
142128 const span = getActiveSpan ( ) ;
143129 const rootSpan = span && getRootSpan ( span ) ;
144130
@@ -148,6 +134,5 @@ function getActiveRootSpan(): Span | undefined {
148134
149135 const op = spanToJSON ( rootSpan ) . op ;
150136
151- // Only use this root span if it is a pageload or navigation span
152- return op === 'navigation' || op === 'pageload' ? rootSpan : undefined ;
137+ return op === 'pageload' ? rootSpan : undefined ;
153138}
0 commit comments