@sentry/react-router 10.53.1 → 10.54.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.
Files changed (119) hide show
  1. package/build/cjs/client/createClientInstrumentation.js +104 -175
  2. package/build/cjs/client/createClientInstrumentation.js.map +1 -1
  3. package/build/cjs/client/hydratedRouter.js +27 -74
  4. package/build/cjs/client/hydratedRouter.js.map +1 -1
  5. package/build/cjs/client/sdk.js +5 -16
  6. package/build/cjs/client/sdk.js.map +1 -1
  7. package/build/cjs/client/sentryOnError.js +4 -27
  8. package/build/cjs/client/sentryOnError.js.map +1 -1
  9. package/build/cjs/client/tracingIntegration.js +4 -18
  10. package/build/cjs/client/tracingIntegration.js.map +1 -1
  11. package/build/cjs/client/utils.js +5 -17
  12. package/build/cjs/client/utils.js.map +1 -1
  13. package/build/cjs/cloudflare/index.js +2 -15
  14. package/build/cjs/cloudflare/index.js.map +1 -1
  15. package/build/cjs/common/debug-build.js +0 -5
  16. package/build/cjs/common/debug-build.js.map +1 -1
  17. package/build/cjs/common/utils.js +8 -33
  18. package/build/cjs/common/utils.js.map +1 -1
  19. package/build/cjs/server/createSentryHandleError.js +4 -13
  20. package/build/cjs/server/createSentryHandleError.js.map +1 -1
  21. package/build/cjs/server/createSentryHandleRequest.js +14 -49
  22. package/build/cjs/server/createSentryHandleRequest.js.map +1 -1
  23. package/build/cjs/server/createServerInstrumentation.js +76 -114
  24. package/build/cjs/server/createServerInstrumentation.js.map +1 -1
  25. package/build/cjs/server/getMetaTagTransformer.js +2 -8
  26. package/build/cjs/server/getMetaTagTransformer.js.map +1 -1
  27. package/build/cjs/server/instrumentation/reactRouter.js +21 -47
  28. package/build/cjs/server/instrumentation/reactRouter.js.map +1 -1
  29. package/build/cjs/server/instrumentation/util.js +5 -41
  30. package/build/cjs/server/instrumentation/util.js.map +1 -1
  31. package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js +5 -12
  32. package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  33. package/build/cjs/server/integration/reactRouterServer.js +10 -42
  34. package/build/cjs/server/integration/reactRouterServer.js.map +1 -1
  35. package/build/cjs/server/sdk.js +6 -20
  36. package/build/cjs/server/sdk.js.map +1 -1
  37. package/build/cjs/server/serverBuild.js +6 -31
  38. package/build/cjs/server/serverBuild.js.map +1 -1
  39. package/build/cjs/server/serverGlobals.js +6 -26
  40. package/build/cjs/server/serverGlobals.js.map +1 -1
  41. package/build/cjs/server/wrapSentryHandleRequest.js +13 -53
  42. package/build/cjs/server/wrapSentryHandleRequest.js.map +1 -1
  43. package/build/cjs/server/wrapServerAction.js +12 -44
  44. package/build/cjs/server/wrapServerAction.js.map +1 -1
  45. package/build/cjs/server/wrapServerLoader.js +12 -44
  46. package/build/cjs/server/wrapServerLoader.js.map +1 -1
  47. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js +38 -72
  48. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  49. package/build/cjs/vite/makeConfigInjectorPlugin.js +4 -12
  50. package/build/cjs/vite/makeConfigInjectorPlugin.js.map +1 -1
  51. package/build/cjs/vite/makeCustomSentryVitePlugins.js +10 -15
  52. package/build/cjs/vite/makeCustomSentryVitePlugins.js.map +1 -1
  53. package/build/cjs/vite/makeEnableSourceMapsPlugin.js +19 -51
  54. package/build/cjs/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  55. package/build/cjs/vite/makeServerBuildCapturePlugin.js +4 -15
  56. package/build/cjs/vite/makeServerBuildCapturePlugin.js.map +1 -1
  57. package/build/cjs/vite/plugin.js +3 -16
  58. package/build/cjs/vite/plugin.js.map +1 -1
  59. package/build/esm/client/createClientInstrumentation.js +104 -175
  60. package/build/esm/client/createClientInstrumentation.js.map +1 -1
  61. package/build/esm/client/hydratedRouter.js +27 -74
  62. package/build/esm/client/hydratedRouter.js.map +1 -1
  63. package/build/esm/client/sdk.js +5 -16
  64. package/build/esm/client/sdk.js.map +1 -1
  65. package/build/esm/client/sentryOnError.js +4 -27
  66. package/build/esm/client/sentryOnError.js.map +1 -1
  67. package/build/esm/client/tracingIntegration.js +4 -18
  68. package/build/esm/client/tracingIntegration.js.map +1 -1
  69. package/build/esm/client/utils.js +5 -17
  70. package/build/esm/client/utils.js.map +1 -1
  71. package/build/esm/cloudflare/index.js +2 -15
  72. package/build/esm/cloudflare/index.js.map +1 -1
  73. package/build/esm/common/debug-build.js +0 -5
  74. package/build/esm/common/debug-build.js.map +1 -1
  75. package/build/esm/common/utils.js +8 -33
  76. package/build/esm/common/utils.js.map +1 -1
  77. package/build/esm/package.json +1 -1
  78. package/build/esm/server/createSentryHandleError.js +4 -13
  79. package/build/esm/server/createSentryHandleError.js.map +1 -1
  80. package/build/esm/server/createSentryHandleRequest.js +14 -49
  81. package/build/esm/server/createSentryHandleRequest.js.map +1 -1
  82. package/build/esm/server/createServerInstrumentation.js +76 -114
  83. package/build/esm/server/createServerInstrumentation.js.map +1 -1
  84. package/build/esm/server/getMetaTagTransformer.js +2 -8
  85. package/build/esm/server/getMetaTagTransformer.js.map +1 -1
  86. package/build/esm/server/instrumentation/reactRouter.js +21 -47
  87. package/build/esm/server/instrumentation/reactRouter.js.map +1 -1
  88. package/build/esm/server/instrumentation/util.js +5 -41
  89. package/build/esm/server/instrumentation/util.js.map +1 -1
  90. package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js +5 -12
  91. package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  92. package/build/esm/server/integration/reactRouterServer.js +10 -42
  93. package/build/esm/server/integration/reactRouterServer.js.map +1 -1
  94. package/build/esm/server/sdk.js +6 -20
  95. package/build/esm/server/sdk.js.map +1 -1
  96. package/build/esm/server/serverBuild.js +6 -31
  97. package/build/esm/server/serverBuild.js.map +1 -1
  98. package/build/esm/server/serverGlobals.js +6 -26
  99. package/build/esm/server/serverGlobals.js.map +1 -1
  100. package/build/esm/server/wrapSentryHandleRequest.js +13 -53
  101. package/build/esm/server/wrapSentryHandleRequest.js.map +1 -1
  102. package/build/esm/server/wrapServerAction.js +12 -44
  103. package/build/esm/server/wrapServerAction.js.map +1 -1
  104. package/build/esm/server/wrapServerLoader.js +12 -44
  105. package/build/esm/server/wrapServerLoader.js.map +1 -1
  106. package/build/esm/vite/buildEnd/handleOnBuildEnd.js +38 -72
  107. package/build/esm/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  108. package/build/esm/vite/makeConfigInjectorPlugin.js +4 -12
  109. package/build/esm/vite/makeConfigInjectorPlugin.js.map +1 -1
  110. package/build/esm/vite/makeCustomSentryVitePlugins.js +10 -15
  111. package/build/esm/vite/makeCustomSentryVitePlugins.js.map +1 -1
  112. package/build/esm/vite/makeEnableSourceMapsPlugin.js +19 -51
  113. package/build/esm/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  114. package/build/esm/vite/makeServerBuildCapturePlugin.js +4 -15
  115. package/build/esm/vite/makeServerBuildCapturePlugin.js.map +1 -1
  116. package/build/esm/vite/plugin.js +3 -16
  117. package/build/esm/vite/plugin.js.map +1 -1
  118. package/build/types/client/hydratedRouter.d.ts.map +1 -1
  119. package/package.json +5 -5
@@ -4,317 +4,246 @@ import { DEBUG_BUILD } from '../common/debug-build.js';
4
4
  import { captureInstrumentationError, getPathFromRequest, normalizeRoutePath, getPattern } from '../common/utils.js';
5
5
  import { resolveNavigateArg } from './utils.js';
6
6
 
7
- const WINDOW = GLOBAL_OBJ ;
8
-
9
- // Tracks active numeric navigation span to prevent duplicate spans when popstate fires
7
+ const WINDOW = GLOBAL_OBJ;
10
8
  let currentNumericNavigationSpan;
11
-
12
- // Per-request middleware counters, keyed by Request
13
- const middlewareCountersMap = new WeakMap();
14
-
15
- const SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';
16
- // Intentionally never reset - once set, instrumentation API handles all navigations for the session.
17
- const SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';
18
- const SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';
19
-
20
- const GLOBAL_WITH_FLAGS = GLOBAL_OBJ ;
21
-
22
- /**
23
- * Options for creating Sentry client instrumentation.
24
- */
25
-
26
- /**
27
- * Creates a Sentry client instrumentation for React Router's instrumentation API.
28
- * @experimental
29
- */
30
- function createSentryClientInstrumentation(
31
- options = {},
32
- ) {
9
+ const middlewareCountersMap = /* @__PURE__ */ new WeakMap();
10
+ const SENTRY_CLIENT_INSTRUMENTATION_FLAG = "__sentryReactRouterClientInstrumentationUsed";
11
+ const SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = "__sentryReactRouterNavigateHookInvoked";
12
+ const SENTRY_POPSTATE_LISTENER_ADDED_FLAG = "__sentryReactRouterPopstateListenerAdded";
13
+ const GLOBAL_WITH_FLAGS = GLOBAL_OBJ;
14
+ function createSentryClientInstrumentation(options = {}) {
33
15
  const { captureErrors = true } = options;
34
-
35
- DEBUG_BUILD && debug.log('React Router client instrumentation API created.');
36
-
16
+ DEBUG_BUILD && debug.log("React Router client instrumentation API created.");
37
17
  return {
38
18
  router(router) {
39
- // Set the flag when React Router actually invokes our instrumentation.
40
- // This ensures the flag is only set in Library Mode (where hooks run),
41
- // not in Framework Mode (where hooks are never called).
42
- // See: https://github.com/remix-run/react-router/discussions/13749
43
19
  GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;
44
- DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');
45
-
46
- // Add popstate listener for browser back/forward navigation (persists for session, one listener only)
20
+ DEBUG_BUILD && debug.log("React Router client instrumentation API router hook registered.");
47
21
  if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {
48
22
  GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;
49
-
50
- WINDOW.addEventListener('popstate', () => {
23
+ WINDOW.addEventListener("popstate", () => {
51
24
  const client = getClient();
52
25
  if (!client) {
53
- currentNumericNavigationSpan = undefined;
26
+ currentNumericNavigationSpan = void 0;
54
27
  return;
55
28
  }
56
-
57
- const pathname = WINDOW.location?.pathname || '/';
58
-
59
- // If there's an active numeric navigation span, update it instead of creating a duplicate
29
+ const pathname = WINDOW.location?.pathname || "/";
60
30
  if (currentNumericNavigationSpan) {
61
31
  if (currentNumericNavigationSpan.isRecording()) {
62
32
  currentNumericNavigationSpan.updateName(pathname);
63
33
  }
64
- currentNumericNavigationSpan = undefined;
34
+ currentNumericNavigationSpan = void 0;
65
35
  return;
66
36
  }
67
-
68
- // Only create a new span for actual browser back/forward button clicks
69
37
  startBrowserTracingNavigationSpan(client, {
70
38
  name: pathname,
71
39
  attributes: {
72
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
73
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
74
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',
75
- 'navigation.type': 'browser.popstate',
76
- },
40
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
41
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
42
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
43
+ "navigation.type": "browser.popstate"
44
+ }
77
45
  });
78
46
  });
79
-
80
- DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');
47
+ DEBUG_BUILD && debug.log("React Router popstate listener registered for browser back/forward navigation.");
81
48
  }
82
-
83
49
  router.instrument({
84
50
  async navigate(callNavigate, info) {
85
- // navigate(0) triggers a page reload - skip span creation, but still capture errors
86
- // (navigation can be rejected before reload, e.g., by a navigation guard)
87
51
  if (info.to === 0) {
88
- const result = await callNavigate();
89
- if (result.status === 'error' && result.error instanceof Error) {
90
- captureInstrumentationError(result, captureErrors, 'react_router.navigate', {
91
- 'http.url': info.currentUrl,
52
+ const result2 = await callNavigate();
53
+ if (result2.status === "error" && result2.error instanceof Error) {
54
+ captureInstrumentationError(result2, captureErrors, "react_router.navigate", {
55
+ "http.url": info.currentUrl
92
56
  });
93
57
  }
94
58
  return;
95
59
  }
96
-
97
60
  GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;
98
-
99
- // Handle numeric navigations (navigate(-1), navigate(1), etc.)
100
- if (typeof info.to === 'number') {
101
- const client = getClient();
102
- let navigationSpan;
103
-
104
- if (client) {
105
- const navigationType = info.to < 0 ? 'router.back' : 'router.forward';
61
+ if (typeof info.to === "number") {
62
+ const client2 = getClient();
63
+ let navigationSpan2;
64
+ if (client2) {
65
+ const navigationType = info.to < 0 ? "router.back" : "router.forward";
106
66
  const currentPathname = WINDOW.location?.pathname || info.currentUrl;
107
-
108
- navigationSpan = startBrowserTracingNavigationSpan(client, {
67
+ navigationSpan2 = startBrowserTracingNavigationSpan(client2, {
109
68
  name: currentPathname,
110
69
  attributes: {
111
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
112
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
113
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',
114
- 'navigation.type': navigationType,
115
- },
70
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
71
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
72
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
73
+ "navigation.type": navigationType
74
+ }
116
75
  });
117
-
118
- // Store ref so popstate listener can update it instead of creating a duplicate
119
- currentNumericNavigationSpan = navigationSpan;
76
+ currentNumericNavigationSpan = navigationSpan2;
120
77
  }
121
-
122
78
  try {
123
- const result = await callNavigate();
124
-
125
- if (navigationSpan && WINDOW.location) {
126
- navigationSpan.updateName(WINDOW.location.pathname);
79
+ const result2 = await callNavigate();
80
+ if (navigationSpan2 && WINDOW.location) {
81
+ navigationSpan2.updateName(WINDOW.location.pathname);
127
82
  }
128
-
129
- if (result.status === 'error' && result.error instanceof Error) {
130
- if (navigationSpan) {
131
- navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
83
+ if (result2.status === "error" && result2.error instanceof Error) {
84
+ if (navigationSpan2) {
85
+ navigationSpan2.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
132
86
  }
133
- captureInstrumentationError(result, captureErrors, 'react_router.navigate', {
134
- 'http.url': WINDOW.location?.pathname || info.currentUrl,
87
+ captureInstrumentationError(result2, captureErrors, "react_router.navigate", {
88
+ "http.url": WINDOW.location?.pathname || info.currentUrl
135
89
  });
136
90
  }
137
91
  } finally {
138
- currentNumericNavigationSpan = undefined;
92
+ currentNumericNavigationSpan = void 0;
139
93
  }
140
94
  return;
141
95
  }
142
-
143
- // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))
144
96
  const client = getClient();
145
97
  const toPath = resolveNavigateArg(info.to);
146
98
  let navigationSpan;
147
-
148
99
  if (client) {
149
100
  navigationSpan = startBrowserTracingNavigationSpan(client, {
150
101
  name: toPath,
151
102
  attributes: {
152
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',
153
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
154
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',
155
- 'navigation.type': 'router.navigate',
156
- },
103
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
104
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "navigation",
105
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.navigation.react_router.instrumentation_api",
106
+ "navigation.type": "router.navigate"
107
+ }
157
108
  });
158
109
  }
159
-
160
110
  const result = await callNavigate();
161
- if (result.status === 'error' && result.error instanceof Error) {
111
+ if (result.status === "error" && result.error instanceof Error) {
162
112
  if (navigationSpan) {
163
- navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
113
+ navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
164
114
  }
165
- captureInstrumentationError(result, captureErrors, 'react_router.navigate', {
166
- 'http.url': toPath,
115
+ captureInstrumentationError(result, captureErrors, "react_router.navigate", {
116
+ "http.url": toPath
167
117
  });
168
118
  }
169
119
  return;
170
120
  },
171
-
172
121
  async fetch(callFetch, info) {
173
122
  await startSpan(
174
123
  {
175
124
  name: `Fetcher ${info.fetcherKey}`,
176
125
  attributes: {
177
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.fetcher',
178
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
179
- },
126
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.fetcher",
127
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
128
+ }
180
129
  },
181
- async span => {
130
+ async (span) => {
182
131
  const result = await callFetch();
183
- if (result.status === 'error' && result.error instanceof Error) {
184
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
185
- captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {
186
- 'http.url': info.href,
132
+ if (result.status === "error" && result.error instanceof Error) {
133
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
134
+ captureInstrumentationError(result, captureErrors, "react_router.fetcher", {
135
+ "http.url": info.href
187
136
  });
188
137
  }
189
- },
138
+ }
190
139
  );
191
- },
140
+ }
192
141
  });
193
142
  },
194
-
195
143
  route(route) {
196
144
  const routeId = route.id;
197
-
198
145
  route.instrument({
199
146
  async loader(callLoader, info) {
200
147
  const urlPath = getPathFromRequest(info.request);
201
148
  const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;
202
-
203
149
  await startSpan(
204
150
  {
205
151
  name: routePattern,
206
152
  attributes: {
207
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_loader',
208
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
209
- },
153
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.client_loader",
154
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
155
+ }
210
156
  },
211
- async span => {
157
+ async (span) => {
212
158
  const result = await callLoader();
213
- if (result.status === 'error' && result.error instanceof Error) {
214
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
215
- captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {
216
- 'http.url': urlPath,
159
+ if (result.status === "error" && result.error instanceof Error) {
160
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
161
+ captureInstrumentationError(result, captureErrors, "react_router.client_loader", {
162
+ "http.url": urlPath
217
163
  });
218
164
  }
219
- },
165
+ }
220
166
  );
221
167
  },
222
-
223
168
  async action(callAction, info) {
224
169
  const urlPath = getPathFromRequest(info.request);
225
170
  const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;
226
-
227
171
  await startSpan(
228
172
  {
229
173
  name: routePattern,
230
174
  attributes: {
231
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_action',
232
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
233
- },
175
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.client_action",
176
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
177
+ }
234
178
  },
235
- async span => {
179
+ async (span) => {
236
180
  const result = await callAction();
237
- if (result.status === 'error' && result.error instanceof Error) {
238
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
239
- captureInstrumentationError(result, captureErrors, 'react_router.client_action', {
240
- 'http.url': urlPath,
181
+ if (result.status === "error" && result.error instanceof Error) {
182
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
183
+ captureInstrumentationError(result, captureErrors, "react_router.client_action", {
184
+ "http.url": urlPath
241
185
  });
242
186
  }
243
- },
187
+ }
244
188
  );
245
189
  },
246
-
247
190
  async middleware(callMiddleware, info) {
248
191
  const urlPath = getPathFromRequest(info.request);
249
192
  const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;
250
-
251
193
  let counters = middlewareCountersMap.get(info.request);
252
194
  if (!counters) {
253
195
  counters = {};
254
196
  middlewareCountersMap.set(info.request, counters);
255
197
  }
256
-
257
198
  const middlewareIndex = counters[routeId] ?? 0;
258
199
  counters[routeId] = middlewareIndex + 1;
259
-
260
200
  await startSpan(
261
201
  {
262
202
  name: `middleware ${routeId}`,
263
203
  attributes: {
264
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_middleware',
265
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
266
- 'react_router.route.id': routeId,
267
- 'http.route': routePattern,
268
- 'react_router.middleware.index': middlewareIndex,
269
- },
204
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.client_middleware",
205
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api",
206
+ "react_router.route.id": routeId,
207
+ "http.route": routePattern,
208
+ "react_router.middleware.index": middlewareIndex
209
+ }
270
210
  },
271
- async span => {
211
+ async (span) => {
272
212
  const result = await callMiddleware();
273
- if (result.status === 'error' && result.error instanceof Error) {
274
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
275
- captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {
276
- 'http.url': urlPath,
213
+ if (result.status === "error" && result.error instanceof Error) {
214
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
215
+ captureInstrumentationError(result, captureErrors, "react_router.client_middleware", {
216
+ "http.url": urlPath
277
217
  });
278
218
  }
279
- },
219
+ }
280
220
  );
281
221
  },
282
-
283
222
  async lazy(callLazy) {
284
223
  await startSpan(
285
224
  {
286
- name: 'Lazy Route Load',
225
+ name: "Lazy Route Load",
287
226
  attributes: {
288
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_lazy',
289
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',
290
- },
227
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.client_lazy",
228
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.react_router.instrumentation_api"
229
+ }
291
230
  },
292
- async span => {
231
+ async (span) => {
293
232
  const result = await callLazy();
294
- if (result.status === 'error' && result.error instanceof Error) {
295
- span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
296
- captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});
233
+ if (result.status === "error" && result.error instanceof Error) {
234
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
235
+ captureInstrumentationError(result, captureErrors, "react_router.client_lazy", {});
297
236
  }
298
- },
237
+ }
299
238
  );
300
- },
239
+ }
301
240
  });
302
- },
241
+ }
303
242
  };
304
243
  }
305
-
306
- /**
307
- * Check if React Router's instrumentation API is being used on the client.
308
- * @experimental
309
- */
310
244
  function isClientInstrumentationApiUsed() {
311
245
  return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];
312
246
  }
313
-
314
- /**
315
- * Check if React Router's instrumentation API's navigate hook was invoked.
316
- * @experimental
317
- */
318
247
  function isNavigateHookInvoked() {
319
248
  return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];
320
249
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getClient,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { ClientInstrumentation, InstrumentableRoute, InstrumentableRouter } from '../common/types';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { resolveNavigateArg } from './utils';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n * @experimental\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router: InstrumentableRouter) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n currentNumericNavigationSpan.updateName(pathname);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(client, {\n name: pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n });\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': info.currentUrl,\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(client, {\n name: currentPathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n });\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n navigationSpan.updateName(WINDOW.location.pathname);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': WINDOW.location?.pathname || info.currentUrl,\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(client, {\n name: toPath,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n });\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': toPath,\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n 'http.url': info.href,\n });\n }\n },\n );\n },\n });\n },\n\n route(route: InstrumentableRoute) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n * @experimental\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n * @experimental\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createClientInstrumentation.js","sources":["../../../src/client/createClientInstrumentation.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n debug,\n getClient,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n SPAN_STATUS_ERROR,\n startSpan,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport type { ClientInstrumentation, InstrumentableRoute, InstrumentableRouter } from '../common/types';\nimport { captureInstrumentationError, getPathFromRequest, getPattern, normalizeRoutePath } from '../common/utils';\nimport { resolveNavigateArg } from './utils';\n\nconst WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;\n\n// Tracks active numeric navigation span to prevent duplicate spans when popstate fires\nlet currentNumericNavigationSpan: Span | undefined;\n\n// Per-request middleware counters, keyed by Request\nconst middlewareCountersMap = new WeakMap<object, Record<string, number>>();\n\nconst SENTRY_CLIENT_INSTRUMENTATION_FLAG = '__sentryReactRouterClientInstrumentationUsed';\n// Intentionally never reset - once set, instrumentation API handles all navigations for the session.\nconst SENTRY_NAVIGATE_HOOK_INVOKED_FLAG = '__sentryReactRouterNavigateHookInvoked';\nconst SENTRY_POPSTATE_LISTENER_ADDED_FLAG = '__sentryReactRouterPopstateListenerAdded';\n\ntype GlobalObjWithFlags = typeof GLOBAL_OBJ & {\n [SENTRY_CLIENT_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_NAVIGATE_HOOK_INVOKED_FLAG]?: boolean;\n [SENTRY_POPSTATE_LISTENER_ADDED_FLAG]?: boolean;\n};\n\nconst GLOBAL_WITH_FLAGS = GLOBAL_OBJ as GlobalObjWithFlags;\n\n/**\n * Options for creating Sentry client instrumentation.\n */\nexport interface CreateSentryClientInstrumentationOptions {\n /**\n * Whether to capture errors from loaders/actions automatically.\n * Set to `false` to avoid duplicates if using custom error handlers.\n * @default true\n */\n captureErrors?: boolean;\n}\n\n/**\n * Creates a Sentry client instrumentation for React Router's instrumentation API.\n * @experimental\n */\nexport function createSentryClientInstrumentation(\n options: CreateSentryClientInstrumentationOptions = {},\n): ClientInstrumentation {\n const { captureErrors = true } = options;\n\n DEBUG_BUILD && debug.log('React Router client instrumentation API created.');\n\n return {\n router(router: InstrumentableRouter) {\n // Set the flag when React Router actually invokes our instrumentation.\n // This ensures the flag is only set in Library Mode (where hooks run),\n // not in Framework Mode (where hooks are never called).\n // See: https://github.com/remix-run/react-router/discussions/13749\n GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG] = true;\n DEBUG_BUILD && debug.log('React Router client instrumentation API router hook registered.');\n\n // Add popstate listener for browser back/forward navigation (persists for session, one listener only)\n if (!GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] && WINDOW.addEventListener) {\n GLOBAL_WITH_FLAGS[SENTRY_POPSTATE_LISTENER_ADDED_FLAG] = true;\n\n WINDOW.addEventListener('popstate', () => {\n const client = getClient();\n if (!client) {\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n const pathname = WINDOW.location?.pathname || '/';\n\n // If there's an active numeric navigation span, update it instead of creating a duplicate\n if (currentNumericNavigationSpan) {\n if (currentNumericNavigationSpan.isRecording()) {\n currentNumericNavigationSpan.updateName(pathname);\n }\n currentNumericNavigationSpan = undefined;\n return;\n }\n\n // Only create a new span for actual browser back/forward button clicks\n startBrowserTracingNavigationSpan(client, {\n name: pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'browser.popstate',\n },\n });\n });\n\n DEBUG_BUILD && debug.log('React Router popstate listener registered for browser back/forward navigation.');\n }\n\n router.instrument({\n async navigate(callNavigate, info) {\n // navigate(0) triggers a page reload - skip span creation, but still capture errors\n // (navigation can be rejected before reload, e.g., by a navigation guard)\n if (info.to === 0) {\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': info.currentUrl,\n });\n }\n return;\n }\n\n GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG] = true;\n\n // Handle numeric navigations (navigate(-1), navigate(1), etc.)\n if (typeof info.to === 'number') {\n const client = getClient();\n let navigationSpan;\n\n if (client) {\n const navigationType = info.to < 0 ? 'router.back' : 'router.forward';\n const currentPathname = WINDOW.location?.pathname || info.currentUrl;\n\n navigationSpan = startBrowserTracingNavigationSpan(client, {\n name: currentPathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': navigationType,\n },\n });\n\n // Store ref so popstate listener can update it instead of creating a duplicate\n currentNumericNavigationSpan = navigationSpan;\n }\n\n try {\n const result = await callNavigate();\n\n if (navigationSpan && WINDOW.location) {\n navigationSpan.updateName(WINDOW.location.pathname);\n }\n\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': WINDOW.location?.pathname || info.currentUrl,\n });\n }\n } finally {\n currentNumericNavigationSpan = undefined;\n }\n return;\n }\n\n // Handle string/object navigations (e.g., navigate('/about') or navigate({ pathname: '/about' }))\n const client = getClient();\n const toPath = resolveNavigateArg(info.to);\n let navigationSpan;\n\n if (client) {\n navigationSpan = startBrowserTracingNavigationSpan(client, {\n name: toPath,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react_router.instrumentation_api',\n 'navigation.type': 'router.navigate',\n },\n });\n }\n\n const result = await callNavigate();\n if (result.status === 'error' && result.error instanceof Error) {\n if (navigationSpan) {\n navigationSpan.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n }\n captureInstrumentationError(result, captureErrors, 'react_router.navigate', {\n 'http.url': toPath,\n });\n }\n return;\n },\n\n async fetch(callFetch, info) {\n await startSpan(\n {\n name: `Fetcher ${info.fetcherKey}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.fetcher',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callFetch();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.fetcher', {\n 'http.url': info.href,\n });\n }\n },\n );\n },\n });\n },\n\n route(route: InstrumentableRoute) {\n const routeId = route.id;\n\n route.instrument({\n async loader(callLoader, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLoader();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_loader', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async action(callAction, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n await startSpan(\n {\n name: routePattern,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_action',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callAction();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_action', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async middleware(callMiddleware, info) {\n const urlPath = getPathFromRequest(info.request);\n const routePattern = normalizeRoutePath(getPattern(info)) || urlPath;\n\n let counters = middlewareCountersMap.get(info.request);\n if (!counters) {\n counters = {};\n middlewareCountersMap.set(info.request, counters);\n }\n\n const middlewareIndex = counters[routeId] ?? 0;\n counters[routeId] = middlewareIndex + 1;\n\n await startSpan(\n {\n name: `middleware ${routeId}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_middleware',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n 'react_router.route.id': routeId,\n 'http.route': routePattern,\n 'react_router.middleware.index': middlewareIndex,\n },\n },\n async span => {\n const result = await callMiddleware();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_middleware', {\n 'http.url': urlPath,\n });\n }\n },\n );\n },\n\n async lazy(callLazy) {\n await startSpan(\n {\n name: 'Lazy Route Load',\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.client_lazy',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.react_router.instrumentation_api',\n },\n },\n async span => {\n const result = await callLazy();\n if (result.status === 'error' && result.error instanceof Error) {\n span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });\n captureInstrumentationError(result, captureErrors, 'react_router.client_lazy', {});\n }\n },\n );\n },\n });\n },\n };\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the client.\n * @experimental\n */\nexport function isClientInstrumentationApiUsed(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_CLIENT_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Check if React Router's instrumentation API's navigate hook was invoked.\n * @experimental\n */\nexport function isNavigateHookInvoked(): boolean {\n return !!GLOBAL_WITH_FLAGS[SENTRY_NAVIGATE_HOOK_INVOKED_FLAG];\n}\n"],"names":["result","client","navigationSpan"],"mappings":"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"}