@@ -50,32 +50,15 @@ export function instrumentVueRouter(
50
50
} ,
51
51
startNavigationSpanFn : ( context : StartSpanOptions ) => void ,
52
52
) : void {
53
- let isFirstPageLoad = true ;
53
+ let hasHandledFirstPageLoad = false ;
54
54
55
55
router . onError ( error => captureException ( error , { mechanism : { handled : false } } ) ) ;
56
56
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 ;
75
60
76
- const attributes : SpanAttributes = {
77
- [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.vue' ,
78
- } ;
61
+ const attributes : SpanAttributes = { } ;
79
62
80
63
for ( const key of Object . keys ( to . params ) ) {
81
64
attributes [ `params.${ key } ` ] = to . params [ key ] ;
@@ -102,30 +85,33 @@ export function instrumentVueRouter(
102
85
103
86
getCurrentScope ( ) . setTransactionName ( spanName ) ;
104
87
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 ) ;
119
94
}
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 ;
120
104
}
121
105
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 ) {
125
107
startNavigationSpanFn ( {
126
108
name : spanName ,
127
109
op : 'navigation' ,
128
- attributes,
110
+ attributes : {
111
+ ...attributes ,
112
+ [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.vue' ,
113
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : transactionSource ,
114
+ } ,
129
115
} ) ;
130
116
}
131
117
@@ -138,7 +124,7 @@ export function instrumentVueRouter(
138
124
} ) ;
139
125
}
140
126
141
- function getActiveRootSpan ( ) : Span | undefined {
127
+ function getActivePageLoadSpan ( ) : Span | undefined {
142
128
const span = getActiveSpan ( ) ;
143
129
const rootSpan = span && getRootSpan ( span ) ;
144
130
@@ -148,6 +134,5 @@ function getActiveRootSpan(): Span | undefined {
148
134
149
135
const op = spanToJSON ( rootSpan ) . op ;
150
136
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 ;
153
138
}
0 commit comments