@@ -44,6 +44,7 @@ import { checkRouteForAsyncHandler } from './lazy-routes';
4444import {
4545 getNormalizedName ,
4646 initializeRouterUtils ,
47+ isLikelyLazyRouteContext ,
4748 locationIsInsideDescendantRoute ,
4849 prefixWithSlash ,
4950 rebuildRoutePathFromAllRoutes ,
@@ -114,7 +115,7 @@ const allRoutes = new Set<RouteObject>();
114115export function processResolvedRoutes (
115116 resolvedRoutes : RouteObject [ ] ,
116117 parentRoute ?: RouteObject ,
117- currentLocation ? : Location ,
118+ currentLocation : Location | null = null ,
118119) : void {
119120 resolvedRoutes . forEach ( child => {
120121 allRoutes . add ( child ) ;
@@ -538,7 +539,7 @@ function wrapPatchRoutesOnNavigation(
538539 key : 'default' ,
539540 } ,
540541 Array . from ( allRoutes ) ,
541- true ,
542+ true , // forceUpdate = true since we're loading lazy routes
542543 _matchRoutes ,
543544 ) ;
544545 }
@@ -552,9 +553,8 @@ function wrapPatchRoutesOnNavigation(
552553 // Update navigation span after routes are patched
553554 const activeRootSpan = getActiveRootSpan ( ) ;
554555 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 ;
558558 if ( pathname ) {
559559 updateNavigationSpan (
560560 activeRootSpan ,
@@ -566,7 +566,7 @@ function wrapPatchRoutesOnNavigation(
566566 key : 'default' ,
567567 } ,
568568 Array . from ( allRoutes ) ,
569- false ,
569+ false , // forceUpdate = false since this is after lazy routes are loaded
570570 _matchRoutes ,
571571 ) ;
572572 }
@@ -603,15 +603,18 @@ export function handleNavigation(opts: {
603603 basename ,
604604 ) ;
605605
606+ // Check if this might be a lazy route context
607+ const isLazyRouteContext = isLikelyLazyRouteContext ( allRoutes || routes , location ) ;
608+
606609 const activeSpan = getActiveSpan ( ) ;
607610 const spanJson = activeSpan && spanToJSON ( activeSpan ) ;
608611 const isAlreadyInNavigationSpan = spanJson ?. op === 'navigation' ;
609612
610613 // Cross usage can result in multiple navigation spans being created without this check
611614 if ( isAlreadyInNavigationSpan && activeSpan && spanJson ) {
612- handleExistingNavigationSpan ( activeSpan , spanJson , name , source , false ) ;
615+ handleExistingNavigationSpan ( activeSpan , spanJson , name , source , isLazyRouteContext ) ;
613616 } else {
614- createNewNavigationSpan ( client , name , source , version , false ) ;
617+ createNewNavigationSpan ( client , name , source , version , isLazyRouteContext ) ;
615618 }
616619 }
617620}
@@ -783,6 +786,7 @@ export function handleExistingNavigationSpan(
783786 }
784787 }
785788
789+ // Always set the source attribute to keep it consistent with the current route
786790 activeSpan ?. setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , source ) ;
787791}
788792
0 commit comments