diff --git a/docs/platforms/javascript/common/configuration/integrations/http.mdx b/docs/platforms/javascript/common/configuration/integrations/http.mdx
index c3666472ad12d8..31c73e77d9f6e5 100644
--- a/docs/platforms/javascript/common/configuration/integrations/http.mdx
+++ b/docs/platforms/javascript/common/configuration/integrations/http.mdx
@@ -93,7 +93,7 @@ The callback function receives two arguments:
_Type: `boolean`_ (Defaults to `true`)
-Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers.
+Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator already handles outgoing trace propagation.
### `ignoreOutgoingRequests`
diff --git a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx
index e18f6fea19c0be..1314528f41519c 100644
--- a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx
+++ b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx
@@ -61,7 +61,7 @@ If set to false, no breadcrumbs will be captured.
_Type: `boolean`_ (Defaults to `true`)
-Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers.
+Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator already handles outgoing trace propagation.
### `ignoreOutgoingRequests`
diff --git a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx
new file mode 100644
index 00000000000000..5c38402902538c
--- /dev/null
+++ b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx
@@ -0,0 +1,96 @@
+---
+title: OpenTelemetry
+description: "Connect Sentry to an OpenTelemetry setup that owns tracing."
+supported:
+ - javascript.nextjs
+ - javascript.node
+ - javascript.eve
+ - javascript.aws-lambda
+ - javascript.azure-functions
+ - javascript.bun
+ - javascript.connect
+ - javascript.express
+ - javascript.fastify
+ - javascript.gcp-functions
+ - javascript.hapi
+ - javascript.hono
+ - javascript.koa
+ - javascript.nestjs
+ - javascript.nitro
+ - javascript.nuxt
+ - javascript.solidstart
+ - javascript.sveltekit
+ - javascript.astro
+ - javascript.remix
+ - javascript.react-router
+ - javascript.tanstackstart-react
+notSupported:
+ - javascript
+---
+
+
+
+_Import name: `Sentry.openTelemetryIntegration`_
+
+This integration is not enabled by default. Use it when OpenTelemetry owns tracing in your application and you want Sentry's errors, logs, metrics, and check-ins to land on the same traces.
+
+Everything Sentry sends that carries trace information is attached to the OpenTelemetry span that's active when it happens, so it shows up on the same trace as the spans your OpenTelemetry SDK exports. Outgoing request propagation is left to your OpenTelemetry propagator.
+
+An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own. If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context.
+
+
+
+This integration sends no spans. To get your OpenTelemetry spans into Sentry, point your own exporter at Sentry's OTLP endpoint with `getOtlpTracesEndpoint()`, as shown below.
+
+
+
+## Configure
+
+This integration runs on the server and takes no options. Leave Sentry tracing off so the two pipelines stay separate. `getOtlpTracesEndpoint()` turns your DSN into the URL and authentication headers of Sentry's OTLP endpoint:
+
+```javascript {filename: instrument.mjs}
+import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
+import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
+import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
+import * as Sentry from "___SDK_PACKAGE___";
+
+const dsn = "___PUBLIC_DSN___";
+const endpoint = Sentry.getOtlpTracesEndpoint(dsn);
+
+if (!endpoint) {
+ throw new Error("Could not parse the Sentry DSN");
+}
+
+const provider = new NodeTracerProvider({
+ spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter(endpoint))],
+});
+
+provider.register();
+
+Sentry.init({
+ dsn,
+ // Leave the OpenTelemetry setup to your own provider.
+ enableOpenTelemetrySetup: false,
+ // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns spans.
+ integrations: [Sentry.openTelemetryIntegration()],
+});
+```
+
+If you already have a provider, add the exporter to that provider instead of registering a second one. Initialize OpenTelemetry before calling `Sentry.init()`. In frameworks with their own instrumentation entry point, initialize both there in that order.
+
+Set `enableOpenTelemetrySetup: false`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off.
+
+For sampling guidance, see the OpenTelemetry setup guide.
+
+## `getOtlpTracesEndpoint`
+
+`Sentry.getOtlpTracesEndpoint(dsn)` converts a Sentry DSN into configuration for an OpenTelemetry HTTP trace exporter. It takes a DSN string and returns an object with these fields:
+
+| Field | Type | Description |
+| --------- | ------------------------ | ------------------------------------------------------------------- |
+| `url` | `string` | The project's Sentry OTLP traces endpoint. |
+| `headers` | `Record` | Authentication headers for the endpoint, including `X-Sentry-Auth`. |
+
+If the helper cannot parse the DSN, it returns `undefined`. The helper does not register a provider or send spans.
+
+Pass the result to `OTLPTraceExporter` and add it to your provider with a `BatchSpanProcessor`, as shown in the [configuration example](#configure). If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper.
diff --git a/docs/platforms/javascript/common/install/esm.mdx b/docs/platforms/javascript/common/install/esm.mdx
index d222a843810b87..1e94c9aadb69c6 100644
--- a/docs/platforms/javascript/common/install/esm.mdx
+++ b/docs/platforms/javascript/common/install/esm.mdx
@@ -52,29 +52,3 @@ on `--import` or `NODE_OPTIONS`, use the
+Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span.
-Use this guide when you already have a completely custom OpenTelemetry setup or when you intend to add a custom OpenTelemetry setup next to the Sentry SDK.
+Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors.
-Setting `skipOpenTelemetrySetup: true` disables the Sentry SDK's automatic OpenTelemetry configuration, **requiring** you to perform the setup manually. For example, to ensure errors are correctly associated with their scope, you must add the `SentryContextManager` to your OpenTelemetry setup. You can find details on the required manual setup further down on this page.
+Initialize your OpenTelemetry provider before calling `Sentry.init()`.
-If you are looking to simply add individual OpenTelemetry instrumentation to your Sentry setup, you should read Adding Additional OpenTelemetry Instrumentation instead.
+## Send OpenTelemetry Spans to Sentry
-
+Add an OTLP exporter to your existing provider. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. `Sentry.getOtlpTracesEndpoint()` supplies the endpoint URL and authentication headers for your DSN.
-
-
+This example uses `NodeTracerProvider`. Add the same span processor to `spanProcessors` if you use `NodeSDK` instead. Keep your existing sampler, propagator, context manager, and instrumentation; do not register a second provider.
-If you don't need the full `@sentry/node` SDK and want a simpler way to bridge your existing OpenTelemetry setup with Sentry, consider using lightweight mode with the OTLP integration instead. It requires significantly less manual wiring.
+```javascript {filename: instrument.mjs}
+import * as Sentry from "___SDK_PACKAGE___";
+import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
+import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
+import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
-
-
+const dsn = "___PUBLIC_DSN___";
+const endpoint = Sentry.getOtlpTracesEndpoint(dsn);
-
+if (!endpoint) {
+ throw new Error("Could not parse the Sentry DSN");
+}
-## Using Sentry for Error Monitoring Only
-
-If you have a custom OpenTelemetry setup and only want to use Sentry for error monitoring, you can skip adding the `SentrySpanProcessor`. You'll still need to add the `SentryContextManager`, `SentryPropagator`, and `SentrySampler` to your setup even if you don't want to send any tracing data to Sentry. Read on to learn why this is needed.
-
-In order for the Sentry SDK to work as expected, and for it to be in sync with OpenTelemetry, we need a few components to be in place.
-
-**Components needed for Sentry to work correctly:**
-
-- **SentryContextManager**: Ensures that the OpenTelemetry context is in sync with Sentry, for example to correctly isolate data between simultaneous requests.
-- **SentrySampler**: Ensures that the Sentry `tracesSampleRate` is respected. Even if you don't use Sentry for tracing, you'll still need this in order for trace propagation to work as expected. Read [Using a Custom Sampler](./#using-a-custom-sampler) if you want to use a custom sampler.
-- **SentryPropagator**: Ensures that trace propagation works correctly.
-- [Required Instrumentation](./#required-instrumentation): Ensures that trace propagation works correctly.
-
-**Additional components needed to also use Sentry for tracing:**
-
-- **SentrySpanProcessor**: Ensures that spans are correctly sent to Sentry.
-
-
- Trace propagation is needed for Sentry to automatically connect services
- together. (For example, if you want to connect the frontend and backend, or
- different backend services.) This makes it possible to see related errors
- across services.{" "}
-
- Learn more about Trace Propagation.
-
-
-
-The following code snippet shows how to set up Sentry for error monitoring only:
-
-
-
-## Required Instrumentation
-
-By default, Sentry will register OpenTelemetry instrumentation to automatically capture spans for traces spanning incoming and outgoing HTTP requests, DB queries, and more.
-
-If tracing is not enabled (no `tracesSampleRate` is defined in the SDK configuration), only a minimal amount of OpenTelemetry instrumentation will be registered. This includes the following:
-
-{/* prettier-ignore-start */}
-
-- A Sentry-specific HTTP instrumentation that handles request isolation and trace propagation. This can work in parallel with [@opentelemetry/instrumentation-http](https://www.npmjs.com/package/@opentelemetry/instrumentation-http), if you register it.
-- [nativeNodeFetchIntegration](/platforms/javascript/guides/node/configuration/integrations/nodefetch/) registers [opentelemetry-instrumentation-fetch-node](https://www.npmjs.com/package/opentelemetry-instrumentation-fetch-node) which is needed for trace propagation.
-
-{/* prettier-ignore-end */}
-
-
-
- If tracing is not enabled, performance instrumentations will not be
- registered but they will still be included in the bundle. If you want to
- reduce the bundle size or used dependencies, you can also{" "}
-
- Set up Sentry without Performance Integrations
-
-
-
-
-These are needed to make sure that trace propagation works correctly.
-
-If you want to add your own http/node-fetch instrumentation, you have to follow the following steps:
-
-### Custom HTTP Instrumentation
-
-
-
-You can add your own `@opentelemetry/instrumentation-http` instance in your OpenTelemetry setup. However, in this case, you need to disable span creation in Sentry's `httpIntegration`. You can also set `tracePropagation: false` to prevent Sentry from injecting trace headers, letting your OpenTelemetry setup handle propagation instead:
-
-
- ```javascript
- const sentryClient = Sentry.init({
- dsn: "___DSN___",
- skipOpenTelemetrySetup: true,
- integrations: [Sentry.httpIntegration({ spans: false, tracePropagation: false })],
-});
- ```
-
-
-
-```javascript
- const sentryClient = Sentry.init({
- dsn: "___DSN___",
- skipOpenTelemetrySetup: true,
- integrations: (integrations) =>
- // Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation
- integrations.filter((i) => i.name !== "BunServer")
+const provider = new NodeTracerProvider({
+ spanProcessors: [
+ new BatchSpanProcessor(new OTLPTraceExporter(endpoint)),
+ // Keep any other span processors you already use.
+ ],
});
-```
-
-
-It's important that `httpIntegration` is still registered this way to ensure that the Sentry SDK can correctly isolate requests, for example when capturing errors.
-### Custom Node Fetch Instrumentation
+provider.register();
-If tracing is disabled, the Node Fetch instrumentation will not emit any spans. In this scenario, it will only inject sentry-specific trace propagation headers. You are free to add your own Node Fetch instrumentation on top of this which may emit spans as you like.
-
-If your OpenTelemetry setup already handles trace propagation for fetch requests, you can set `tracePropagation: false` to prevent Sentry from injecting duplicate trace headers:
-
-```javascript
-const sentryClient = Sentry.init({
- dsn: "___DSN___",
- skipOpenTelemetrySetup: true,
- integrations: [
- Sentry.nativeNodeFetchIntegration({ tracePropagation: false }),
- ],
+Sentry.init({
+ dsn,
+ enableOpenTelemetrySetup: false,
+ // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing.
+ integrations: [Sentry.openTelemetryIntegration()],
});
```
-## Using a Custom Sampler
-
-While you can use your own sampler, we recommend that you use the `SentrySampler`. This will ensure that the correct subset of traces will be sent to Sentry, based on your `tracesSampleRate`. It will also ensure that all other Sentry features like trace propagation work as expected. If you do need to use your own sampler, make sure to wrap your `SamplingResult` with our `wrapSamplingDecision` method like in the example below:
-
-
-
-
-
-It is recommended registering your own ESM loader hooks when you have a complete custom OpenTelemetry setup, first and foremost because it makes the most sense architecturally.
-You likely went through the effort to set up OpenTelemetry by itself and now you want to add Sentry to your application without messing with your OpenTelemetry setup.
-
-Additionally, there are a few pitfalls that can very simply be avoided by registering your own hooks:
+## Use Sentry for Error Monitoring Only
-- Registering loader hooks multiple times might result in duplicated spans being created. [More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961)
-- OpenTelemetry instrumentation in ESM is very sensitive as to _when_ it is added relative to _when_ the loader hooks are registered.
- The control over this should stay with the owner of the OpenTelemetry setup and not the Sentry SDK.
+If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit the Sentry OTLP exporter from the example above. The `Sentry.init()` configuration stays the same. `openTelemetryIntegration()` links Sentry errors to the active OpenTelemetry trace without sending spans to Sentry.
-
+## Configure Sampling
-
-
-
- Learn more about ESM installation methods.
-
-
-
+Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface.
diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx
new file mode 100644
index 00000000000000..0499cec6813aa8
--- /dev/null
+++ b/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx
@@ -0,0 +1,210 @@
+---
+title: Using Your Existing OpenTelemetry Setup
+description: "Learn how to use your existing custom OpenTelemetry setup with Sentry."
+supported:
+ - javascript.nextjs
+ - javascript.node
+ - javascript.eve
+ - javascript.aws-lambda
+ - javascript.azure-functions
+ - javascript.bun
+ - javascript.connect
+ - javascript.express
+ - javascript.fastify
+ - javascript.gcp-functions
+ - javascript.hapi
+ - javascript.hono
+ - javascript.koa
+ - javascript.nestjs
+ - javascript.nitro
+ - javascript.nuxt
+ - javascript.solidstart
+ - javascript.sveltekit
+ - javascript.astro
+ - javascript.remix
+ - javascript.react-router
+ - javascript.tanstackstart-react
+notSupported:
+ - javascript
+sidebar_order: 0
+---
+
+
+
+Use this guide when you already have a completely custom OpenTelemetry setup or when you intend to add a custom OpenTelemetry setup next to the Sentry SDK.
+
+Setting `skipOpenTelemetrySetup: true` disables the Sentry SDK's automatic OpenTelemetry configuration, **requiring** you to perform the setup manually. For example, to ensure errors are correctly associated with their scope, you must add the `SentryContextManager` to your OpenTelemetry setup. You can find details on the required manual setup further down on this page.
+
+If you are looking to simply add individual OpenTelemetry instrumentation to your Sentry setup, you should read Adding Additional OpenTelemetry Instrumentation instead.
+
+
+
+
+
+
+If you don't need the full `@sentry/node` SDK and want a simpler way to bridge your existing OpenTelemetry setup with Sentry, consider using lightweight mode with the OTLP integration instead. It requires significantly less manual wiring.
+
+
+
+
+
+
+
+
+
+
+
+
+## Using Sentry for Error Monitoring Only
+
+If you have a custom OpenTelemetry setup and only want to use Sentry for error monitoring, you can skip adding the `SentrySpanProcessor`. You'll still need to add the `SentryContextManager`, `SentryPropagator`, and `SentrySampler` to your setup even if you don't want to send any tracing data to Sentry. Read on to learn why this is needed.
+
+In order for the Sentry SDK to work as expected, and for it to be in sync with OpenTelemetry, we need a few components to be in place.
+
+**Components needed for Sentry to work correctly:**
+
+- **SentryContextManager**: Ensures that the OpenTelemetry context is in sync with Sentry, for example to correctly isolate data between simultaneous requests.
+- **SentrySampler**: Ensures that the Sentry `tracesSampleRate` is respected. Even if you don't use Sentry for tracing, you'll still need this in order for trace propagation to work as expected. Read [Using a Custom Sampler](#using-a-custom-sampler) if you want to use a custom sampler.
+- **SentryPropagator**: Ensures that trace propagation works correctly.
+- [Required Instrumentation](#required-instrumentation): Ensures that trace propagation works correctly.
+
+**Additional components needed to also use Sentry for tracing:**
+
+- **SentrySpanProcessor**: Ensures that spans are correctly sent to Sentry.
+
+
+ Trace propagation is needed for Sentry to automatically connect services
+ together. (For example, if you want to connect the frontend and backend, or
+ different backend services.) This makes it possible to see related errors
+ across services.{" "}
+
+ Learn more about Trace Propagation.
+
+
+
+The following code snippet shows how to set up Sentry for error monitoring only:
+
+
+
+
+
+
+
+
+
+## Required Instrumentation
+
+By default, Sentry will register OpenTelemetry instrumentation to automatically capture spans for traces spanning incoming and outgoing HTTP requests, DB queries, and more.
+
+If tracing is not enabled (no `tracesSampleRate` is defined in the SDK configuration), only a minimal amount of OpenTelemetry instrumentation will be registered. This includes the following:
+
+{/* prettier-ignore-start */}
+
+- A Sentry-specific HTTP instrumentation that handles request isolation and trace propagation. This can work in parallel with [@opentelemetry/instrumentation-http](https://www.npmjs.com/package/@opentelemetry/instrumentation-http), if you register it.
+- [nativeNodeFetchIntegration](/platforms/javascript/guides/node/configuration/integrations/nodefetch/) registers [opentelemetry-instrumentation-fetch-node](https://www.npmjs.com/package/opentelemetry-instrumentation-fetch-node) which is needed for trace propagation.
+
+{/* prettier-ignore-end */}
+
+
+
+ If tracing is not enabled, performance instrumentations will not be
+ registered but they will still be included in the bundle. If you want to
+ reduce the bundle size or used dependencies, you can also{" "}
+
+ Set up Sentry without Performance Integrations
+
+
+
+
+These are needed to make sure that trace propagation works correctly.
+
+If you want to add your own http/node-fetch instrumentation, you have to follow the following steps:
+
+### Custom HTTP Instrumentation
+
+
+
+You can add your own `@opentelemetry/instrumentation-http` instance in your OpenTelemetry setup. However, in this case, you need to disable span creation in Sentry's `httpIntegration`. You can also set `tracePropagation: false` to prevent Sentry from injecting trace headers, letting your OpenTelemetry setup handle propagation instead:
+
+
+ ```javascript
+ const sentryClient = Sentry.init({
+ dsn: "___DSN___",
+ skipOpenTelemetrySetup: true,
+ integrations: [Sentry.httpIntegration({ spans: false, tracePropagation: false })],
+});
+ ```
+
+
+
+```javascript
+ const sentryClient = Sentry.init({
+ dsn: "___DSN___",
+ skipOpenTelemetrySetup: true,
+ integrations: (integrations) =>
+ // Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation
+ integrations.filter((i) => i.name !== "BunServer")
+});
+```
+
+
+It's important that `httpIntegration` is still registered this way to ensure that the Sentry SDK can correctly isolate requests, for example when capturing errors.
+
+### Custom Node Fetch Instrumentation
+
+If tracing is disabled, the Node Fetch instrumentation will not emit any spans. In this scenario, it will only inject sentry-specific trace propagation headers. You are free to add your own Node Fetch instrumentation on top of this which may emit spans as you like.
+
+If your OpenTelemetry setup already handles trace propagation for fetch requests, you can set `tracePropagation: false` to prevent Sentry from injecting duplicate trace headers:
+
+```javascript
+const sentryClient = Sentry.init({
+ dsn: "___DSN___",
+ skipOpenTelemetrySetup: true,
+ integrations: [
+ Sentry.nativeNodeFetchIntegration({ tracePropagation: false }),
+ ],
+});
+```
+
+## Using a Custom Sampler
+
+While you can use your own sampler, we recommend that you use the `SentrySampler`. This will ensure that the correct subset of traces will be sent to Sentry, based on your `tracesSampleRate`. It will also ensure that all other Sentry features like trace propagation work as expected. If you do need to use your own sampler, make sure to wrap your `SamplingResult` with our `wrapSamplingDecision` method like in the example below:
+
+
+
+
+
+
+
+
+
+
+
+It is recommended registering your own ESM loader hooks when you have a complete custom OpenTelemetry setup, first and foremost because it makes the most sense architecturally.
+You likely went through the effort to set up OpenTelemetry by itself and now you want to add Sentry to your application without messing with your OpenTelemetry setup.
+
+Additionally, there are a few pitfalls that can very simply be avoided by registering your own hooks:
+
+- Registering loader hooks multiple times might result in duplicated spans being created. [More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961)
+- OpenTelemetry instrumentation in ESM is very sensitive as to _when_ it is added relative to _when_ the loader hooks are registered.
+ The control over this should stay with the owner of the OpenTelemetry setup and not the Sentry SDK.
+
+
+
+
+
+
+ Learn more about ESM installation methods.
+
+
+
diff --git a/docs/platforms/javascript/common/opentelemetry/index.mdx b/docs/platforms/javascript/common/opentelemetry/index.mdx
index fbde8fe769b4c0..9416efde7d57a5 100644
--- a/docs/platforms/javascript/common/opentelemetry/index.mdx
+++ b/docs/platforms/javascript/common/opentelemetry/index.mdx
@@ -29,13 +29,10 @@ supported:
- javascript.tanstackstart-react
notSupported:
- javascript
-beta: true
---
-The Sentry SDK uses [OpenTelemetry](https://opentelemetry.io/) under the hood. This means that any OpenTelemetry instrumentation that emits spans will automatically be picked up by Sentry without any further configuration.
+The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. For the default setup, see Tracing.
-To start capturing traces and spans, set up Tracing and Performance Monitoring with your Sentry SDK. If you don't use tracing, Sentry still connects to OpenTelemetry under the hood to ensure that context isolation and trace propagation works correctly.
-
-By default, Sentry will automatically set up OpenTelemetry for you, but you can also use your own OpenTelemetry setup. Read the guides below to learn how to use a custom OpenTelemetry setup or how to get the most out of the Sentry and OpenTelemetry integration.
+If your application also uses OpenTelemetry, choose a setup based on which SDK manages tracing:
diff --git a/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx
new file mode 100644
index 00000000000000..57eb7542bc1b9e
--- /dev/null
+++ b/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx
@@ -0,0 +1,41 @@
+---
+title: OpenTelemetry Support
+description: "Learn how to use OpenTelemetry with Sentry."
+sidebar_order: 14
+sidebar_section: configuration
+supported:
+ - javascript.nextjs
+ - javascript.node
+ - javascript.eve
+ - javascript.aws-lambda
+ - javascript.azure-functions
+ - javascript.bun
+ - javascript.connect
+ - javascript.express
+ - javascript.fastify
+ - javascript.gcp-functions
+ - javascript.hapi
+ - javascript.hono
+ - javascript.koa
+ - javascript.nestjs
+ - javascript.nitro
+ - javascript.nuxt
+ - javascript.solidstart
+ - javascript.sveltekit
+ - javascript.astro
+ - javascript.remix
+ - javascript.react-router
+ - javascript.tanstackstart-react
+notSupported:
+ - javascript
+beta: true
+---
+
+The Sentry SDK uses [OpenTelemetry](https://opentelemetry.io/) under the hood. This means that any OpenTelemetry instrumentation that emits spans will automatically be picked up by Sentry without any further configuration.
+
+To start capturing traces and spans, set up Tracing and Performance Monitoring with your Sentry SDK. If you don't use tracing, Sentry still connects to OpenTelemetry under the hood to ensure that context isolation and trace propagation works correctly.
+
+By default, Sentry will automatically set up OpenTelemetry for you, but you can also use your own OpenTelemetry setup. Read the guides below to learn how to use a custom OpenTelemetry setup or how to get the most out of the Sentry and OpenTelemetry integration.
+
+- Using Your Existing OpenTelemetry Setup
+- Using OpenTelemetry APIs
diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx
index 40bc8d5179743b..0a1db82c1b4f71 100644
--- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx
+++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx
@@ -1,6 +1,7 @@
---
-title: Using OpenTelemetry APIs
-description: "Learn how to use OpenTelemetry APIs with Sentry."
+title: Capture Spans from OpenTelemetry APIs
+description: "Let Sentry capture and send spans created by OpenTelemetry APIs."
+sidebar_order: 0
supported:
- javascript.nextjs
- javascript.node
@@ -27,127 +28,31 @@ supported:
- javascript.tanstackstart-react
notSupported:
- javascript
-sidebar_order: 1
---
-Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenTelemetry APIs will be automatically captured by Sentry, while any spans started using the Sentry SDK will be automatically propagated to OpenTelemetry.
+To capture spans that your code or a library creates through `@opentelemetry/api`, set `enableOpenTelemetrySetup: true`. Sentry registers an OpenTelemetry-compatible tracer provider, context manager, and propagator. Spans created through `@opentelemetry/api` become native Sentry spans. Sentry's tracing configuration controls sampling and export.
-## Adding Additional OpenTelemetry Instrumentation
-
-While the Sentry SDK includes some OpenTelemetry instrumentation out of the box, you may want to add additional instrumentation to your application. This can be done by registering the instrumentation through OpenTelemetry like the example below:
-
-```javascript {tabTitle: ESM} {12-13}
-import * as Sentry from "@sentry/node";
-import {
- GenericPoolInstrumentation,
-} from "@opentelemetry/instrumentation-generic-pool";
+```javascript
+import * as Sentry from "___SDK_PACKAGE___";
+import { trace } from "@opentelemetry/api";
Sentry.init({
- dsn: "___DSN___",
-
- // The SentrySampler will use this to determine which traces to sample
+ dsn: "___PUBLIC_DSN___",
+ enableOpenTelemetrySetup: true,
tracesSampleRate: 1.0,
-
- // Add additional OpenTelemetry instrumentation:
- openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
-});
-```
-```javascript {tabTitle: CJS} {12-13}
-const Sentry = require("@sentry/node");
-const {
- GenericPoolInstrumentation,
-} = require("@opentelemetry/instrumentation-generic-pool");
-
-Sentry.init({
- dsn: "___DSN___",
-
- // The SentrySampler will use this to determine which traces to sample
- tracesSampleRate: 1.0,
-
- // Add additional OpenTelemetry instrumentation:
- openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
-});
-```
-
-
- It is possible to add instrumentations via `registerInstrumentations()` from
- `@opentelemetry/instrumentation`. However, with ESM (`import`/`export` syntax)
- you need to be careful to do so before importing any modules that should be
- instrumented.
-
-As a rule of thumb, `registerInstrumentations()` should be called right after, and in the same context as registering ESM Loaders.
-
-
-
-## Using an OpenTelemetry Tracer
-
-We recommend using `Sentry.startSpan()` and related APIs to create spans, but you can also create spans using native OpenTelemetry APIs.
-
-You can access the tracer Sentry uses via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below:
-
-```javascript {tabTitle: ESM}
-import * as Sentry from "@sentry/node";
-
-const tracer = Sentry.getClient()?.tracer;
-// Now you can use native APIs on the tracer:
-tracer.startActiveSpan("span name", () => {
- // measure something
-});
-```
-```javascript {tabTitle: CJS}
-const Sentry = require("@sentry/node");
-
-const tracer = Sentry.getClient()?.tracer;
-// Now you can use native APIs on the tracer:
-tracer.startActiveSpan("span name", () => {
- // measure something
});
-```
-
-You can also use any other tracer. All OpenTelemetry spans will be picked up by Sentry automatically.
-
-## Modifying the default OpenTelemetry TracerProvider
-
-You can access the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
-
-```javascript {tabTitle: ESM}
-import * as Sentry from "@sentry/node";
-
-const provider = Sentry.getClient()?.traceProvider;
-```
-```javascript {tabTitle: CJS}
-const Sentry = require("@sentry/node");
-
-const provider = Sentry.getClient()?.traceProvider;
-```
-## Adding Additional Span Processors
+const tracer = trace.getTracer("my-app");
-You can add additional span processors to the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
-
-```javascript {tabTitle: ESM}
-import * as Sentry from "@sentry/node";
-
-Sentry.init({
- dsn: "___DSN___",
-
- // The SentrySampler will use this to determine which traces to sample
- tracesSampleRate: 1.0,
-
- // Add additional OpenTelemetry SpanProcessors:
- openTelemetrySpanProcessors: [new MySpanProcessor()],
+tracer.startActiveSpan("process-order", (span) => {
+ try {
+ // Your synchronous work here.
+ } finally {
+ span.end();
+ }
});
```
-```javascript {tabTitle: CJS}
-const Sentry = require("@sentry/node");
-Sentry.init({
- dsn: "___DSN___",
-
- // The SentrySampler will use this to determine which traces to sample
- tracesSampleRate: 1.0,
+Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use your own OpenTelemetry pipeline instead. Sentry will not replace an existing provider.
- // Add additional OpenTelemetry SpanProcessors:
- openTelemetrySpanProcessors: [new MySpanProcessor()],
-});
-```
+Most server SDKs leave `enableOpenTelemetrySetup` off by default. The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable it by default to capture spans emitted by those frameworks.
diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx
new file mode 100644
index 00000000000000..d114441401a19c
--- /dev/null
+++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx
@@ -0,0 +1,152 @@
+---
+title: Using OpenTelemetry APIs
+description: "Learn how to use OpenTelemetry APIs with Sentry."
+supported:
+ - javascript.nextjs
+ - javascript.node
+ - javascript.eve
+ - javascript.aws-lambda
+ - javascript.azure-functions
+ - javascript.bun
+ - javascript.connect
+ - javascript.express
+ - javascript.fastify
+ - javascript.gcp-functions
+ - javascript.hapi
+ - javascript.hono
+ - javascript.koa
+ - javascript.nestjs
+ - javascript.nitro
+ - javascript.nuxt
+ - javascript.solidstart
+ - javascript.sveltekit
+ - javascript.astro
+ - javascript.remix
+ - javascript.react-router
+ - javascript.tanstackstart-react
+notSupported:
+ - javascript
+sidebar_order: 1
+---
+
+Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenTelemetry APIs will be automatically captured by Sentry, while any spans started using the Sentry SDK will be automatically propagated to OpenTelemetry.
+
+## Adding Additional OpenTelemetry Instrumentation
+
+While the Sentry SDK includes some OpenTelemetry instrumentation out of the box, you may want to add additional instrumentation to your application. This can be done by registering the instrumentation through OpenTelemetry like the example below:
+
+```javascript {tabTitle: ESM} {12-13}
+import * as Sentry from "@sentry/node";
+import {
+ GenericPoolInstrumentation,
+} from "@opentelemetry/instrumentation-generic-pool";
+
+Sentry.init({
+ dsn: "___DSN___",
+
+ // The SentrySampler will use this to determine which traces to sample
+ tracesSampleRate: 1.0,
+
+ // Add additional OpenTelemetry instrumentation:
+ openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
+});
+```
+```javascript {tabTitle: CJS} {12-13}
+const Sentry = require("@sentry/node");
+const {
+ GenericPoolInstrumentation,
+} = require("@opentelemetry/instrumentation-generic-pool");
+
+Sentry.init({
+ dsn: "___DSN___",
+
+ // The SentrySampler will use this to determine which traces to sample
+ tracesSampleRate: 1.0,
+
+ // Add additional OpenTelemetry instrumentation:
+ openTelemetryInstrumentations: [new GenericPoolInstrumentation()],
+});
+```
+
+
+ It is possible to add instrumentations via `registerInstrumentations()` from
+ `@opentelemetry/instrumentation`. However, with ESM (`import`/`export` syntax)
+ you need to be careful to do so before importing any modules that should be
+ instrumented.
+
+As a rule of thumb, `registerInstrumentations()` should be called right after, and in the same context as registering ESM Loaders.
+
+
+
+## Using an OpenTelemetry Tracer
+
+We recommend using `Sentry.startSpan()` and related APIs to create spans, but you can also create spans using native OpenTelemetry APIs.
+
+You can access the tracer Sentry uses via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below:
+
+```javascript {tabTitle: ESM}
+import * as Sentry from "@sentry/node";
+
+const tracer = Sentry.getClient()?.tracer;
+// Now you can use native APIs on the tracer:
+tracer.startActiveSpan("span name", () => {
+ // measure something
+});
+```
+```javascript {tabTitle: CJS}
+const Sentry = require("@sentry/node");
+
+const tracer = Sentry.getClient()?.tracer;
+// Now you can use native APIs on the tracer:
+tracer.startActiveSpan("span name", () => {
+ // measure something
+});
+```
+
+You can also use any other tracer. All OpenTelemetry spans will be picked up by Sentry automatically.
+
+## Modifying the default OpenTelemetry TracerProvider
+
+You can access the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
+
+```javascript {tabTitle: ESM}
+import * as Sentry from "@sentry/node";
+
+const provider = Sentry.getClient()?.traceProvider;
+```
+```javascript {tabTitle: CJS}
+const Sentry = require("@sentry/node");
+
+const provider = Sentry.getClient()?.traceProvider;
+```
+
+## Adding Additional Span Processors
+
+You can add additional span processors to the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation.
+
+```javascript {tabTitle: ESM}
+import * as Sentry from "@sentry/node";
+
+Sentry.init({
+ dsn: "___DSN___",
+
+ // The SentrySampler will use this to determine which traces to sample
+ tracesSampleRate: 1.0,
+
+ // Add additional OpenTelemetry SpanProcessors:
+ openTelemetrySpanProcessors: [new MySpanProcessor()],
+});
+```
+```javascript {tabTitle: CJS}
+const Sentry = require("@sentry/node");
+
+Sentry.init({
+ dsn: "___DSN___",
+
+ // The SentrySampler will use this to determine which traces to sample
+ tracesSampleRate: 1.0,
+
+ // Add additional OpenTelemetry SpanProcessors:
+ openTelemetrySpanProcessors: [new MySpanProcessor()],
+});
+```
diff --git a/docs/platforms/javascript/guides/nestjs/install/esm.mdx b/docs/platforms/javascript/guides/nestjs/install/esm.mdx
index 9ba9ba454e9a06..fb036cb73ad7a8 100644
--- a/docs/platforms/javascript/guides/nestjs/install/esm.mdx
+++ b/docs/platforms/javascript/guides/nestjs/install/esm.mdx
@@ -42,29 +42,3 @@ NODE_OPTIONS="--import ./instrument.mjs" npm run start
```
We do not support ESM in Node versions before 18.19.0.
-
-## Troubleshooting ESM Instrumentation
-
-By default, all packages are automatically wrapped by
-[import-in-the-middle](https://www.npmjs.com/package/import-in-the-middle) to
-aid instrumenting them.
-
-If `import-in-the-middle` encounters problems wrapping a package, you may see
-syntax errors at runtime or logged errors in your console:
-
-```logs
-SyntaxError: The requested module '...' does not provide an export named '...'
-(node:3368) Error: 'import-in-the-middle' failed to wrap 'file://../../path/to/file.js'
-```
-
-To confirm that these errors are caused by `import-in-the-middle`,
-disable it by setting `registerEsmLoaderHooks` to false. Note, this will also
-disable tracing instrumentation:
-
-```javascript {tabTitle:ESM} {filename: instrument.mjs} {4}
-import * as Sentry from "@sentry/nestjs";
-
-Sentry.init({
- registerEsmLoaderHooks: false,
-});
-```
diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx
similarity index 100%
rename from platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx
rename to platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx
diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx
similarity index 100%
rename from platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx
rename to platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx
diff --git a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx
similarity index 95%
rename from platform-includes/performance/opentelemetry-setup/javascript.bun.mdx
rename to platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx
index 4927978b8dd075..8a9c210fb0eba9 100644
--- a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx
+++ b/platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx
@@ -83,4 +83,4 @@ sdk.start();
validateOpenTelemetrySetup();
```
-Make sure that all [Required OpenTelemetry Instrumentation](./#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected.
+Make sure that all [Required OpenTelemetry Instrumentation](#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected.
diff --git a/platform-includes/performance/opentelemetry-setup/javascript.mdx b/platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx
similarity index 94%
rename from platform-includes/performance/opentelemetry-setup/javascript.mdx
rename to platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx
index 8e89e864d6d5b6..70515a91aa4d2a 100644
--- a/platform-includes/performance/opentelemetry-setup/javascript.mdx
+++ b/platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx
@@ -75,4 +75,4 @@ sdk.start();
Sentry.validateOpenTelemetrySetup();
```
-Make sure that all [Required OpenTelemetry Instrumentation](./#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected.
+Make sure that all [Required OpenTelemetry Instrumentation](#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected.
diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx
similarity index 100%
rename from platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx
rename to platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx
diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx
similarity index 100%
rename from platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx
rename to platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx
diff --git a/redirects.js b/redirects.js
index ce4a3cae7c4551..c886196053f4db 100644
--- a/redirects.js
+++ b/redirects.js
@@ -588,6 +588,17 @@ const developerDocsRedirects = [
/** @type {import('next/dist/lib/load-custom-routes').Redirect[]} */
const userDocsRedirects = [
+ {
+ source: '/platforms/javascript/guides/:guide/opentelemetry/integration/',
+ destination:
+ '/platforms/javascript/guides/:guide/configuration/integrations/opentelemetry/',
+ },
+ {
+ source: '/platforms/javascript/guides/:guide/opentelemetry/integration.md',
+ destination:
+ '/platforms/javascript/guides/:guide/configuration/integrations/opentelemetry.md',
+ },
+
// Guides → Get Started restructure
{
source: '/guides/',