@@ -39,9 +39,10 @@ import type {
3939 UseNavigationType ,
4040 UseRoutes ,
4141} from '../types' ;
42- import { checkRouteForAsyncHandler , updateNavigationSpanWithLazyRoutes } from './lazy-routes' ;
42+ import { checkRouteForAsyncHandler } from './lazy-routes' ;
4343import {
4444 getGlobalLocation ,
45+ getGlobalPathname ,
4546 getNormalizedName ,
4647 initializeRouterUtils ,
4748 locationIsInsideDescendantRoute ,
@@ -59,6 +60,53 @@ let _enableAsyncRouteHandlers: boolean = false;
5960
6061const CLIENTS_WITH_INSTRUMENT_NAVIGATION = new WeakSet < Client > ( ) ;
6162
63+ /**
64+ * Updates a navigation span with the correct route name after lazy routes have been loaded.
65+ */
66+ export function updateNavigationSpan (
67+ activeRootSpan : Span ,
68+ location : Location ,
69+ allRoutes : RouteObject [ ] ,
70+ forceUpdate = false ,
71+ matchRoutes : MatchRoutes ,
72+ ) : void {
73+ // Check if this span has already been named to avoid multiple updates
74+ // But allow updates if this is a forced update (e.g., when lazy routes are loaded)
75+ const hasBeenNamed =
76+ ! forceUpdate &&
77+ (
78+ activeRootSpan as {
79+ __sentry_navigation_name_set__ ?: boolean ;
80+ }
81+ ) ?. __sentry_navigation_name_set__ ;
82+
83+ if ( ! hasBeenNamed ) {
84+ // Get fresh branches for the current location with all loaded routes
85+ const currentBranches = matchRoutes ( allRoutes , location ) ;
86+ const [ name , source ] = resolveRouteNameAndSource (
87+ location ,
88+ allRoutes ,
89+ allRoutes ,
90+ ( currentBranches as RouteMatch [ ] ) || [ ] ,
91+ '' ,
92+ ) ;
93+
94+ // Only update if we have a valid name and the span hasn't finished
95+ const spanJson = spanToJSON ( activeRootSpan ) ;
96+ if ( name && ! spanJson . timestamp ) {
97+ activeRootSpan . updateName ( name ) ;
98+ activeRootSpan . setAttribute ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , source ) ;
99+
100+ // Mark this span as having its name set to prevent future updates
101+ addNonEnumerableProperty (
102+ activeRootSpan as { __sentry_navigation_name_set__ ?: boolean } ,
103+ '__sentry_navigation_name_set__' ,
104+ true ,
105+ ) ;
106+ }
107+ }
108+ }
109+
62110export interface ReactRouterOptions {
63111 useEffect : UseEffect ;
64112 useLocation : UseLocation ;
@@ -131,7 +179,7 @@ export function processResolvedRoutes(
131179 ) ;
132180 } else if ( spanOp === 'navigation' ) {
133181 // For navigation spans, update the name with the newly loaded routes
134- updateNavigationSpanWithLazyRoutes ( activeRootSpan , location , Array . from ( allRoutes ) , false , _matchRoutes ) ;
182+ updateNavigationSpan ( activeRootSpan , location , Array . from ( allRoutes ) , false , _matchRoutes ) ;
135183 }
136184 }
137185 }
@@ -162,7 +210,7 @@ function wrapPatchRoutesOnNavigation(
162210 addRoutesToAllRoutes ( children ) ;
163211 const activeRootSpan = getActiveRootSpan ( ) ;
164212 if ( activeRootSpan && ( spanToJSON ( activeRootSpan ) as { op ?: string } ) . op === 'navigation' ) {
165- updateNavigationSpanWithLazyRoutes (
213+ updateNavigationSpan (
166214 activeRootSpan ,
167215 {
168216 pathname : targetPath ,
@@ -188,9 +236,9 @@ function wrapPatchRoutesOnNavigation(
188236 if ( activeRootSpan && ( spanToJSON ( activeRootSpan ) as { op ?: string } ) . op === 'navigation' ) {
189237 // For memory routers, we don't have a reliable way to get the current pathname
190238 // without accessing window.location, so we'll use targetPath for both cases
191- const pathname = targetPath || ( isMemoryRouter ? getGlobalLocation ( ) ?. pathname : undefined ) ;
239+ const pathname = targetPath || ( isMemoryRouter ? getGlobalPathname ( ) : undefined ) ;
192240 if ( pathname ) {
193- updateNavigationSpanWithLazyRoutes (
241+ updateNavigationSpan (
194242 activeRootSpan ,
195243 {
196244 pathname,
@@ -421,7 +469,7 @@ export function createReactRouterV6CompatibleTracingIntegration(
421469 afterAllSetup ( client ) {
422470 integration . afterAllSetup ( client ) ;
423471
424- const initPathName = getGlobalLocation ( ) ?. pathname ;
472+ const initPathName = getGlobalPathname ( ) ;
425473 if ( instrumentPageLoad && initPathName ) {
426474 startBrowserTracingPageLoadSpan ( client , {
427475 name : initPathName ,
0 commit comments