@@ -518,21 +518,42 @@ export function handleNavigation(opts: {
518518 }
519519
520520 const activeSpan = getActiveSpan ( ) ;
521- const isAlreadyInNavigationSpan = activeSpan && spanToJSON ( activeSpan ) . op === 'navigation' ;
521+ const rootSpan = activeSpan ? getRootSpan ( activeSpan ) : undefined ;
522+ const isAlreadyInNavigationSpan = rootSpan && spanToJSON ( rootSpan ) . op === 'navigation' ;
522523
523524 // Cross usage can result in multiple navigation spans being created without this check
524525 if ( isAlreadyInNavigationSpan ) {
525- activeSpan ?. updateName ( name ) ;
526- activeSpan ?. setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , source ) ;
526+ // Check if we've already set the name for this span using a custom property
527+ const hasBeenNamed = (
528+ rootSpan as {
529+ __sentry_navigation_name_set__ ?: boolean ;
530+ }
531+ ) ?. __sentry_navigation_name_set__ ;
532+ if ( ! hasBeenNamed ) {
533+ // This is the first time we're setting the name for this span
534+ const spanJson = spanToJSON ( rootSpan ) ;
535+ if ( ! spanJson . timestamp ) {
536+ rootSpan ?. updateName ( name ) ;
537+ rootSpan ?. setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , source ) ;
538+ }
539+ // Mark this span as having its name set to prevent future updates
540+ addNonEnumerableProperty ( rootSpan , '__sentry_navigation_name_set__' , true ) ;
541+ }
542+ // If we already have a name for this span, don't update it
527543 } else {
528- startBrowserTracingNavigationSpan ( client , {
544+ const span = startBrowserTracingNavigationSpan ( client , {
529545 name,
530546 attributes : {
531547 [ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE ] : source ,
532548 [ SEMANTIC_ATTRIBUTE_SENTRY_OP ] : 'navigation' ,
533549 [ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN ] : `auto.navigation.react.reactrouter_v${ version } ` ,
534550 } ,
535551 } ) ;
552+
553+ // Mark the new span as having its name set
554+ if ( span ) {
555+ addNonEnumerableProperty ( span , '__sentry_navigation_name_set__' , true ) ;
556+ }
536557 }
537558 }
538559}
0 commit comments