Automatic Instrumentation for Next.js

Learn what spans are captured after tracing is enabled.

@sentry/nextjs provides a BrowserTracing integration to add automatic instrumentation for monitoring the performance of browser applications, which is enabled by default once you set up tracing in your app. Further, the SDK will automatically enable error collection and tracing in your API routes and Next.js Data Fetchers.

Once you enable tracing, the SDK automatically captures performance data without additional code:

WhatDescriptionMetrics
Page loadsFull page load performanceLCP, CLS, TTFB
NavigationsClient-side route changesDuration, Web Vitals
HTTP requestsAll fetch/XHR callsDuration, status, URL
ResponsivenessInteraction to Next PaintINP
Long tasksMain thread blocking > 50msDuration, attribution

The BrowserTracing integration creates a new transaction for each pageload and navigation event, and creates a child span for every XMLHttpRequest or fetch request that occurs while those transactions are open. Additionally, the SDK creates transactions for all requests to API routes and Next.js data fetchers. Learn more about traces, transactions, and spans.

To enable tracing, simply set either a tracesSampleRate or a tracesSampler in your SDK configuration options, as detailed in Set Up Tracing.

Most apps only need these options:

tracePropagationTargets

TypeArray<string | RegExp>
Default['localhost', /^\/$/]

Controls which outgoing requests include tracing headers (sentry-trace and baggage). Required for connecting frontend spans to backend spans.

By default, tracing headers are only attached to requests containing localhost or starting with /. Add your API domains to trace requests across services:

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 and baggage headers attached.
Copied
Sentry.init({
  // ...
  integrations: [Sentry.browserTracingIntegration()],

  // Set `tracePropagationTargets` to control for which URLs trace propagation should be enabled
  tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
});

beforeStartSpan

Type(options: StartSpanOptions) => StartSpanOptions

Modify span data before it's captured. Useful for adding context or normalizing URLs with dynamic segments:

Copied
Sentry.init({
  // ...
  integrations: [
    Sentry.browserTracingIntegration({
      beforeStartSpan: (context) => {
        return {
          ...context,
          attributes: {
            ...context.attributes,
            resultFormat: "legacy",
          },
        };
      },
    }),
  ],
});

shouldCreateSpanForRequest

Type(url: string) => boolean

Exclude requests from tracing, such as health checks or analytics pings:

Copied
Sentry.init({
  // ...
  integrations: [
    Sentry.browserTracingIntegration({
      shouldCreateSpanForRequest: (url) => {
        // Do not create spans for outgoing requests to a `/health/` endpoint
        return !url.match(/\/health\/?$/);
      },
    }),
  ],
});

BrowserTracing automatically captures Web Vitals. To capture clicks and the work they trigger as spans, add the Interactions integration.

webVitals

Available since11.0.0
TypeWebVitalsOptions

Configure which Web Vitals BrowserTracing collects. For example, to disable INP collection:

Copied
Sentry.init({
  // ...
  integrations: [
    Sentry.browserTracingIntegration({
      webVitals: {
        ignore: ["inp"],
      },
    }),
  ],
});

If you explicitly add webVitalsIntegration(), configure these options on that integration instead. See WebVitals for details and browser support requirements.

BrowserTracing automatically captures INP to measure responsiveness. Results appear in the Web Vitals module.

enableInp

Available since7.104.0
Typeboolean
Defaulttrue (since version 8.0.0)

Enable or disable INP collection. Defaults to true in SDK 8 and later, and false in SDK 7.x.

Deprecated in SDK version 11. Use webVitals: { ignore: ["inp"] } to disable INP. Explicitly adding webVitalsIntegration() takes precedence over this option.

Timing & Timeout Options

These timeouts control pageload and navigation spans.

Configure timeouts for click-triggered work on the Interactions integration separately.

idleTimeout

Typenumber
Default1000

Time in ms to wait before finishing a pageload/navigation span when no unfinished child spans remain.

finalTimeout

Typenumber
Default30000

Maximum duration in ms for pageload/navigation spans. Spans exceeding this are automatically finished.

childSpanTimeout

Typenumber
Default15000

Maximum time in ms a child span can run before the parent pageload/navigation span is finished.

Enable/Disable Specific Instrumentation

instrumentPageLoad

Typeboolean
Defaulttrue

Enable/disable automatic pageload span creation on initial page load.

instrumentNavigation

Typeboolean
Defaulttrue

Enable/disable automatic navigation span creation on history changes.

instrumentBfcacheRestore

Available since11.0.0
Typeboolean
Defaulttrue

Start a navigation span when the page is restored from the back/forward cache. This starts a new trace for activity after the restore. It is independent of instrumentNavigation.

Web Vitals for restored pages are collected by default in stream mode. Set webVitals: { bfcacheNavigations: false } to disable this collection. See WebVitals for requirements.

enableLongTask

Typeboolean
Defaulttrue

Enable/disable automatic spans for long tasks (main thread blocking > 50ms).

enableLongAnimationFrame

Available since8.18.0
Typeboolean
Defaulttrue

Enable/disable spans for long animation frames. Falls back to long tasks if browser doesn't support long animation frames.

markBackgroundSpan

Typeboolean
Defaulttrue

Mark pageload/navigation spans as "cancelled" when the tab moves to background. Recommended to keep enabled for accurate measurements.

enableReportPageLoaded

Available since10.13.0
Typeboolean
Defaultfalse

Enable the Sentry.reportPageLoaded() function.

traceFetch

Typeboolean
Defaulttrue

Enable/disable automatic span creation for fetch requests.

traceXHR

Typeboolean
Defaulttrue

Enable/disable automatic span creation for XMLHttpRequest (XHR) requests.

enableHTTPTimings

Typeboolean
Defaulttrue

Enable/disable adding detailed HTTP timing data (DNS lookup, TLS handshake, etc.) to fetch/XHR spans via the Performance Resource Timing API.

linkPreviousTrace

Type'in-memory' | 'session-storage' | false
Default'in-memory'

Controls how new pageload spans are linked to the previous trace. Set to 'in-memory' to link within the same page lifecycle, 'session-storage' to persist links across page reloads via session storage, or false to disable trace linking.

Filtering & Ignoring Spans

ignoreResourceSpans

Available since9.23.0
TypeArray<string>
Default[]

Ignore specific resource span categories by their op (e.g., resource.script, resource.css):

Copied
Sentry.init({
  integrations: [
    Sentry.browserTracingIntegration({
      ignoreResourceSpans: ["resource.css", "resource.script"],
    }),
  ],
});

Use the UserTiming integration to capture performance.mark() and performance.measure() entries. To ignore entries by name:

Copied
Sentry.init({
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.userTimingIntegration({
      ignore: ["myMeasurement", /myMark/],
    }),
  ],
});

onRequestSpanStart

Type(span: Span, requestInformation: { headers?: WebFetchHeaders }): void

Callback invoked when a span starts for an outgoing fetch/XHR request. Use to annotate spans with additional attributes based on request headers.

The browserTracingIntegration is automatically enabled in @sentry/nextjs. To customize options, include it explicitly in instrumentation-client.js:

Copied
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "___PUBLIC_DSN___",
  integrations: [
    Sentry.browserTracingIntegration({
      // your options here
    }),
  ],
  tracesSampleRate: 1.0,
  tracePropagationTargets: [
    "localhost",
    /^\//,
    /^https:\/\/yourserver\.io\/api/,
  ],
});
Was this helpful?
Help improve this content
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").