@@ -44,6 +44,7 @@ import { checkRouteForAsyncHandler } from './lazy-routes';
44
44
import {
45
45
getNormalizedName ,
46
46
initializeRouterUtils ,
47
+ isLikelyLazyRouteContext ,
47
48
locationIsInsideDescendantRoute ,
48
49
prefixWithSlash ,
49
50
rebuildRoutePathFromAllRoutes ,
@@ -114,7 +115,7 @@ const allRoutes = new Set<RouteObject>();
114
115
export function processResolvedRoutes (
115
116
resolvedRoutes : RouteObject [ ] ,
116
117
parentRoute ?: RouteObject ,
117
- currentLocation ? : Location ,
118
+ currentLocation : Location | null = null ,
118
119
) : void {
119
120
resolvedRoutes . forEach ( child => {
120
121
allRoutes . add ( child ) ;
@@ -538,7 +539,7 @@ function wrapPatchRoutesOnNavigation(
538
539
key : 'default' ,
539
540
} ,
540
541
Array . from ( allRoutes ) ,
541
- true ,
542
+ true , // forceUpdate = true since we're loading lazy routes
542
543
_matchRoutes ,
543
544
) ;
544
545
}
@@ -552,9 +553,8 @@ function wrapPatchRoutesOnNavigation(
552
553
// Update navigation span after routes are patched
553
554
const activeRootSpan = getActiveRootSpan ( ) ;
554
555
if ( activeRootSpan && ( spanToJSON ( activeRootSpan ) as { op ?: string } ) . op === 'navigation' ) {
555
- // For memory routers, we don't have a reliable way to get the current pathname
556
- // without accessing window.location, so we'll use targetPath for both cases
557
- const pathname = targetPath || ( isMemoryRouter ? WINDOW . location ?. pathname : undefined ) ;
556
+ // For memory routers, we should not access window.location; use targetPath only
557
+ const pathname = isMemoryRouter ? targetPath : targetPath || WINDOW . location ?. pathname ;
558
558
if ( pathname ) {
559
559
updateNavigationSpan (
560
560
activeRootSpan ,
@@ -566,7 +566,7 @@ function wrapPatchRoutesOnNavigation(
566
566
key : 'default' ,
567
567
} ,
568
568
Array . from ( allRoutes ) ,
569
- false ,
569
+ false , // forceUpdate = false since this is after lazy routes are loaded
570
570
_matchRoutes ,
571
571
) ;
572
572
}
@@ -603,15 +603,18 @@ export function handleNavigation(opts: {
603
603
basename ,
604
604
) ;
605
605
606
+ // Check if this might be a lazy route context
607
+ const isLazyRouteContext = isLikelyLazyRouteContext ( allRoutes || routes , location ) ;
608
+
606
609
const activeSpan = getActiveSpan ( ) ;
607
610
const spanJson = activeSpan && spanToJSON ( activeSpan ) ;
608
611
const isAlreadyInNavigationSpan = spanJson ?. op === 'navigation' ;
609
612
610
613
// Cross usage can result in multiple navigation spans being created without this check
611
614
if ( isAlreadyInNavigationSpan && activeSpan && spanJson ) {
612
- handleExistingNavigationSpan ( activeSpan , spanJson , name , source , false ) ;
615
+ handleExistingNavigationSpan ( activeSpan , spanJson , name , source , isLazyRouteContext ) ;
613
616
} else {
614
- createNewNavigationSpan ( client , name , source , version , false ) ;
617
+ createNewNavigationSpan ( client , name , source , version , isLazyRouteContext ) ;
615
618
}
616
619
}
617
620
}
@@ -783,6 +786,7 @@ export function handleExistingNavigationSpan(
783
786
}
784
787
}
785
788
789
+ // Always set the source attribute to keep it consistent with the current route
786
790
activeSpan ?. setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , source ) ;
787
791
}
788
792
0 commit comments