@@ -174,6 +174,62 @@ describe('tanstackRouterBrowserTracingIntegration', () => {
174174 ) ;
175175 } ) ;
176176
177+ it ( 'clears url.template on pageload onResolved when the final destination does not match a route' , ( ) => {
178+ const integration = tanstackRouterBrowserTracingIntegration ( mockRouter , {
179+ instrumentPageLoad : true ,
180+ instrumentNavigation : false ,
181+ } ) ;
182+
183+ integration . afterAllSetup ( mockClient as any ) ;
184+
185+ const onResolvedCallback = getSubscribeCallback ( 'onResolved' ) ;
186+ expect ( onResolvedCallback ) . toBeDefined ( ) ;
187+
188+ // A redirect during pageload lands on a URL that no longer matches a route.
189+ ( mockRouter . matchRoutes as any ) . mockReturnValueOnce ( [ { routeId : '__root__' , params : { } } ] ) ;
190+
191+ onResolvedCallback ( {
192+ toLocation : { pathname : '/unknown/path' , search : { } } ,
193+ } ) ;
194+
195+ expect ( mockPageloadSpan . updateName ) . toHaveBeenCalledWith ( '/unknown/path' ) ;
196+ expect ( mockPageloadSpan . setAttribute ) . toHaveBeenLastCalledWith ( SEMANTIC_ATTRIBUTE_SENTRY_SOURCE , 'url' ) ;
197+ expect ( mockPageloadSpan . setAttributes ) . toHaveBeenLastCalledWith (
198+ expect . objectContaining ( {
199+ [ URL_TEMPLATE ] : undefined ,
200+ 'url.path' : '/unknown/path' ,
201+ 'url.full' : expect . any ( String ) ,
202+ } ) ,
203+ ) ;
204+ } ) ;
205+
206+ it ( 'unsubscribes the pageload onResolved handler after the first resolution' , ( ) => {
207+ const unsubscribe = vi . fn ( ) ;
208+ ( mockRouter . subscribe as any ) . mockImplementation ( ( eventType : string ) => {
209+ if ( eventType === 'onResolved' ) {
210+ return unsubscribe ;
211+ }
212+ return vi . fn ( ) ;
213+ } ) ;
214+
215+ const integration = tanstackRouterBrowserTracingIntegration ( mockRouter , {
216+ instrumentPageLoad : true ,
217+ instrumentNavigation : false ,
218+ } ) ;
219+
220+ integration . afterAllSetup ( mockClient as any ) ;
221+
222+ const onResolvedCallback = getSubscribeCallback ( 'onResolved' ) ;
223+ expect ( onResolvedCallback ) . toBeDefined ( ) ;
224+
225+ onResolvedCallback ( { toLocation : { pathname : '/test/456' , search : { } } } ) ;
226+
227+ // The handler must detach itself so later resolutions (e.g. subsequent navigations)
228+ // don't touch the pageload span again.
229+ expect ( unsubscribe ) . toHaveBeenCalledTimes ( 1 ) ;
230+ expect ( mockPageloadSpan . updateName ) . toHaveBeenCalledTimes ( 1 ) ;
231+ } ) ;
232+
177233 const getSubscribeCallback = ( eventType : string ) : ( ( ...args : any [ ] ) => void ) =>
178234 ( mockRouter . subscribe as any ) . mock . calls . find (
179235 ( call : [ string , ( ...args : any [ ] ) => void ] ) => call [ 0 ] === eventType ,
0 commit comments