Skip to content

Commit 7e3c69a

Browse files
committed
feat(react): Add browserTracingReactRouterV3Integration
To replace the routing instrumentation.
1 parent 4285a7e commit 7e3c69a

File tree

3 files changed

+310
-63
lines changed

3 files changed

+310
-63
lines changed

packages/react/src/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ export { Profiler, withProfiler, useProfiler } from './profiler';
55
export type { ErrorBoundaryProps, FallbackRender } from './errorboundary';
66
export { ErrorBoundary, withErrorBoundary } from './errorboundary';
77
export { createReduxEnhancer } from './redux';
8-
export { reactRouterV3Instrumentation } from './reactrouterv3';
8+
export {
9+
// eslint-disable-next-line deprecation/deprecation
10+
reactRouterV3Instrumentation,
11+
browserTracingReactRouterV3Integration,
12+
} from './reactrouterv3';
913
export { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';
1014
export {
1115
reactRouterV6Instrumentation,

packages/react/src/reactrouterv3.ts

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1-
import { WINDOW } from '@sentry/browser';
2-
import type { Primitive, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
1+
import {
2+
WINDOW,
3+
browserTracingIntegration,
4+
startBrowserTracingNavigationSpan,
5+
startBrowserTracingPageLoadSpan,
6+
} from '@sentry/browser';
7+
import {
8+
SEMANTIC_ATTRIBUTE_SENTRY_OP,
9+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
10+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
11+
} from '@sentry/core';
12+
import type {
13+
Integration,
14+
SpanAttributes,
15+
StartSpanOptions,
16+
Transaction,
17+
TransactionContext,
18+
TransactionSource,
19+
} from '@sentry/types';
320

421
import type { Location, ReactRouterInstrumentation } from './types';
522

@@ -21,13 +38,61 @@ export type Match = (
2138

2239
type ReactRouterV3TransactionSource = Extract<TransactionSource, 'url' | 'route'>;
2340

41+
interface ReactRouterOptions {
42+
history: HistoryV3;
43+
routes: Route[];
44+
match: Match;
45+
}
46+
47+
/**
48+
* A browser tracing integration that uses React Router v3 to instrument navigations.
49+
* Expects `history` (and optionally `routes` and `matchPath`) to be passed as options.
50+
*/
51+
export function browserTracingReactRouterV3Integration(
52+
options: Parameters<typeof browserTracingIntegration>[0] & ReactRouterOptions,
53+
): Integration {
54+
const integration = browserTracingIntegration({
55+
...options,
56+
instrumentPageLoad: false,
57+
instrumentNavigation: false,
58+
});
59+
60+
const { history, routes, match, instrumentPageLoad = true, instrumentNavigation = true } = options;
61+
62+
return {
63+
...integration,
64+
afterAllSetup(client) {
65+
integration.afterAllSetup(client);
66+
67+
const startPageloadCallback = (startSpanOptions: StartSpanOptions): undefined => {
68+
startBrowserTracingPageLoadSpan(client, startSpanOptions);
69+
return undefined;
70+
};
71+
72+
const startNavigationCallback = (startSpanOptions: StartSpanOptions): undefined => {
73+
startBrowserTracingNavigationSpan(client, startSpanOptions);
74+
return undefined;
75+
};
76+
77+
// eslint-disable-next-line deprecation/deprecation
78+
const instrumentation = reactRouterV3Instrumentation(history, routes, match);
79+
80+
// Now instrument page load & navigation with correct settings
81+
instrumentation(startPageloadCallback, instrumentPageLoad, false);
82+
instrumentation(startNavigationCallback, false, instrumentNavigation);
83+
},
84+
};
85+
}
86+
2487
/**
2588
* Creates routing instrumentation for React Router v3
2689
* Works for React Router >= 3.2.0 and < 4.0.0
2790
*
2891
* @param history object from the `history` library
2992
* @param routes a list of all routes, should be
3093
* @param match `Router.match` utility
94+
*
95+
* @deprecated Use `browserTracingReactRouterV3Integration()` instead
3196
*/
3297
export function reactRouterV3Instrumentation(
3398
history: HistoryV3,
@@ -52,13 +117,10 @@ export function reactRouterV3Instrumentation(
52117
prevName = localName;
53118
activeTransaction = startTransaction({
54119
name: prevName,
55-
op: 'pageload',
56-
origin: 'auto.pageload.react.reactrouterv3',
57-
tags: {
58-
'routing.instrumentation': 'react-router-v3',
59-
},
60-
metadata: {
61-
source,
120+
attributes: {
121+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload',
122+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react.reactrouter_v3',
123+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
62124
},
63125
});
64126
},
@@ -71,22 +133,23 @@ export function reactRouterV3Instrumentation(
71133
if (activeTransaction) {
72134
activeTransaction.end();
73135
}
74-
const tags: Record<string, Primitive> = {
75-
'routing.instrumentation': 'react-router-v3',
76-
};
77-
if (prevName) {
78-
tags.from = prevName;
79-
}
136+
const from = prevName;
80137
normalizeTransactionName(routes, location, match, (localName: string, source: TransactionSource = 'url') => {
81138
prevName = localName;
139+
140+
const attributes: SpanAttributes = {
141+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',
142+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v3',
143+
[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,
144+
};
145+
146+
if (from) {
147+
attributes.from = from;
148+
}
149+
82150
activeTransaction = startTransaction({
83151
name: prevName,
84-
op: 'navigation',
85-
origin: 'auto.navigation.react.reactrouterv3',
86-
tags,
87-
metadata: {
88-
source,
89-
},
152+
attributes,
90153
});
91154
});
92155
}

0 commit comments

Comments
 (0)