@@ -13,7 +13,7 @@ import {
1313 registerRequestInstrumentation ,
1414 RequestInstrumentationOptions ,
1515} from './request' ;
16- import { defaultBeforeNavigate , defaultRoutingInstrumentation } from './router' ;
16+ import { defaultRoutingInstrumentation } from './router' ;
1717
1818export const DEFAULT_MAX_TRANSACTION_DURATION_SECONDS = 600 ;
1919
@@ -61,12 +61,17 @@ export interface BrowserTracingOptions extends RequestInstrumentationOptions {
6161 markBackgroundTransactions : boolean ;
6262
6363 /**
64- * beforeNavigate is called before a pageload/navigation transaction is created and allows for users
65- * to set custom transaction context. Default behavior is to return `window.location.pathname` .
64+ * beforeNavigate is called before a pageload/navigation transaction is created and allows users to modify transaction
65+ * context data, or drop the transaction entirely (by setting `sampled = false` in the context) .
6666 *
67- * If undefined is returned, a pageload/navigation transaction will not be created.
67+ * Note: For legacy reasons, transactions can also be dropped by returning `undefined`, though that option may
68+ * disappear in the future.
69+ *
70+ * @param context: The context data which will be passed to `startTransaction` by default
71+ *
72+ * @returns A (potentially) modified context object, with `sampled = false` if the transaction should be dropped.
6873 */
69- beforeNavigate ( context : TransactionContext ) : TransactionContext | undefined ;
74+ beforeNavigate ? ( context : TransactionContext ) : TransactionContext | undefined ;
7075
7176 /**
7277 * Instrumentation that creates routing change transactions. By default creates
@@ -80,7 +85,6 @@ export interface BrowserTracingOptions extends RequestInstrumentationOptions {
8085}
8186
8287const DEFAULT_BROWSER_TRACING_OPTIONS = {
83- beforeNavigate : defaultBeforeNavigate ,
8488 idleTimeout : DEFAULT_IDLE_TIMEOUT ,
8589 markBackgroundTransactions : true ,
8690 maxTransactionDuration : DEFAULT_MAX_TRANSACTION_DURATION_SECONDS ,
@@ -188,21 +192,25 @@ export class BrowserTracing implements Integration {
188192 // eslint-disable-next-line @typescript-eslint/unbound-method
189193 const { beforeNavigate, idleTimeout, maxTransactionDuration } = this . options ;
190194
191- // if beforeNavigate returns undefined, we should not start a transaction.
192- const ctx = beforeNavigate ( {
195+ const expandedContext = {
193196 ...context ,
194197 ...getHeaderContext ( ) ,
195198 trimEnd : true ,
196- } ) ;
199+ } ;
200+ const modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate ( expandedContext ) : expandedContext ;
197201
198- if ( ctx === undefined ) {
199- logger . log ( `[Tracing] Did not create ${ context . op } idleTransaction due to beforeNavigate` ) ;
200- return undefined ;
202+ // TODO (kmclb): for backwards compatibility reasons, beforeNavigate can return undefined to "drop" the transaction
203+ // (prevent it from being sent to Sentry). This can be removed in V6, after which time modifiedContext and
204+ // finalContext will be one and the same.
205+ const finalContext = modifiedContext === undefined ? { ...expandedContext , sampled : false } : modifiedContext ;
206+
207+ if ( finalContext . sampled === false ) {
208+ logger . log ( `[Tracing] Will not send ${ finalContext . op } transaction because of beforeNavigate.` ) ;
201209 }
202210
203211 const hub = this . _getCurrentHub ( ) ;
204- logger . log ( `[Tracing] starting ${ ctx . op } idleTransaction on scope` ) ;
205- const idleTransaction = startIdleTransaction ( hub , ctx , idleTimeout , true ) ;
212+ logger . log ( `[Tracing] Starting ${ finalContext . op } transaction on scope` ) ;
213+ const idleTransaction = startIdleTransaction ( hub , finalContext , idleTimeout , true ) ;
206214 idleTransaction . registerBeforeFinishCallback ( ( transaction , endTimestamp ) => {
207215 this . _metrics . addPerformanceEntries ( transaction ) ;
208216 adjustTransactionDuration ( secToMs ( maxTransactionDuration ) , transaction , endTimestamp ) ;
0 commit comments