7
7
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
8
8
} from '@sentry/core' ;
9
9
import { startBrowserTracingNavigationSpan , startBrowserTracingPageLoadSpan , WINDOW } from '@sentry/react' ;
10
+ import { maybeParameterizeRoute } from './parameterization' ;
10
11
11
12
export const INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME = 'incomplete-app-router-transaction' ;
12
13
@@ -34,15 +35,16 @@ const currentRouterPatchingNavigationSpanRef: NavigationSpanRef = { current: und
34
35
35
36
/** Instruments the Next.js app router for pageloads. */
36
37
export function appRouterInstrumentPageLoad ( client : Client ) : void {
38
+ const parameterizedPathname = maybeParameterizeRoute ( WINDOW . location . pathname ) ;
37
39
const origin = browserPerformanceTimeOrigin ( ) ;
38
40
startBrowserTracingPageLoadSpan ( client , {
39
- name : WINDOW . location . pathname ,
41
+ name : parameterizedPathname ?? WINDOW . location . pathname ,
40
42
// pageload should always start at timeOrigin (and needs to be in s, not ms)
41
43
startTime : origin ? origin / 1000 : undefined ,
42
44
attributes : {
43
45
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'pageload' ,
44
46
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.pageload.nextjs.app_router_instrumentation' ,
45
- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
47
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : parameterizedPathname ? 'route' : 'url' ,
46
48
} ,
47
49
} ) ;
48
50
}
@@ -85,7 +87,8 @@ const GLOBAL_OBJ_WITH_NEXT_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {
85
87
/** Instruments the Next.js app router for navigation. */
86
88
export function appRouterInstrumentNavigation ( client : Client ) : void {
87
89
routerTransitionHandler = ( href , navigationType ) => {
88
- const pathname = new URL ( href , WINDOW . location . href ) . pathname ;
90
+ const parameterizedPathname = maybeParameterizeRoute ( href ) ;
91
+ const pathname = parameterizedPathname ?? new URL ( href , WINDOW . location . href ) . pathname ;
89
92
90
93
if ( navigationRoutingMode === 'router-patch' ) {
91
94
navigationRoutingMode = 'transition-start-hook' ;
@@ -104,23 +107,27 @@ export function appRouterInstrumentNavigation(client: Client): void {
104
107
attributes : {
105
108
[ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'navigation' ,
106
109
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.nextjs.app_router_instrumentation' ,
107
- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
110
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : parameterizedPathname ? 'route' : 'url' ,
108
111
'navigation.type' : `router.${ navigationType } ` ,
109
112
} ,
110
113
} ) ;
111
114
}
112
115
} ;
113
116
114
117
WINDOW . addEventListener ( 'popstate' , ( ) => {
118
+ const parameterizedPathname = maybeParameterizeRoute ( WINDOW . location . pathname ) ;
115
119
if ( currentRouterPatchingNavigationSpanRef . current ?. isRecording ( ) ) {
116
- currentRouterPatchingNavigationSpanRef . current . updateName ( WINDOW . location . pathname ) ;
117
- currentRouterPatchingNavigationSpanRef . current . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'url' ) ;
120
+ currentRouterPatchingNavigationSpanRef . current . updateName ( parameterizedPathname ?? WINDOW . location . pathname ) ;
121
+ currentRouterPatchingNavigationSpanRef . current . setAttribute (
122
+ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ,
123
+ parameterizedPathname ? 'route' : 'url' ,
124
+ ) ;
118
125
} else {
119
126
currentRouterPatchingNavigationSpanRef . current = startBrowserTracingNavigationSpan ( client , {
120
- name : WINDOW . location . pathname ,
127
+ name : parameterizedPathname ?? WINDOW . location . pathname ,
121
128
attributes : {
122
129
[ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : 'auto.navigation.nextjs.app_router_instrumentation' ,
123
- [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : 'url' ,
130
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : parameterizedPathname ? 'route' : 'url' ,
124
131
'navigation.type' : 'browser.popstate' ,
125
132
} ,
126
133
} ) ;
@@ -209,9 +216,14 @@ function patchRouter(client: Client, router: NextRouter, currentNavigationSpanRe
209
216
transactionAttributes [ 'navigation.type' ] = 'router.forward' ;
210
217
}
211
218
219
+ const parameterizedPathname = maybeParameterizeRoute ( transactionName ) ;
220
+
212
221
currentNavigationSpanRef . current = startBrowserTracingNavigationSpan ( client , {
213
- name : transactionName ,
214
- attributes : transactionAttributes ,
222
+ name : parameterizedPathname ?? transactionName ,
223
+ attributes : {
224
+ ...transactionAttributes ,
225
+ [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : parameterizedPathname ? 'route' : 'url' ,
226
+ } ,
215
227
} ) ;
216
228
217
229
return target . apply ( thisArg , argArray ) ;
0 commit comments