@@ -331,20 +331,12 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
331331 let _pageloadSpan : Span | undefined ;
332332
333333 /** Create routing idle transaction. */
334- function _createRouteSpan (
335- client : Client ,
336- startSpanOptions : StartSpanOptions ,
337- defaultOp : string ,
338- makeActive = true ,
339- url ?: string ,
340- ) : void {
341- // `beforeStartSpan` is a public hook that receives - and may override - the deprecated `op` option,
342- // so it stays part of the options handed to it and is only folded into `sentry.op` afterwards.
343- // TODO(v12): Drop `op` once `StartSpanOptions.op` is removed.
334+ function _createRouteSpan ( client : Client , startSpanOptions : StartSpanOptions , makeActive = true , url ?: string ) : void {
335+ const originalOp = startSpanOptions . attributes ?. [ SENTRY_OP ] ;
336+ // backfill top-level `op` option
344337 // oxlint-disable-next-line typescript/no-deprecated
345- const optionsWithOp : StartSpanOptions = { op : defaultOp , ...startSpanOptions } ;
346- // oxlint-disable-next-line typescript/no-deprecated
347- const isPageloadSpan = optionsWithOp . op === 'pageload' ;
338+ const optionsWithOp : StartSpanOptions = { op : originalOp , ...startSpanOptions } ;
339+ const isPageloadSpan = originalOp === PAGELOAD ;
348340
349341 const initialSpanName = optionsWithOp . name ;
350342 const finalStartSpanOptions : StartSpanOptions = beforeStartSpan ? beforeStartSpan ( optionsWithOp ) : optionsWithOp ;
@@ -359,9 +351,11 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
359351 ...finalStartSpanOptions . attributes ,
360352 } ;
361353
362- // Mirrors the precedence `startSpan` applies: an explicit `sentry.op` attribute wins over `op`.
363354 // oxlint-disable-next-line typescript/no-deprecated
364- attributes [ SENTRY_OP ] ??= finalStartSpanOptions . op ;
355+ if ( finalStartSpanOptions . op !== originalOp ) {
356+ // oxlint-disable-next-line typescript/no-deprecated
357+ attributes [ SENTRY_OP ] = finalStartSpanOptions . op ;
358+ }
365359
366360 // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`
367361 // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.
@@ -500,8 +494,8 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
500494 _createRouteSpan (
501495 client ,
502496 {
503- op : NAVIGATION_REDIRECT ,
504497 ...startSpanOptions ,
498+ attributes : { [ SENTRY_OP ] : NAVIGATION_REDIRECT , ...startSpanOptions . attributes } ,
505499 } ,
506500 false ,
507501 navigationOptions . url ,
@@ -532,12 +526,11 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
532526 _createRouteSpan (
533527 client ,
534528 {
535- op : NAVIGATION ,
536529 ...startSpanOptions ,
530+ attributes : { [ SENTRY_OP ] : NAVIGATION , ...startSpanOptions . attributes } ,
537531 // Navigation starts a new trace and is NOT parented under any active interaction (e.g. ui.action.click)
538532 parentSpan : null ,
539533 } ,
540- 'navigation' ,
541534 true ,
542535 navigationOptions ?. url ,
543536 ) ;
@@ -571,8 +564,8 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
571564 } ) ;
572565
573566 _createRouteSpan ( client , {
574- op : PAGELOAD ,
575567 ...startSpanOptions ,
568+ attributes : { [ SENTRY_OP ] : PAGELOAD , ...startSpanOptions . attributes } ,
576569 } ) ;
577570 } ) ;
578571
0 commit comments