Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export {
} from '@sentry/browser-utils';
export type { CachedRouteProvider, RouteProvider } from '@sentry/browser-utils';
export { interactionsIntegration } from './integrations/interactions';
export { linkedTracesIntegration } from './integrations/linkedTraces';
export { longTasksIntegration } from './integrations/longTasks';
export { xhrTracingIntegration } from './integrations/xhrTracing';

Expand Down
36 changes: 36 additions & 0 deletions packages/browser/src/integrations/linkedTraces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { IntegrationFn } from '@sentry/core';
import { defineIntegration } from '@sentry/core';
import { linkTraces } from '../tracing/linkedTraces';

interface LinkedTracesOptions {
/**
* Where the previous trace is stored: `'in-memory'` for single-page applications, or
* `'session-storage'` for multi-page applications, which writes to the browser's `sessionStorage`.
*
* Default: 'in-memory'
*/
linkPreviousTrace?: 'in-memory' | 'session-storage';

/**
* If true, subsequent traces are sampled consistently with the sampling decision of the initial trace.
*
* Default: false
*/
consistentTraceSampling?: boolean;
}

const _linkedTracesIntegration = ((options: LinkedTracesOptions = {}) => {
const { linkPreviousTrace = 'in-memory', consistentTraceSampling = false } = options;

return {
name: 'LinkedTraces',
setup(client) {
linkTraces(client, { linkPreviousTrace, consistentTraceSampling });
},
};
}) satisfies IntegrationFn;

/**
* Links each new trace to the previous one, so you can navigate between traces in Sentry.
*/
export const linkedTracesIntegration = defineIntegration(_linkedTracesIntegration);
25 changes: 15 additions & 10 deletions packages/browser/src/tracing/browserTracingIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { getHttpRequestData, WINDOW } from '../helpers';
import type { WebVitalsOptions } from '../integrations/webVitals';
import { webVitalsIntegration } from '../integrations/webVitals';
import { registerBackgroundTabDetection } from './backgroundtab';
import { linkTraces } from './linkedTraces';
import { linkedTracesIntegration } from '../integrations/linkedTraces';
import { xhrTracingIntegration } from '../integrations/xhrTracing';
import { defaultRequestInstrumentationOptions, instrumentFetchRequests } from './request';
import {
Expand Down Expand Up @@ -287,7 +287,14 @@ export interface BrowserTracingOptions {
*/
export type BrowserTracingCoreOptions = Omit<
BrowserTracingOptions,
'enableInp' | 'webVitals' | 'enableElementTiming' | 'enableLongTask' | 'enableLongAnimationFrame' | 'traceXHR'
| 'enableInp'
| 'webVitals'
| 'enableElementTiming'
| 'enableLongTask'
| 'enableLongAnimationFrame'
| 'traceXHR'
| 'linkPreviousTrace'
| 'consistentTraceSampling'
>;

const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingCoreOptions = {
Expand All @@ -298,8 +305,6 @@ const DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingCoreOptions = {
markBackgroundSpan: true,
ignoreResourceSpans: [],
detectRedirects: true,
linkPreviousTrace: 'in-memory',
consistentTraceSampling: false,
enableReportPageLoaded: false,
...defaultRequestInstrumentationOptions,
};
Expand Down Expand Up @@ -334,6 +339,8 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
enableHTTPTimings,
onRequestSpanStart,
onRequestSpanEnd,
linkPreviousTrace = 'in-memory',
consistentTraceSampling,
} = options;

return _browserTracingIntegration(options, client => {
Expand All @@ -359,6 +366,10 @@ export const browserTracingIntegration = ((options: Partial<BrowserTracingOption
xhrTracingIntegration({ shouldCreateSpanForRequest, enableHTTPTimings, onRequestSpanStart, onRequestSpanEnd }),
);
}

if (linkPreviousTrace !== 'off') {
client.addIntegration(linkedTracesIntegration({ linkPreviousTrace, consistentTraceSampling }));
}
});
}) satisfies IntegrationFn;

Expand Down Expand Up @@ -396,8 +407,6 @@ function _browserTracingIntegration(
instrumentNavigation,
instrumentBfcacheRestore,
detectRedirects,
linkPreviousTrace,
consistentTraceSampling,
enableReportPageLoaded,
onRequestSpanStart,
onRequestSpanEnd,
Expand Down Expand Up @@ -674,10 +683,6 @@ function _browserTracingIntegration(

let startingUrl: string | undefined = getLocationHref();

if (linkPreviousTrace !== 'off') {
linkTraces(client, { linkPreviousTrace, consistentTraceSampling });
}

if (WINDOW.location) {
if (instrumentPageLoad) {
startBrowserTracingPageLoadSpan(client, {
Expand Down
20 changes: 20 additions & 0 deletions packages/browser/test/tracing/browserTracingIntegration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,26 @@ describe('browserTracingIntegration', () => {
expect(!!client.getIntegrationByName('XhrTracing')).toBe(registered);
});

it.each([
['registers linkedTracesIntegration by default', {}, true],
[
'does not register linkedTracesIntegration when linkPreviousTrace is off',
{ linkPreviousTrace: 'off' as const },
false,
],
])('%s', (_name, options, registered) => {
const client = new BrowserClient(
getDefaultBrowserClientOptions({
tracesSampleRate: 1,
integrations: [browserTracingIntegration(options)],
}),
);
setCurrentClient(client);
client.init();

expect(!!client.getIntegrationByName('LinkedTraces')).toBe(registered);
});

it('keeps the webVitalsIntegration the user supplies', () => {
const userWebVitals = webVitalsModule.webVitalsIntegration({ softNavigations: false });

Expand Down
Loading