Skip to content

Commit c5b63b9

Browse files
committed
fix(react): Add POP guard for long-running pageload spans
1 parent 632f0b9 commit c5b63b9

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

packages/react/src/reactrouter-compat-utils/instrumentation.tsx

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ export function createV6CompatibleWrapCreateBrowserRouter<
241241

242242
const activeRootSpan = getActiveRootSpan();
243243

244+
// Track whether we've handled the initial POP to avoid creating navigation spans
245+
// for POP events that occur during the initial pageload phase.
246+
let hasHandledInitialPop = false;
247+
244248
// The initial load ends when `createBrowserRouter` is called.
245249
// This is the earliest convenient time to update the transaction name.
246250
// Callbacks to `router.subscribe` are not called for the initial load.
@@ -252,23 +256,19 @@ export function createV6CompatibleWrapCreateBrowserRouter<
252256
basename,
253257
allRoutes: Array.from(allRoutes),
254258
});
259+
hasHandledInitialPop = true;
255260
}
256261

257262
router.subscribe((state: RouterState) => {
258-
if (state.historyAction === 'PUSH' || state.historyAction === 'POP') {
259-
// Wait for the next render if loading an unsettled route
260-
if (state.navigation.state !== 'idle') {
261-
requestAnimationFrame(() => {
262-
handleNavigation({
263-
location: state.location,
264-
routes,
265-
navigationType: state.historyAction,
266-
version,
267-
basename,
268-
allRoutes: Array.from(allRoutes),
269-
});
270-
});
271-
} else {
263+
const shouldHandleNavigation =
264+
state.historyAction === 'PUSH' ||
265+
// Only handle POP events after the initial pageload POP has been processed.
266+
// This prevents creating navigation spans for POP events during long-running pageloads,
267+
// while still allowing legitimate back/forward button navigation to be tracked.
268+
(state.historyAction === 'POP' && hasHandledInitialPop);
269+
270+
if (shouldHandleNavigation) {
271+
const navigationHandler = (): void => {
272272
handleNavigation({
273273
location: state.location,
274274
routes,
@@ -277,6 +277,13 @@ export function createV6CompatibleWrapCreateBrowserRouter<
277277
basename,
278278
allRoutes: Array.from(allRoutes),
279279
});
280+
};
281+
282+
// Wait for the next render if loading an unsettled route
283+
if (state.navigation.state !== 'idle') {
284+
requestAnimationFrame(navigationHandler);
285+
} else {
286+
navigationHandler();
280287
}
281288
}
282289
});

0 commit comments

Comments
 (0)