@sentry/react 11.0.0-beta.1 → 11.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const reactRouter = require('react-router');
4
+ const reactrouter_compat = require('./reactrouter.compat.js');
5
+
6
+ function reactRouterBrowserTracingIntegration(options = {}) {
7
+ return reactrouter_compat.reactRouterBrowserTracingIntegration({
8
+ useLocation: reactRouter.useLocation,
9
+ useNavigationType: reactRouter.useNavigationType,
10
+ createRoutesFromChildren: reactRouter.createRoutesFromChildren,
11
+ matchRoutes: reactRouter.matchRoutes,
12
+ ...options
13
+ });
14
+ }
15
+
16
+ exports.wrapCreateBrowserRouter = reactrouter_compat.wrapCreateBrowserRouter;
17
+ exports.wrapCreateMemoryRouter = reactrouter_compat.wrapCreateMemoryRouter;
18
+ exports.wrapReactRouterRouting = reactrouter_compat.wrapReactRouterRouting;
19
+ exports.wrapUseRoutes = reactrouter_compat.wrapUseRoutes;
20
+ exports.reactRouterBrowserTracingIntegration = reactRouterBrowserTracingIntegration;
21
+ //# sourceMappingURL=react-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-router.js","sources":["../../src/react-router.ts"],"sourcesContent":["import type { browserTracingIntegration } from '@sentry/browser';\nimport type { Integration } from '@sentry/core';\nimport { createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router';\nimport type { ReactRouterOptions } from './reactrouter-compat-utils';\nimport { reactRouterBrowserTracingIntegration as reactRouterBrowserTracingIntegrationBase } from './reactrouter.compat';\n\n// The routing wrappers (`wrapReactRouterRouting`, `wrapUseRoutes`, `wrapCreateBrowserRouter`,\n// `wrapCreateMemoryRouter`) do not need the hooks - they read the config the integration below stored on\n// the client - so they are re-exported unchanged from the main entry point.\nexport {\n wrapReactRouterRouting,\n wrapCreateBrowserRouter,\n wrapCreateMemoryRouter,\n wrapUseRoutes,\n} from './reactrouter.compat';\n\ntype BrowserTracingOptions = Parameters<typeof browserTracingIntegration>[0];\n\n/**\n * A browser tracing integration for React Router v6, v7 and v8.\n *\n * Unlike {@link reactRouterBrowserTracingIntegration} exported from `@sentry/react`, this variant pulls the\n * required router hooks (`useLocation`, `useNavigationType`, `createRoutesFromChildren` and `matchRoutes`)\n * directly from `react-router`, so you don't have to pass them in:\n *\n * ```ts\n * import { reactRouterBrowserTracingIntegration } from '@sentry/react/react-router';\n *\n * Sentry.init({ integrations: [reactRouterBrowserTracingIntegration()] });\n * ```\n *\n * Any of the hooks can still be overridden via `options` (e.g. to supply the `react-router-dom` versions in v6).\n *\n * This requires `react-router` to be resolvable (it is declared as an optional peer dependency). If you are on\n * React Router v6 with only `react-router-dom` installed, either add `react-router` as a dependency or import\n * `reactRouterBrowserTracingIntegration` from `@sentry/react` and pass the hooks explicitly.\n */\nexport function reactRouterBrowserTracingIntegration(\n options: BrowserTracingOptions & Partial<ReactRouterOptions> = {},\n): Integration {\n return reactRouterBrowserTracingIntegrationBase({\n useLocation,\n useNavigationType,\n createRoutesFromChildren,\n matchRoutes,\n ...options,\n });\n}\n"],"names":["reactRouterBrowserTracingIntegrationBase","useLocation","useNavigationType","createRoutesFromChildren","matchRoutes"],"mappings":";;;;;AAqCO,SAAS,oCAAA,CACd,OAAA,GAA+D,EAAC,EACnD;AACb,EAAA,OAAOA,uDAAA,CAAyC;AAAA,iBAC9CC,uBAAA;AAAA,uBACAC,6BAAA;AAAA,8BACAC,oCAAA;AAAA,iBACAC,uBAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH;;;;;;;;"}
@@ -10,16 +10,10 @@ const utils = require('./utils.js');
10
10
  const attributes = require('@sentry/conventions/attributes');
11
11
  const op = require('@sentry/conventions/op');
12
12
 
13
- let _useEffect;
14
- let _useLocation;
15
- let _useNavigationType;
16
- let _createRoutesFromChildren;
17
- let _matchRoutes;
18
- let _enableAsyncRouteHandlers = false;
19
- let _lazyRouteTimeout = 3e3;
20
- let _lazyRouteManifest;
21
- let _basename = "";
22
- const CLIENTS_WITH_INSTRUMENT_NAVIGATION = /* @__PURE__ */ new WeakSet();
13
+ const reactRouterConfigByClient = /* @__PURE__ */ new WeakMap();
14
+ function getRouterConfig(client) {
15
+ return client ? reactRouterConfigByClient.get(client) : void 0;
16
+ }
23
17
  const useIsomorphicLayoutEffect = browser.WINDOW?.document ? React.useLayoutEffect : React.useEffect;
24
18
  const activeNavigationSpans = /* @__PURE__ */ new WeakMap();
25
19
  const allRoutes = /* @__PURE__ */ new Set();
@@ -103,11 +97,11 @@ function resolveDeferredLazyRoutePromise(span) {
103
97
  }
104
98
  }
105
99
  }
106
- function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = null, capturedSpan) {
100
+ function processResolvedRoutes(resolvedRoutes, config, parentRoute, currentLocation = null, capturedSpan) {
107
101
  resolvedRoutes.forEach((child) => {
108
102
  allRoutes.add(child);
109
- if (_enableAsyncRouteHandlers) {
110
- lazyRoutes.checkRouteForAsyncHandler(child, processResolvedRoutes);
103
+ if (config.enableAsyncRouteHandlers) {
104
+ lazyRoutes.checkRouteForAsyncHandler(child, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
111
105
  }
112
106
  });
113
107
  if (parentRoute) {
@@ -136,29 +130,35 @@ function processResolvedRoutes(resolvedRoutes, parentRoute, currentLocation = nu
136
130
  activeRootSpan: targetSpan,
137
131
  location: { pathname: location.pathname },
138
132
  routes: Array.from(allRoutes),
139
- allRoutes: Array.from(allRoutes)
133
+ allRoutes: Array.from(allRoutes),
134
+ config
140
135
  });
141
136
  } else if (spanOp === "navigation") {
142
- updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, _matchRoutes);
137
+ updateNavigationSpan(targetSpan, location, Array.from(allRoutes), false, config);
143
138
  }
144
139
  }
145
140
  }
146
141
  }
147
- function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, matchRoutes) {
142
+ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate = false, config) {
148
143
  const { name: currentName, end_timestamp, attributes: attributes$1 } = core.spanToJSON(activeRootSpan);
144
+ const spanPathname = activeRootSpan?.__sentry_navigation_pathname__;
145
+ if (spanPathname !== void 0 && spanPathname !== location.pathname) {
146
+ debugBuild.DEBUG_BUILD && core.debug.log(
147
+ `[React Router] Not renaming the navigation span for "${spanPathname}" with the route of "${location.pathname}"`
148
+ );
149
+ return;
150
+ }
149
151
  const hasBeenNamed = activeRootSpan?.__sentry_navigation_name_set__;
150
152
  const currentNameHasWildcard = currentName && utils.transactionNameHasWildcard(currentName);
151
153
  const shouldUpdate = !hasBeenNamed || forceUpdate || currentNameHasWildcard;
152
154
  if (shouldUpdate && !end_timestamp) {
153
- const currentBranches = matchRoutes(allRoutes2, location);
155
+ const currentBranches = config.matchRoutes(allRoutes2, location);
154
156
  const [name, source] = utils.resolveRouteNameAndSource(
155
157
  location,
156
158
  allRoutes2,
157
159
  allRoutes2,
158
160
  currentBranches || [],
159
- _basename,
160
- _lazyRouteManifest,
161
- _enableAsyncRouteHandlers
161
+ config
162
162
  );
163
163
  const currentSource = attributes$1[attributes.SENTRY_SEGMENT_NAME_SOURCE];
164
164
  const isImprovement = name && (!currentName || // No current name - always set
@@ -179,7 +179,7 @@ function updateNavigationSpan(activeRootSpan, location, allRoutes2, forceUpdate
179
179
  }
180
180
  }
181
181
  }
182
- function setupRouterSubscription(router, routes, version, basename, activeRootSpan) {
182
+ function setupRouterSubscription(router, routes, version, activeRootSpan, config) {
183
183
  let isInitialPageloadComplete = false;
184
184
  let hasSeenPageloadSpan = !!activeRootSpan && core.spanToJSON(activeRootSpan).attributes[attributes.SENTRY_OP] === "pageload";
185
185
  let hasSeenPopAfterPageload = false;
@@ -213,8 +213,8 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
213
213
  routes,
214
214
  navigationType: state.historyAction,
215
215
  version,
216
- basename,
217
- allRoutes: Array.from(allRoutes)
216
+ allRoutes: Array.from(allRoutes),
217
+ config
218
218
  });
219
219
  };
220
220
  if (state.navigation.state !== "idle") {
@@ -236,17 +236,19 @@ function setupRouterSubscription(router, routes, version, basename, activeRootSp
236
236
  });
237
237
  }
238
238
  function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version) {
239
- if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
240
- debugBuild.DEBUG_BUILD && core.debug.warn(
241
- `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`
242
- );
243
- return createRouterFunction;
244
- }
245
239
  return function(routes, opts) {
240
+ const base = getRouterConfig(core.getClient());
241
+ if (!base) {
242
+ debugBuild.DEBUG_BUILD && core.debug.warn(
243
+ `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
244
+ );
245
+ return createRouterFunction(routes, opts);
246
+ }
247
+ const config = { ...base, basename: opts?.basename || "" };
246
248
  addRoutesToAllRoutes(routes);
247
- if (_enableAsyncRouteHandlers) {
249
+ if (config.enableAsyncRouteHandlers) {
248
250
  for (const route of routes) {
249
- lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
251
+ lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
250
252
  }
251
253
  }
252
254
  const activeRootSpan = utils.getActiveRootSpan();
@@ -255,35 +257,35 @@ function createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, version
255
257
  core.addNonEnumerableProperty(activeRootSpan, "__sentry_may_have_lazy_routes__", true);
256
258
  createDeferredLazyRoutePromise(activeRootSpan);
257
259
  }
258
- const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan);
260
+ const wrappedOpts = wrapPatchRoutesOnNavigation(opts, false, activeRootSpan, config);
259
261
  const router = createRouterFunction(routes, wrappedOpts);
260
- const basename = opts?.basename;
261
262
  if (router.state.historyAction === "POP" && activeRootSpan) {
262
263
  updatePageloadTransaction({
263
264
  activeRootSpan,
264
265
  location: router.state.location,
265
266
  routes,
266
- basename,
267
- allRoutes: Array.from(allRoutes)
267
+ allRoutes: Array.from(allRoutes),
268
+ config
268
269
  });
269
270
  }
270
- _basename = basename || "";
271
- setupRouterSubscription(router, routes, version, basename, activeRootSpan);
271
+ setupRouterSubscription(router, routes, version, activeRootSpan, config);
272
272
  return router;
273
273
  };
274
274
  }
275
275
  function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version) {
276
- if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
277
- debugBuild.DEBUG_BUILD && core.debug.warn(
278
- `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because of one or more missing parameters.`
279
- );
280
- return createRouterFunction;
281
- }
282
276
  return function(routes, opts) {
277
+ const base = getRouterConfig(core.getClient());
278
+ if (!base) {
279
+ debugBuild.DEBUG_BUILD && core.debug.warn(
280
+ `reactRouter${version ? `V${version}` : ""}Instrumentation was unable to wrap the \`createMemoryRouter\` function because the React Router browser tracing integration was not set up. Make sure \`Sentry.init()\` runs before the router is created.`
281
+ );
282
+ return createRouterFunction(routes, opts);
283
+ }
284
+ const config = { ...base, basename: opts?.basename || "" };
283
285
  addRoutesToAllRoutes(routes);
284
- if (_enableAsyncRouteHandlers) {
286
+ if (config.enableAsyncRouteHandlers) {
285
287
  for (const route of routes) {
286
- lazyRoutes.checkRouteForAsyncHandler(route, processResolvedRoutes);
288
+ lazyRoutes.checkRouteForAsyncHandler(route, (r, p, l, s) => processResolvedRoutes(r, config, p, l, s));
287
289
  }
288
290
  }
289
291
  const memoryActiveRootSpanEarly = utils.getActiveRootSpan();
@@ -292,9 +294,8 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
292
294
  core.addNonEnumerableProperty(memoryActiveRootSpanEarly, "__sentry_may_have_lazy_routes__", true);
293
295
  createDeferredLazyRoutePromise(memoryActiveRootSpanEarly);
294
296
  }
295
- const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly);
297
+ const wrappedOpts = wrapPatchRoutesOnNavigation(opts, true, memoryActiveRootSpanEarly, config);
296
298
  const router = createRouterFunction(routes, wrappedOpts);
297
- const basename = opts?.basename;
298
299
  let initialEntry = void 0;
299
300
  const initialEntries = opts?.initialEntries;
300
301
  const initialIndex = opts?.initialIndex;
@@ -308,19 +309,17 @@ function createV6CompatibleWrapCreateMemoryRouter(createRouterFunction, version)
308
309
  activeRootSpan: memoryActiveRootSpan,
309
310
  location,
310
311
  routes,
311
- basename,
312
- allRoutes: Array.from(allRoutes)
312
+ allRoutes: Array.from(allRoutes),
313
+ config
313
314
  });
314
315
  }
315
- _basename = basename || "";
316
- setupRouterSubscription(router, routes, version, basename, memoryActiveRootSpan);
316
+ setupRouterSubscription(router, routes, version, memoryActiveRootSpan, config);
317
317
  return router;
318
318
  };
319
319
  }
320
320
  function createReactRouterV6CompatibleTracingIntegration(options, version) {
321
321
  const integration = browser.browserTracingIntegration({ ...options, instrumentPageLoad: false, instrumentNavigation: false });
322
322
  const {
323
- useEffect,
324
323
  useLocation,
325
324
  useNavigationType,
326
325
  createRoutesFromChildren,
@@ -332,15 +331,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
332
331
  lazyRouteTimeout,
333
332
  lazyRouteManifest
334
333
  } = options;
335
- return {
336
- ...integration,
334
+ return core.extendIntegration(integration, {
337
335
  setup(client) {
338
- integration.setup(client);
339
336
  const finalTimeout = options.finalTimeout ?? 3e4;
340
337
  const defaultMaxWait = (options.idleTimeout ?? 1e3) * 3;
341
338
  const configuredMaxWait = lazyRouteTimeout ?? defaultMaxWait;
339
+ let resolvedLazyRouteTimeout;
342
340
  if (configuredMaxWait === Infinity) {
343
- _lazyRouteTimeout = finalTimeout;
341
+ resolvedLazyRouteTimeout = finalTimeout;
344
342
  debugBuild.DEBUG_BUILD && core.debug.log(
345
343
  "[React Router] lazyRouteTimeout set to Infinity, capping at finalTimeout:",
346
344
  finalTimeout,
@@ -348,7 +346,7 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
348
346
  );
349
347
  } else if (Number.isNaN(configuredMaxWait)) {
350
348
  debugBuild.DEBUG_BUILD && core.debug.warn("[React Router] lazyRouteTimeout must be a number, falling back to default:", defaultMaxWait);
351
- _lazyRouteTimeout = defaultMaxWait;
349
+ resolvedLazyRouteTimeout = defaultMaxWait;
352
350
  } else if (configuredMaxWait < 0) {
353
351
  debugBuild.DEBUG_BUILD && core.debug.warn(
354
352
  "[React Router] lazyRouteTimeout must be non-negative or Infinity, got:",
@@ -356,21 +354,30 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
356
354
  "falling back to:",
357
355
  defaultMaxWait
358
356
  );
359
- _lazyRouteTimeout = defaultMaxWait;
357
+ resolvedLazyRouteTimeout = defaultMaxWait;
360
358
  } else {
361
- _lazyRouteTimeout = configuredMaxWait;
359
+ resolvedLazyRouteTimeout = configuredMaxWait;
360
+ }
361
+ if (typeof useLocation === "function" && typeof useNavigationType === "function" && typeof createRoutesFromChildren === "function" && typeof matchRoutes === "function") {
362
+ reactRouterConfigByClient.set(client, {
363
+ useLocation,
364
+ useNavigationType,
365
+ createRoutesFromChildren,
366
+ matchRoutes,
367
+ stripBasename: stripBasename || false,
368
+ enableAsyncRouteHandlers,
369
+ instrumentNavigation,
370
+ lazyRouteTimeout: resolvedLazyRouteTimeout,
371
+ lazyRouteManifest,
372
+ basename: ""
373
+ });
374
+ } else {
375
+ debugBuild.DEBUG_BUILD && core.debug.warn(
376
+ "[React Router] Skipping route instrumentation because `useLocation`, `useNavigationType`, `createRoutesFromChildren` or `matchRoutes` was not provided. Pass them to `reactRouterBrowserTracingIntegration`, or import it from `@sentry/react/react-router` to have them supplied automatically."
377
+ );
362
378
  }
363
- _useEffect = useEffect;
364
- _useLocation = useLocation;
365
- _useNavigationType = useNavigationType;
366
- _matchRoutes = matchRoutes;
367
- _createRoutesFromChildren = createRoutesFromChildren;
368
- _enableAsyncRouteHandlers = enableAsyncRouteHandlers;
369
- _lazyRouteManifest = lazyRouteManifest;
370
- utils.initializeRouterUtils(matchRoutes, stripBasename || false);
371
379
  },
372
380
  afterAllSetup(client) {
373
- integration.afterAllSetup(client);
374
381
  const initPathName = browser.WINDOW.location?.pathname;
375
382
  if (instrumentPageLoad && initPathName) {
376
383
  browser.startBrowserTracingPageLoadSpan(client, {
@@ -384,25 +391,14 @@ function createReactRouterV6CompatibleTracingIntegration(options, version) {
384
391
  }
385
392
  });
386
393
  }
387
- if (instrumentNavigation) {
388
- CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client);
389
- }
390
394
  }
391
- };
395
+ });
392
396
  }
393
397
  function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
394
- if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) {
395
- debugBuild.DEBUG_BUILD && core.debug.warn(
396
- "reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters."
397
- );
398
- return origUseRoutes;
399
- }
400
- const SentryRoutes = (props) => {
398
+ const RouteReporter = ({ config, routes, locationArg }) => {
401
399
  const isMountRenderPass = React.useRef(true);
402
- const { routes, locationArg } = props;
403
- const Routes = origUseRoutes(routes, locationArg);
404
- const location = _useLocation();
405
- const navigationType = _useNavigationType();
400
+ const location = config.useLocation();
401
+ const navigationType = config.useNavigationType();
406
402
  const stableLocationParam = typeof locationArg === "string" || locationArg?.pathname ? locationArg : location;
407
403
  useIsomorphicLayoutEffect(() => {
408
404
  const added = addRoutesToAllRoutes(routes);
@@ -415,7 +411,8 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
415
411
  activeRootSpan: utils.getActiveRootSpan(),
416
412
  location: normalizedLocation,
417
413
  routes,
418
- allRoutes: Array.from(allRoutes)
414
+ allRoutes: Array.from(allRoutes),
415
+ config
419
416
  });
420
417
  isMountRenderPass.current = false;
421
418
  } else {
@@ -424,17 +421,26 @@ function createV6CompatibleWrapUseRoutes(origUseRoutes, version) {
424
421
  routes,
425
422
  navigationType,
426
423
  version,
427
- allRoutes: Array.from(allRoutes)
424
+ allRoutes: Array.from(allRoutes),
425
+ config
428
426
  });
429
427
  }
430
428
  }, [navigationType, stableLocationParam]);
431
- return Routes;
429
+ return null;
430
+ };
431
+ const SentryRoutesWrapper = ({
432
+ routes,
433
+ locationArg
434
+ }) => {
435
+ const config = getRouterConfig(core.getClient());
436
+ const routesElement = origUseRoutes(routes, locationArg);
437
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, routesElement, config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routes, locationArg }) : null);
432
438
  };
433
439
  return (routes, locationArg) => {
434
- return /* @__PURE__ */ React.createElement(SentryRoutes, { routes, locationArg });
440
+ return /* @__PURE__ */ React.createElement(SentryRoutesWrapper, { routes, locationArg });
435
441
  };
436
442
  }
437
- function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan) {
443
+ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter, capturedSpan, config) {
438
444
  if (!opts || !("patchRoutesOnNavigation" in opts) || typeof opts.patchRoutesOnNavigation !== "function") {
439
445
  return opts || {};
440
446
  }
@@ -473,7 +479,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
473
479
  { pathname: targetPath, search: "", hash: "", state: null, key: "default" },
474
480
  Array.from(allRoutes),
475
481
  true,
476
- _matchRoutes
482
+ config
477
483
  );
478
484
  }
479
485
  return originalPatch(routeId, children);
@@ -501,7 +507,7 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
501
507
  { pathname, search: "", hash: "", state: null, key: "default" },
502
508
  Array.from(allRoutes),
503
509
  false,
504
- _matchRoutes
510
+ config
505
511
  );
506
512
  }
507
513
  }
@@ -515,10 +521,10 @@ function wrapPatchRoutesOnNavigation(opts, isMemoryRouter = false, capturedSpan)
515
521
  };
516
522
  }
517
523
  function handleNavigation(opts) {
518
- const { location, routes, navigationType, version, matches, basename, allRoutes: allRoutes2 } = opts;
519
- const branches = Array.isArray(matches) ? matches : _matchRoutes(allRoutes2 || routes, location, basename);
524
+ const { location, routes, navigationType, version, config, matches, allRoutes: allRoutes2 } = opts;
525
+ const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
520
526
  const client = core.getClient();
521
- if (!client || !CLIENTS_WITH_INSTRUMENT_NAVIGATION.has(client)) {
527
+ if (!client || !config.instrumentNavigation) {
522
528
  return;
523
529
  }
524
530
  const activeRootSpan = utils.getActiveRootSpan();
@@ -531,9 +537,7 @@ function handleNavigation(opts) {
531
537
  allRoutes2 || routes,
532
538
  allRoutes2 || routes,
533
539
  branches,
534
- basename,
535
- _lazyRouteManifest,
536
- _enableAsyncRouteHandlers
540
+ config
537
541
  );
538
542
  const locationKey = computeLocationKey(location);
539
543
  const trackedNav = activeNavigationSpans.get(client);
@@ -591,6 +595,7 @@ function handleNavigation(opts) {
591
595
  throw e;
592
596
  }
593
597
  if (navigationSpan) {
598
+ core.addNonEnumerableProperty(navigationSpan, "__sentry_navigation_pathname__", location.pathname);
594
599
  activeNavigationSpans.set(client, {
595
600
  span: navigationSpan,
596
601
  routeName: placeholderEntry.routeName,
@@ -598,7 +603,7 @@ function handleNavigation(opts) {
598
603
  pathname: location.pathname,
599
604
  locationKey
600
605
  });
601
- patchSpanEnd(navigationSpan, location, routes, basename, "navigation");
606
+ patchSpanEnd(navigationSpan, location, routes, "navigation", config);
602
607
  } else {
603
608
  activeNavigationSpans.delete(client);
604
609
  }
@@ -638,20 +643,18 @@ function updatePageloadTransaction({
638
643
  activeRootSpan,
639
644
  location,
640
645
  routes,
646
+ config,
641
647
  matches,
642
- basename,
643
648
  allRoutes: allRoutes2
644
649
  }) {
645
- const branches = Array.isArray(matches) ? matches : _matchRoutes(allRoutes2 || routes, location, basename);
650
+ const branches = Array.isArray(matches) ? matches : config.matchRoutes(allRoutes2 || routes, location, config.basename);
646
651
  if (branches) {
647
652
  const [name, source] = utils.resolveRouteNameAndSource(
648
653
  location,
649
654
  allRoutes2 || routes,
650
655
  allRoutes2 || routes,
651
656
  branches,
652
- basename,
653
- _lazyRouteManifest,
654
- _enableAsyncRouteHandlers
657
+ config
655
658
  );
656
659
  core.getCurrentScope().setTransactionName(name || "/");
657
660
  if (activeRootSpan) {
@@ -662,10 +665,10 @@ function updatePageloadTransaction({
662
665
  if (source === "route") {
663
666
  activeRootSpan.setAttribute(attributes.URL_TEMPLATE, name);
664
667
  }
665
- patchSpanEnd(activeRootSpan, location, routes, basename, "pageload");
668
+ patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
666
669
  }
667
670
  } else if (activeRootSpan) {
668
- patchSpanEnd(activeRootSpan, location, routes, basename, "pageload");
671
+ patchSpanEnd(activeRootSpan, location, routes, "pageload", config);
669
672
  }
670
673
  }
671
674
  function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSource, allowNoCurrentName = false) {
@@ -684,7 +687,7 @@ function shouldUpdateWildcardSpanName(currentName, currentSource, newName, newSo
684
687
  }
685
688
  return false;
686
689
  }
687
- function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes2) {
690
+ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes2, config) {
688
691
  try {
689
692
  const currentSource = spanJson.attributes[attributes.SENTRY_SEGMENT_NAME_SOURCE];
690
693
  if (currentSource === "route" && currentName && !utils.transactionNameHasWildcard(currentName)) {
@@ -692,19 +695,11 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
692
695
  }
693
696
  const currentAllRoutes = Array.from(allRoutes2);
694
697
  const routesToUse = currentAllRoutes.length > 0 ? currentAllRoutes : routes;
695
- const branches = _matchRoutes(routesToUse, location, basename);
698
+ const branches = config.matchRoutes(routesToUse, location, config.basename);
696
699
  if (!branches) {
697
700
  return;
698
701
  }
699
- const [name, source] = utils.resolveRouteNameAndSource(
700
- location,
701
- routesToUse,
702
- routesToUse,
703
- branches,
704
- basename,
705
- _lazyRouteManifest,
706
- _enableAsyncRouteHandlers
707
- );
702
+ const [name, source] = utils.resolveRouteNameAndSource(location, routesToUse, routesToUse, branches, config);
708
703
  const isImprovement = shouldUpdateWildcardSpanName(currentName, currentSource, name, source, true);
709
704
  const spanNotEnded = spanType === "pageload" || !spanJson.end_timestamp;
710
705
  if (isImprovement && spanNotEnded) {
@@ -721,7 +716,7 @@ function tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, route
721
716
  debugBuild.DEBUG_BUILD && core.debug.warn(`Error updating span details before ending: ${error}`);
722
717
  }
723
718
  }
724
- function patchSpanEnd(span, location, routes, basename, spanType) {
719
+ function patchSpanEnd(span, location, routes, spanType, config) {
725
720
  const patchedPropertyName = `__sentry_${spanType}_end_patched__`;
726
721
  const hasEndBeenPatched = span?.[patchedPropertyName];
727
722
  if (hasEndBeenPatched || !span.end) {
@@ -752,18 +747,18 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
752
747
  const hasPendingOrMayHaveLazyRoutes = pendingPromises && pendingPromises.size > 0 || mayHaveLazyRoutes;
753
748
  const shouldWaitForLazyRoutes = hasPendingOrMayHaveLazyRoutes && currentName && (utils.transactionNameHasWildcard(currentName) || currentSource !== "route");
754
749
  if (shouldWaitForLazyRoutes) {
755
- if (_lazyRouteTimeout === 0) {
756
- tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
750
+ if (config.lazyRouteTimeout === 0) {
751
+ tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
757
752
  cleanupNavigationSpan();
758
753
  originalEnd(endTimestamp);
759
754
  return;
760
755
  }
761
- const timeoutPromise = new Promise((r) => setTimeout(r, _lazyRouteTimeout));
756
+ const timeoutPromise = new Promise((r) => setTimeout(r, config.lazyRouteTimeout));
762
757
  let waitPromise;
763
758
  if (pendingPromises && pendingPromises.size > 0) {
764
759
  const allSettled = Promise.allSettled(pendingPromises).then(() => {
765
760
  });
766
- waitPromise = _lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
761
+ waitPromise = config.lazyRouteTimeout === Infinity ? allSettled : Promise.race([allSettled, timeoutPromise]);
767
762
  } else {
768
763
  waitPromise = timeoutPromise;
769
764
  }
@@ -775,9 +770,9 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
775
770
  updatedSpanJson.name,
776
771
  location,
777
772
  routes,
778
- basename,
779
773
  spanType,
780
- allRoutes
774
+ allRoutes,
775
+ config
781
776
  );
782
777
  cleanupNavigationSpan();
783
778
  originalEnd(endTimestamp);
@@ -787,24 +782,23 @@ function patchSpanEnd(span, location, routes, basename, spanType) {
787
782
  });
788
783
  return;
789
784
  }
790
- tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, basename, spanType, allRoutes);
785
+ tryUpdateSpanNameBeforeEnd(span, spanJson, currentName, location, routes, spanType, allRoutes, config);
791
786
  cleanupNavigationSpan();
792
787
  originalEnd(endTimestamp);
793
788
  };
794
789
  core.addNonEnumerableProperty(span, patchedPropertyName, true);
795
790
  }
796
791
  function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
797
- if (!_useEffect || !_useLocation || !_useNavigationType || !_createRoutesFromChildren || !_matchRoutes) {
798
- debugBuild.DEBUG_BUILD && core.debug.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.
799
- useEffect: ${_useEffect}. useLocation: ${_useLocation}. useNavigationType: ${_useNavigationType}.
800
- createRoutesFromChildren: ${_createRoutesFromChildren}. matchRoutes: ${_matchRoutes}.`);
801
- return Routes;
802
- }
803
- const SentryRoutes = (props) => {
792
+ const RouteReporter = ({
793
+ config,
794
+ routeChildren
795
+ }) => {
804
796
  const isMountRenderPass = React.useRef(true);
805
- const location = _useLocation();
806
- const navigationType = _useNavigationType();
807
- const routes = _createRoutesFromChildren(props.children);
797
+ const location = config.useLocation();
798
+ const navigationType = config.useNavigationType();
799
+ const routes = config.createRoutesFromChildren(
800
+ routeChildren
801
+ );
808
802
  useIsomorphicLayoutEffect(() => {
809
803
  const added = addRoutesToAllRoutes(routes);
810
804
  return () => removeRoutesFromAllRoutes(added);
@@ -816,17 +810,36 @@ function createV6CompatibleWithSentryReactRouterRouting(Routes, version) {
816
810
  activeRootSpan: utils.getActiveRootSpan(),
817
811
  location,
818
812
  routes,
819
- allRoutes: Array.from(allRoutes)
813
+ allRoutes: Array.from(allRoutes),
814
+ config
820
815
  });
821
816
  isMountRenderPass.current = false;
822
817
  } else {
823
- handleNavigation({ location, routes, navigationType, version, allRoutes: Array.from(allRoutes) });
818
+ handleNavigation({
819
+ location,
820
+ routes,
821
+ navigationType,
822
+ version,
823
+ allRoutes: Array.from(allRoutes),
824
+ config
825
+ });
824
826
  }
825
827
  },
826
828
  // Re-run only on location/navigation changes, not children changes
827
829
  [location, navigationType]
828
830
  );
829
- return /* @__PURE__ */ React.createElement(Routes, { ...props });
831
+ return null;
832
+ };
833
+ const SentryRoutes = (props) => {
834
+ const config = getRouterConfig(core.getClient());
835
+ return /* @__PURE__ */ React.createElement(
836
+ React.Fragment,
837
+ null,
838
+ // @ts-expect-error Setting more specific React Component typing for `R` generic above
839
+ // will break advanced type inference done by react router params
840
+ /* @__PURE__ */ React.createElement(Routes, { ...props }),
841
+ config ? /* @__PURE__ */ React.createElement(RouteReporter, { config, routeChildren: props.children }) : null
842
+ );
830
843
  };
831
844
  hoistNonReactStatics.hoistNonReactStatics(SentryRoutes, Routes);
832
845
  return SentryRoutes;