Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion packages/browser/src/tracing/browserTracingIntegration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ export function startBrowserTracingNavigationSpan(
options?: { url?: string; isRedirect?: boolean },
): Span | undefined {
const { url, isRedirect } = options || {};

client.emit('beforeStartNavigationSpan', spanOptions);
client.emit('startNavigationSpan', spanOptions, { isRedirect });

const scope = getCurrentScope();
Expand Down
18 changes: 18 additions & 0 deletions packages/browser/test/tracing/browserTracingIntegration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,24 @@ describe('browserTracingIntegration', () => {
},
});
});

it('triggers beforeStartNavigationSpan hook listeners', () => {
const client = new BrowserClient(
getDefaultBrowserClientOptions({
tracesSampleRate: 1,
integrations: [browserTracingIntegration()],
}),
);
setCurrentClient(client);

const mockBeforeStartNavigationSpanCallback = vi.fn((options: StartSpanOptions) => options);

client.on('beforeStartNavigationSpan', mockBeforeStartNavigationSpanCallback);

startBrowserTracingNavigationSpan(client, { name: 'test span', op: 'navigation' });

expect(mockBeforeStartNavigationSpanCallback).toHaveBeenCalledWith({ name: 'test span', op: 'navigation' });
});
});

describe('using the <meta> tag data', () => {
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
) => void,
): () => void;

/**
* A hook for triggering right before a navigation span is started.
* @returns {() => void} A function that, when executed, removes the registered callback.
*/
public on(hook: 'beforeStartNavigationSpan', callback: (options: StartSpanOptions) => void): () => void;

/**
* A hook for browser tracing integrations to trigger a span for a navigation.
* @returns {() => void} A function that, when executed, removes the registered callback.
Expand Down Expand Up @@ -782,6 +788,11 @@ export abstract class Client<O extends ClientOptions = ClientOptions> {
traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },
): void;

/**
* Emit a hook event for triggering right before a navigation span is started.
*/
public emit(hook: 'beforeStartNavigationSpan', options: StartSpanOptions): void;

/**
* Emit a hook event for browser tracing integrations to trigger a span for a navigation.
*/
Expand Down
28 changes: 17 additions & 11 deletions packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,25 @@ describe('pagesRouterInstrumentNavigation', () => {

Router.events.emit('routeChangeStart', targetLocation);

expect(emit).toHaveBeenCalledTimes(1);
expect(emit).toHaveBeenCalledTimes(2);
const expectedStartSpanOptions = {
name: expectedTransactionName,
attributes: {
'sentry.op': 'navigation',
'sentry.origin': 'auto.navigation.nextjs.pages_router_instrumentation',
'sentry.source': expectedTransactionSource,
},
};
expect(emit).toHaveBeenCalledWith(
'startNavigationSpan',
expect.objectContaining({
name: expectedTransactionName,
attributes: {
'sentry.op': 'navigation',
'sentry.origin': 'auto.navigation.nextjs.pages_router_instrumentation',
'sentry.source': expectedTransactionSource,
},
}),
{ isRedirect: undefined },
'beforeStartNavigationSpan',
expect.objectContaining(expectedStartSpanOptions),
{
isRedirect: undefined,
},
);
expect(emit).toHaveBeenCalledWith('startNavigationSpan', expect.objectContaining(expectedStartSpanOptions), {
isRedirect: undefined,
});
},
);
});
Loading