Automatic Instrumentation
Learn what spans are captured after tracing is enabled.
Capturing spans requires that you first set up tracing in your app if you haven't already.
The Sentry SDK provides a BrowserTracing
integration to add automatic instrumentation for monitoring the performance of browser applications.
The BrowserTracing
integration creates a new transaction for each page load and navigation event, and creates a child span for every XMLHttpRequest
or fetch
request that occurs while those transactions are open. Learn more about traces, transactions, and spans.
To enable tracing, include browserTracingIntegration
in your SDK configuration options.
After configuration, you will see both pageload
and navigation
transactions in the Sentry UI.
// If you're using one of our framework SDK packages, like `@sentry/react`,
// substitute its name for `@sentry/browser` here
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
integrations: [Sentry.browserTracingIntegration()],
// We recommend adjusting this value in production, or using tracesSampler
// for finer control
tracesSampleRate: 1.0,
});
By default, the browserTracingIntegration()
will create a pageload
span for when the page is initially loaded, as well as a navigation
span for whenever the URL changes afterwards.
To make sure that spans are created correctly for a custom routing setup, you'll need to opt out of the default span creation by setting instrumentNavigation: false
and instrumentPageLoad: false
in the browserTracingIntegration()
options. You can then manually create spans like this:
const client = Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
// disable automatic span creation
instrumentNavigation: false,
instrumentPageLoad: false,
}),
],
});
// We start the pageload span as early as possible!
let pageLoadSpan = Sentry.startBrowserTracingPageLoadSpan(client, {
name: window.location.pathname,
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
},
});
// Somewhere, instrument your router like this:
myRouter.on("routeChange", (route) => {
// Make sure that the pageload span uses the route name
// After that, each route change should trigger a navigation span (which will automatically finish the previous one)
if (pageLoadSpan) {
pageLoadSpan.updateName(route.name);
pageLoadSpan.setAttribute(
Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
"route",
);
pageLoadSpan = undefined;
} else {
Sentry.startBrowserTracingNavigationSpan(client, {
op: "navigation",
name: route.name, // or what the name of the span should be
attributes: {
[Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "route",
},
});
}
});
Supported options:
The tracingOrigins
option was renamed tracePropagationTargets
and deprecated in version 7.19.0
of the JavaScript SDK. tracingOrigins
will be removed in version 8.
A list of strings and regular expressions. The JavaScript SDK will attach the sentry-trace
and baggage
headers to all outgoing XHR/fetch requests whose destination contains a string in the list or matches a regex in the list. If your frontend is making requests to a different domain, you'll need to add it there to propagate the sentry-trace
and baggage
headers to the backend services, which is required to link spans together as part of a single trace.
The tracePropagationTargets
option matches the entire request URL, not just the domain. Using stricter regex to match certain parts of the URL ensures that requests don't unnecessarily have additional headers attached.
The default value of tracePropagationTargets
is ['localhost', /^\//]
. This means that by default, tracing headers are only attached to requests that contain localhost
in their URL or requests whose URL starts with a '/'
(for example GET /api/v1/users
).
For example:
- A frontend application is served from
example.com
. - A backend service is served from
api.example.com
. - During development, the backend service is served from
localhost
. - The frontend application makes API calls to the backend.
- Set the
tracePropagationTargets
option to["localhost", /^https:\/\/api\.example\.com/]
. - Now outgoing XHR/fetch requests to your backend service will get the
sentry-trace
andbaggage
headers attached.
Sentry.init({
// ...
integrations: [Sentry.browserTracingIntegration()],
// Set `tracePropagationTargets` to control for which URLs trace propagation should be enabled
tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
});
You will need to configure your web server CORS to allow the sentry-trace
and baggage
headers. The configuration might look like "Access-Control-Allow-Headers: sentry-trace"
and "Access-Control-Allow-Headers: baggage"
, but it depends on your set up. If you do not allow the two headers, the request might be blocked.
beforeStartSpan
is called at the start of every pageload
or navigation
span, and is passed an object containing data about the span which will be started. With beforeStartSpan
you can modify that data.
One common use case is parameterizing transaction names. For both pageload
and navigation
transactions, the browserTracingIntegration
uses the browser's window.location
value to generate a transaction name. Using beforeStartSpan
lets you modify the transaction name to make it more generic, so that for example, transactions named GET /users/12312012
and GET /users/11212012
can both be renamed to GET /users/:userid
. That way they'll be grouped together.
Sentry.init({
// ...
integrations: [
Sentry.browserTracingIntegration({
beforeStartSpan: (context) => {
return {
...context,
// You could use your UI's routing library to find the matching
// route template here. We don't have one right now, so do some basic
// parameter replacements.
name: location.pathname
.replace(/\/[a-f0-9]{32}/g, "/<hash>")
.replace(/\/\d+/g, "/<digits>"),
};
},
}),
],
});
If you're using React, read our docs to learn how to set up your React Router integration.
This function can be used to filter out unwanted spans such as XHRs running health checks or something similar. If this function isn't specified, spans will be created for all requests.
Sentry.init({
// ...
integrations: [
Sentry.browserTracingIntegration({
shouldCreateSpanForRequest: (url) => {
// Do not create spans for outgoing requests to a `/health/` endpoint
return !url.match(/\/health\/?$/);
},
}),
],
});
The idle time, measured in ms, to wait until the pageload/navigation span will be finished, if there are no unfinished spans. The pageload/navigation span will use the end timestamp of the last finished span as the endtime.
The default is 1000
.
The maximum duration of the pageload/naivgation span, measured in ms. If the duration exceeds the finalTimeout
value, it will be finished.
The default is 30000
.
The time, measured in ms, that a child span may run. If the last started child span is still running for more than this time, the pageload/navigation span will be finished.
The default is 15000
.
This flag enables or disables creation of navigation
span on history changes.
The default is true
.
This flag enables or disables creation of pageload
span on first pageload.
The default is true
.
This option flags pageload/navigation spans when tabs are moved to the background with "cancelled". Because browser background tab timing is not suited for precise measurements of operations and can affect your statistics in nondeterministic ways, we recommend that this option be enabled.
The default is true
.
This option determines whether spans for long tasks automatically get created.
The default is true
.
The enableLongAnimationFrame
option requires SDK version 8.18.0 or higher.
This option determines whether spans for long animation frames get created automatically. If both enableLongAnimationFrame
and enableLongTask
are enabled, Sentry will send long animation frames and fallback to long tasks (if long animation frames aren't supported by the browser).
The default is true
.
The enableInp
option requires SDK version 7.104.0 or higher.
This option determines whether interactions spans automatically get created when an Interaction to Next Paint (INP) event is detected. Interactions are scored and surfaced in the Web Vitals module.
The default is true
in 8.x
of the SDK, and false
in 7.x
.
INP samples currently incur no cost to enable at Sentry. Basic samples contain limited information such as the interaction target, latency, and user. You may wish to enrich your INP samples by setting up Session Replays and/or setting up Browser Profiling instrumentation around your interactive elements to gain further insights into your slowest interactions.
Please note that any Session Replays and Browser Profiles used this way will incur their standard cost depending on your plan and are subject to the sampling rates configured.
Sentry.init({
// ...
integrations: [
Sentry.browserTracingIntegration({
enableInp: true,
}),
],
});
This option determines the sample rate of INP spans. interactionsSampleRate
is applied on top of tracesSampleRate
, therefore if your interactionsSampleRate
is set to 0.5
and your tracesSampleRate
is set to 0.1
, the outcome will be 0.05
.
The default is 1.0
.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").