@@ -61,10 +61,15 @@ export interface BrowserTracingOptions extends RequestInstrumentationOptions {
61
61
markBackgroundTransactions : boolean ;
62
62
63
63
/**
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) .
66
66
*
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.
68
73
*/
69
74
beforeNavigate ?( context : TransactionContext ) : TransactionContext | undefined ;
70
75
@@ -187,22 +192,25 @@ export class BrowserTracing implements Integration {
187
192
// eslint-disable-next-line @typescript-eslint/unbound-method
188
193
const { beforeNavigate, idleTimeout, maxTransactionDuration } = this . options ;
189
194
190
- // if beforeNavigate returns undefined, we should not start a transaction.
191
195
const expandedContext = {
192
196
...context ,
193
197
...getHeaderContext ( ) ,
194
198
trimEnd : true ,
195
199
} ;
196
200
const modifiedContext = typeof beforeNavigate === 'function' ? beforeNavigate ( expandedContext ) : expandedContext ;
197
201
198
- if ( modifiedContext === 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.` ) ;
201
209
}
202
210
203
211
const hub = this . _getCurrentHub ( ) ;
204
- const idleTransaction = startIdleTransaction ( hub , modifiedContext , idleTimeout , true ) ;
205
- logger . log ( `[Tracing] Starting ${ modifiedContext . op } transaction on scope` ) ;
212
+ const idleTransaction = startIdleTransaction ( hub , finalContext , idleTimeout , true ) ;
213
+ logger . log ( `[Tracing] Starting ${ finalContext . op } transaction on scope` ) ;
206
214
idleTransaction . registerBeforeFinishCallback ( ( transaction , endTimestamp ) => {
207
215
this . _metrics . addPerformanceEntries ( transaction ) ;
208
216
adjustTransactionDuration ( secToMs ( maxTransactionDuration ) , transaction , endTimestamp ) ;
0 commit comments