From 357da46a69445e33750945b1d44f32a5755e9759 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 27 Oct 2026 12:55:50 -0400 Subject: [PATCH 01/13] docs(js): Document the managed tunnel and serveTunnelIntegration Adds the serveTunnelIntegration page, the browser tunnel: true option, a managed tunnel section in troubleshooting, framework getting-started snippets, and updates TanStack Start tunnelRoute docs for 11.10.0. --- .../integrations/servetunnel.mdx | 106 ++++++++++++++++++ .../common/configuration/options.mdx | 23 ++++ .../common/troubleshooting/index.mdx | 36 +++++- .../features/createSentryTunnelRoute.mdx | 4 +- .../features/sentryTanstackStart.mdx | 30 ++--- .../manual-setup/index.mdx | 2 +- .../javascript.nuxt.mdx | 5 +- .../javascript.astro.mdx | 19 ++++ .../javascript.nuxt.mdx | 19 ++++ .../javascript.sveltekit.mdx | 17 ++- 10 files changed, 235 insertions(+), 26 deletions(-) create mode 100644 docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx create mode 100644 platform-includes/getting-started-tunneling/javascript.astro.mdx create mode 100644 platform-includes/getting-started-tunneling/javascript.nuxt.mdx diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx new file mode 100644 index 0000000000000..0d5d3487cb0b5 --- /dev/null +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -0,0 +1,106 @@ +--- +title: ServeTunnel +description: "Serves a tunnel on your server so browser events reach Sentry through your own origin, past ad blockers." +supported: + - javascript.sveltekit + - javascript.nuxt + - javascript.nitro + - javascript.astro + - javascript.react-router + - javascript.tanstackstart-react + - javascript.solidstart + - javascript.remix + - javascript.cloudflare +--- + + + +_Import name: `Sentry.serveTunnelIntegration`_ + +Ad blockers often drop requests to `*.ingest.sentry.io`. This integration serves a tunnel endpoint from your app's server, so the browser SDK can send its events to your own origin instead. The server forwards them to Sentry. + +Set it up on both sides. Add the integration to your server `Sentry.init`: + +```javascript {filename:Server} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +And set `tunnel: true` in your browser `Sentry.init`: + +```javascript {filename:Browser} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: true, +}); +``` + +The browser and the server both derive the tunnel path from the DSN, for example `/qpo967`. You don't need a route file, a build step, or an environment variable. If your app is served under a base path, the SDK adds it on both sides. + + + +The tunnel is only served by the SDKs that answer requests from a framework hook: SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3. On other servers, see [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). + + + + + +On Cloudflare Workers, import the integration from `@sentry/cloudflare` and add it to the options you pass to `withSentry`, `defineCloudflareOptions`, or `initCloudflareSentryHandle`: + +```javascript +import { serveTunnelIntegration } from "@sentry/cloudflare"; + +export default { + dsn: "___PUBLIC_DSN___", + integrations: [serveTunnelIntegration()], +}; +``` + + + +## How It Works + +- The tunnel answers before your app's own middleware, so auth or CSRF middleware doesn't block it. +- It only forwards envelopes whose DSN is allowed. By default, that's the server's own DSN. Other envelopes get a `403`, so the tunnel can't be used as an open proxy. +- It forwards only the user agent, client hint, `Origin`, and `Referer` headers. Cookies and auth headers never reach Sentry. The visitor's IP address is forwarded from the `cf-connecting-ip`, `x-vercel-forwarded-for`, or `x-forwarded-for` header. +- Tunnel requests don't create server spans. +- The tunnel is only served while the server SDK is enabled. Without a DSN, or with `enabled: false`, requests to the tunnel path get your app's 404 page, and the browser's events are lost. + +## Options + +### `allowedDsns` + +_Type: `string[]`_ + +DSNs to forward besides the server's own. Use this when the browser uses a different DSN than the server. The server's own DSN is always allowed. + +```javascript +Sentry.serveTunnelIntegration({ + allowedDsns: ["___PUBLIC_DSN___"], +}); +``` + +### `path` + +_Type: `string`_ + +A fixed tunnel path instead of the one derived from the DSN. The path is served as written, without the base path. Set the same path in the browser with the object form. A string `tunnel` is sent as `text/plain`, which the CSRF protection in SvelteKit and Astro rejects. + +```javascript {filename:Server} +Sentry.serveTunnelIntegration({ path: "/monitoring" }); +``` + +```javascript {filename:Browser} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: { path: "/monitoring" }, +}); +``` + +### `basePath` + +_Type: `string`_ + +The path prefix your app is served under, for example `/docs`. The SDK reads it from your framework config, so you only need this option when it can't. Set the same value in the browser `tunnel` option. diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index 68134bd8e631c..7cb62e4331b73 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -83,6 +83,8 @@ Environments are case-sensitive. The environment name can't contain newlines, sp + + Sets the URL that will be used to transport captured events. This can be used to work around ad-blockers or to have more granular control over events sent to Sentry. Adding your DSN is still required when using this option so necessary attributes can be set on the generated Sentry data. This option **requires the implementation** of a custom server endpoint. Learn more and find examples in [Dealing with Ad-Blockers](/platforms/javascript/troubleshooting/#dealing-with-ad-blockers). @@ -91,6 +93,27 @@ The endpoint must forward only the request body to Sentry and accept only your o + + + + + + +Where the browser SDK sends captured events instead of the Sentry ingest URL. Use it to work around ad blockers or to control which events reach Sentry. The DSN is still required, so the SDK can set the attributes it needs on your data. + +- A string (URL or relative path) sends events to it as written. This **requires the implementation** of a custom server endpoint. The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). +- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with `serveTunnelIntegration`. Available since version `11.10.0`. +- An object works like `true`, with these options: + - `path`: a fixed tunnel path, used as written without the base path. + - `basePath`: the path prefix your app is served under, for example `/docs`. Most framework SDKs set it for you. + - `trailingSlash`: appends a trailing slash to the tunnel path, for servers that redirect paths without one. + +On the server, `tunnel` only takes a URL. It's where the server SDK sends its own events, and it's independent from `serveTunnelIntegration`. + + + + + diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 1fb9a9adef7e9..c49efbe2070e6 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -223,6 +223,40 @@ You can work around our CDN bundles being blocked by [using our NPM packages](#u + + + + + +The SDK can serve the tunnel for you. Set `tunnel: true` in your browser `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: + +```javascript {tabTitle:Browser} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: true, +}); +``` + +```javascript {tabTitle:Server} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. The SDK reads your app's base path from your framework config. + + + +The managed tunnel is only available for Remix 3. + + + +See `serveTunnelIntegration` for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. + + + + @@ -258,7 +292,7 @@ Your tunnel endpoint must: - Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. - Send the envelope only to the host of that DSN. -On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with versions `10.77.1` (v10) and `11.9.0` (v11), it also rejects requests larger than 20 MiB. +On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with version `11.10.0`, the DSN of the active server SDK is always allowed, so `allowedDsns` is optional. It forwards the user agent, client hint, `Origin`, and `Referer` headers, and the visitor's IP address, but never cookies or auth headers. ```javascript import { handleTunnelRequest } from "@sentry/core"; diff --git a/docs/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute.mdx b/docs/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute.mdx index d3244d9717c84..e27f458929227 100644 --- a/docs/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute.mdx +++ b/docs/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute.mdx @@ -13,7 +13,7 @@ description: "Learn how to manually define a Sentry tunnel route in your TanStac the route file, the DSN allowlist, or can't use the Vite plugin. -The `createSentryTunnelRoute` helper returns a TanStack Start server-route configuration with a `POST` handler that forwards Sentry envelopes to Sentry's ingest servers. Use it inside a file route to expose a same-origin tunnel endpoint. It forwards only the request body to Sentry. +The `createSentryTunnelRoute` helper returns a TanStack Start server-route configuration with a `POST` handler that forwards Sentry envelopes to Sentry's ingest servers. Use it inside a file route to expose a same-origin tunnel endpoint. For a tunnel that needs no route file, use the [`tunnelRoute`](/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart/#tunnel-route) option instead. ## Usage @@ -46,7 +46,7 @@ Sentry.init({ A list of DSN strings that the route is allowed to forward to. The route validates each incoming envelope against this list and rejects any DSN that isn't allowed. -If `allowedDsns` is omitted or empty, the route falls back to the DSN of the active server-side Sentry SDK at runtime. If neither is available, requests to the route return a 500 response. +Since version `11.10.0`, the DSN of the active server-side Sentry SDK is always allowed too. If `allowedDsns` is omitted or empty, the route uses only that DSN. If neither is available, requests to the route return a 500 response. ```typescript {filename:src/routes/monitor.ts} Sentry.createSentryTunnelRoute({ diff --git a/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx b/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx index 5663884faf889..60c363debc735 100644 --- a/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx +++ b/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx @@ -97,13 +97,15 @@ sentryTanstackStart({ -The `tunnelRoute` option registers a same-origin TanStack Start server route that forwards Sentry envelopes to Sentry's ingest servers. It also automatically sets the client `tunnel` option in `Sentry.init()` so browser events go through that route. This helps avoid ad blockers and corporate firewalls that block requests to `*.sentry.io`. It forwards only the request body to Sentry. +The `tunnelRoute` option serves a same-origin tunnel that forwards Sentry envelopes to Sentry's ingest servers. It also automatically sets the client `tunnel` option in `Sentry.init()` so browser events go through it. This helps avoid ad blockers and corporate firewalls that block requests to `*.sentry.io`. + +Since version `11.10.0`, the tunnel answers in the server entry, before TanStack Start's request middleware and routing. It works the same way as `serveTunnelIntegration`, which you can use instead of this option. `tunnelRoute` accepts three shapes: #### `tunnelRoute: true` (recommended) -Generates an opaque, unguessable route path for each dev session and production build. Because the path changes between builds, ad blockers can't reliably target it. +Serves a path derived from the DSN, under your router's base path. It's the same path that `Sentry.init({ tunnel: true })` uses. ```typescript {filename:vite.config.ts} sentryTanstackStart({ @@ -111,9 +113,14 @@ sentryTanstackStart({ }), ``` + + Before version `11.10.0`, `tunnelRoute: true` generated a new random path for + each dev session and production build. + + #### Static path -Pass a string to use a fixed route path. This is easier to reason about, but a known path is easier for ad blockers to add to a list. +Pass a string to use a fixed route path. The path is used as written, without the base path. ```typescript {filename:vite.config.ts} sentryTanstackStart({ @@ -123,7 +130,7 @@ sentryTanstackStart({ #### Object form -Use the object form to control the DSN allowlist or set a static path explicitly: +Use the object form to allow more DSNs or set a static path explicitly: ```typescript {filename:vite.config.ts} sentryTanstackStart({ @@ -134,19 +141,14 @@ sentryTanstackStart({ }), ``` -- **`allowedDsns`** — only envelopes targeting one of these DSNs are forwarded. If omitted or empty, the route falls back to the DSN of the active server-side Sentry SDK at runtime. -- **`path`** — the public route path. If omitted, an opaque path is generated (same behavior as `tunnelRoute: true`). +- **`allowedDsns`**: envelopes for these DSNs are forwarded, in addition to the DSN of the active server-side Sentry SDK. +- **`path`**: the public route path. If omitted, the path is derived from the DSN (same behavior as `tunnelRoute: true`). - If you also pass `tunnel` to `Sentry.init()`, the runtime option wins and the - managed tunnel route is bypassed. The SDK logs a warning when this happens. - - - - When using `tunnelRoute: true` (or the object form without `path`), the - generated path changes for each dev session and each production build. Don't - hard-code it elsewhere in your app or infrastructure. + If you also pass a different `tunnel` to `Sentry.init()`, the runtime option + wins and the managed tunnel route is bypassed. The SDK logs a warning when + this happens. diff --git a/docs/platforms/javascript/guides/tanstackstart-react/manual-setup/index.mdx b/docs/platforms/javascript/guides/tanstackstart-react/manual-setup/index.mdx index a9c893db8c249..b8e980f5bb13b 100644 --- a/docs/platforms/javascript/guides/tanstackstart-react/manual-setup/index.mdx +++ b/docs/platforms/javascript/guides/tanstackstart-react/manual-setup/index.mdx @@ -370,7 +370,7 @@ Ad blockers and corporate firewalls often block requests to `*.sentry.io`, which The `sentryTanstackStart` Vite plugin can register a tunnel route for you and automatically wire up the client `tunnel` option. -Setting `tunnelRoute: true` generates an opaque route for each dev session and production build, making it harder for ad blockers to target. See the [`sentryTanstackStart`](/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart/#tunnel-route) feature page for static paths and the full set of options. +Setting `tunnelRoute: true` serves the tunnel at a path derived from your DSN. See the [`sentryTanstackStart`](/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart/#tunnel-route) feature page for static paths and the full set of options. If you can't use the Vite plugin, or need full control over the route file and DSN allowlist, use [`createSentryTunnelRoute`](/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute/) to define the route yourself. diff --git a/platform-includes/getting-started-complete/javascript.nuxt.mdx b/platform-includes/getting-started-complete/javascript.nuxt.mdx index 8847328ac123f..e3a96e9137b12 100644 --- a/platform-includes/getting-started-complete/javascript.nuxt.mdx +++ b/platform-includes/getting-started-complete/javascript.nuxt.mdx @@ -263,10 +263,7 @@ export default defineNuxtConfig({ ### Avoid Ad Blockers With Tunneling (Optional) - + ### Control the Data You Send to Sentry (Optional) diff --git a/platform-includes/getting-started-tunneling/javascript.astro.mdx b/platform-includes/getting-started-tunneling/javascript.astro.mdx new file mode 100644 index 0000000000000..b99782cc63ad6 --- /dev/null +++ b/platform-includes/getting-started-tunneling/javascript.astro.mdx @@ -0,0 +1,19 @@ +To keep ad blockers from dropping Sentry events, send them through a tunnel on your own origin. The SDK serves the tunnel and forwards the events to Sentry. + +Set `tunnel: true` in your client `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: + +```javascript {filename:sentry.client.config.(js|ts)} {3} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: true, +}); +``` + +```javascript {filename:sentry.server.config.(js|ts)} {3} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. diff --git a/platform-includes/getting-started-tunneling/javascript.nuxt.mdx b/platform-includes/getting-started-tunneling/javascript.nuxt.mdx new file mode 100644 index 0000000000000..ba7feb068a7f0 --- /dev/null +++ b/platform-includes/getting-started-tunneling/javascript.nuxt.mdx @@ -0,0 +1,19 @@ +To keep ad blockers from dropping Sentry events, send them through a tunnel on your own origin. The SDK serves the tunnel and forwards the events to Sentry. + +Set `tunnel: true` in your client `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: + +```javascript {filename:sentry.client.config.ts} {3} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: true, +}); +``` + +```javascript {filename:sentry.server.config.ts} {3} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. diff --git a/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx b/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx index 3b1ef2770c630..db41cd6335b34 100644 --- a/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx +++ b/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx @@ -1,10 +1,19 @@ -You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option inside your `hooks.client.(js|ts)` file's `Sentry.init` to add an API endpoint in your application that forwards Sentry events to Sentry servers. +To keep ad blockers from dropping Sentry events, send them through a tunnel on your own origin. The SDK serves the tunnel and forwards the events to Sentry. -This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. The endpoint must forward only the request body to Sentry and accept only your own DSN. You can find a detailed explanation on how to do this on our [Troubleshooting page](/platforms/javascript/guides/sveltekit/troubleshooting/#using-the-tunnel-option). +Set `tunnel: true` in your client `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: -```javascript {filename:hooks.client.(js|ts)} {3} +```javascript {filename:src/hooks.client.(js|ts)} {3} Sentry.init({ dsn: "___PUBLIC_DSN___", - tunnel: "/tunnel", + tunnel: true, }); ``` + +```javascript {filename:src/instrumentation.server.(js|ts)} {3} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. From 2d33fead1d90ecabfad120a1ab5ec4fb1ead31fe Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Tue, 27 Oct 2026 16:55:30 -0400 Subject: [PATCH 02/13] docs(js): Document serving the managed tunnel on any server Covers the tunnel helpers every server SDK exports and the new handleTunnelRequest signature from getsentry/sentry-javascript#25783. --- .../integrations/servetunnel.mdx | 51 +++++++++++++------ .../common/troubleshooting/index.mdx | 23 +++++---- 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 0d5d3487cb0b5..06610725fcee9 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -1,16 +1,8 @@ --- title: ServeTunnel description: "Serves a tunnel on your server so browser events reach Sentry through your own origin, past ad blockers." -supported: - - javascript.sveltekit - - javascript.nuxt - - javascript.nitro - - javascript.astro - - javascript.react-router - - javascript.tanstackstart-react - - javascript.solidstart - - javascript.remix - - javascript.cloudflare +supportedCategories: + - server --- @@ -39,11 +31,7 @@ Sentry.init({ The browser and the server both derive the tunnel path from the DSN, for example `/qpo967`. You don't need a route file, a build step, or an environment variable. If your app is served under a base path, the SDK adds it on both sides. - - -The tunnel is only served by the SDKs that answer requests from a framework hook: SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3. On other servers, see [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). - - +The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, [serve it yourself](#serving-the-tunnel-yourself). @@ -104,3 +92,36 @@ Sentry.init({ _Type: `string`_ The path prefix your app is served under, for example `/docs`. The SDK reads it from your framework config, so you only need this option when it can't. Set the same value in the browser `tunnel` option. + +## Serving the Tunnel Yourself + +On servers without a framework SDK hook, like Express, Fastify, `node:http`, Bun, or Deno, mount `handleTunnelRequestIfMatched` before your routes and body parsers. It forwards tunnel requests and returns `undefined` for everything else: + +```javascript {tabTitle:Express} +const express = require("express"); +const Sentry = require("@sentry/node"); + +const app = express(); + +app.use( + (req, res, next) => Sentry.handleTunnelRequestIfMatched(req, res) ?? next() +); +``` + +```javascript {tabTitle:Fetch API} +export default { + fetch(request) { + return Sentry.handleTunnelRequestIfMatched(request) ?? handleApp(request); + }, +}; +``` + +To register the tunnel as a route instead, use `getTunnelPath()`, which returns the path the browser derives from the server's DSN, and `handleTunnelRequest`: + +```javascript +app.post(Sentry.getTunnelPath(), (req, res) => + Sentry.handleTunnelRequest(req, res) +); +``` + +Both helpers take a fetch `Request`, or Node's `req` and `res`. Without options, they use the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. `handleTunnelRequestIfMatched` also takes the same options as the integration, and `handleTunnelRequest` takes `allowedDsns`. To check a request without reading its body, use `isTunnelRequest(request)`. diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index c49efbe2070e6..72451544fad24 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -223,7 +223,7 @@ You can work around our CDN bundles being blocked by [using our NPM packages](#u - + @@ -244,13 +244,15 @@ Sentry.init({ }); ``` -The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. The SDK reads your app's base path from your framework config. +The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. - +The SvelteKit, Nuxt, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: -The managed tunnel is only available for Remix 3. - - +```javascript {filename:Server} +app.use( + (req, res, next) => Sentry.handleTunnelRequestIfMatched(req, res) ?? next() +); +``` See `serveTunnelIntegration` for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. @@ -292,19 +294,20 @@ Your tunnel endpoint must: - Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. - Send the envelope only to the host of that DSN. -On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with version `11.10.0`, the DSN of the active server SDK is always allowed, so `allowedDsns` is optional. It forwards the user agent, client hint, `Origin`, and `Referer` headers, and the visitor's IP address, but never cookies or auth headers. +On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with version `11.10.0`, every server SDK exports it, and the DSN of the active server SDK is always allowed, so `allowedDsns` is optional. It forwards the user agent, client hint, `Origin`, and `Referer` headers, and the visitor's IP address, but never cookies or auth headers. ```javascript -import { handleTunnelRequest } from "@sentry/core"; +import * as Sentry from "@sentry/node"; export async function POST(request) { - return handleTunnelRequest({ - request, + return Sentry.handleTunnelRequest(request, { allowedDsns: ["___PUBLIC_DSN___"], }); } ``` +It also takes Node's `req` and `res`, for example in Express: `app.post("/tunnel", (req, res) => Sentry.handleTunnelRequest(req, res))`. Versions before `11.10.0` take the request as an option instead, `handleTunnelRequest({ request, allowedDsns })`. That form still works, but is deprecated. + If you implement the endpoint yourself, here's an example for your server component: ```csharp From 192476d4175d7c49d966ff7b791b0dd98418742d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 12:34:36 -0400 Subject: [PATCH 03/13] docs(js): Align the managed tunnel docs with the 11.10.0 release Hides SolidStart until it serves the managed tunnel, fixes the Cloudflare example, and notes that the manual helpers need serveTunnelIntegration to drop tunnel spans. --- .../configuration/integrations/servetunnel.mdx | 17 ++++++++++++----- .../javascript/common/configuration/options.mdx | 5 +++++ .../javascript/common/troubleshooting/index.mdx | 4 ++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 06610725fcee9..676130496bb7c 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -3,6 +3,8 @@ title: ServeTunnel description: "Serves a tunnel on your server so browser events reach Sentry through your own origin, past ad blockers." supportedCategories: - server +notSupported: + - javascript.solidstart --- @@ -31,19 +33,22 @@ Sentry.init({ The browser and the server both derive the tunnel path from the DSN, for example `/qpo967`. You don't need a route file, a build step, or an environment variable. If your app is served under a base path, the SDK adds it on both sides. -The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, [serve it yourself](#serving-the-tunnel-yourself). +The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, [serve it yourself](#serving-the-tunnel-yourself). On Cloudflare Workers, import the integration from `@sentry/cloudflare` and add it to the options you pass to `withSentry`, `defineCloudflareOptions`, or `initCloudflareSentryHandle`: ```javascript -import { serveTunnelIntegration } from "@sentry/cloudflare"; +import { + defineCloudflareOptions, + serveTunnelIntegration, +} from "@sentry/cloudflare"; -export default { +export default defineCloudflareOptions((env) => ({ dsn: "___PUBLIC_DSN___", integrations: [serveTunnelIntegration()], -}; +})); ``` @@ -124,4 +129,6 @@ app.post(Sentry.getTunnelPath(), (req, res) => ); ``` -Both helpers take a fetch `Request`, or Node's `req` and `res`. Without options, they use the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. `handleTunnelRequestIfMatched` also takes the same options as the integration, and `handleTunnelRequest` takes `allowedDsns`. To check a request without reading its body, use `isTunnelRequest(request)`. +Both helpers take a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). Without options, they use the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. `handleTunnelRequestIfMatched` also takes the same options as the integration, and `handleTunnelRequest` takes `allowedDsns`. To check a request without reading its body, use `isTunnelRequest(request)`. + +The helpers work without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index 7cb62e4331b73..9ac84aed548fe 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -102,6 +102,9 @@ The endpoint must forward only the request body to Sentry and accept only your o Where the browser SDK sends captured events instead of the Sentry ingest URL. Use it to work around ad blockers or to control which events reach Sentry. The DSN is still required, so the SDK can set the attributes it needs on your data. - A string (URL or relative path) sends events to it as written. This **requires the implementation** of a custom server endpoint. The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). + + + - `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with `serveTunnelIntegration`. Available since version `11.10.0`. - An object works like `true`, with these options: - `path`: a fixed tunnel path, used as written without the base path. @@ -110,6 +113,8 @@ Where the browser SDK sends captured events instead of the Sentry ingest URL. Us On the server, `tunnel` only takes a URL. It's where the server SDK sends its own events, and it's independent from `serveTunnelIntegration`. + + diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 72451544fad24..c2bf62f58796a 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -223,7 +223,7 @@ You can work around our CDN bundles being blocked by [using our NPM packages](#u - + @@ -246,7 +246,7 @@ Sentry.init({ The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. -The SvelteKit, Nuxt, Astro, React Router (framework mode), TanStack Start, SolidStart, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: +The SvelteKit, Nuxt, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: ```javascript {filename:Server} app.use( From 29024301823250ac6033faca0df389ebf9eec0f7 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 12:36:20 -0400 Subject: [PATCH 04/13] docs(js): Hide the managed tunnel docs from Next.js for now --- .../common/configuration/integrations/servetunnel.mdx | 1 + docs/platforms/javascript/common/configuration/options.mdx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 676130496bb7c..4ecdb32c7aa67 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -4,6 +4,7 @@ description: "Serves a tunnel on your server so browser events reach Sentry thro supportedCategories: - server notSupported: + - javascript.nextjs - javascript.solidstart --- diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index 9ac84aed548fe..b4fefadfe565c 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -103,7 +103,7 @@ Where the browser SDK sends captured events instead of the Sentry ingest URL. Us - A string (URL or relative path) sends events to it as written. This **requires the implementation** of a custom server endpoint. The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). - + - `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with `serveTunnelIntegration`. Available since version `11.10.0`. - An object works like `true`, with these options: From 40a501ccee44abfaf1cbcd42b1b7ac4789c3802d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 12:38:17 -0400 Subject: [PATCH 05/13] docs(js): Align the tunnel endpoint rules with handleTunnelRequest --- docs/platforms/javascript/common/troubleshooting/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index c2bf62f58796a..d8220f94c01c6 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -290,7 +290,7 @@ Once configured, all events will be sent to the `/tunnel` endpoint. This solutio Your tunnel endpoint must: -- Forward only the request body to Sentry, without the request headers. +- Forward the request body to Sentry, without cookies or auth headers. - Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. - Send the envelope only to the host of that DSN. From 77ff18e7741560ce60f70a33dea976cd47cf92e4 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 12:40:23 -0400 Subject: [PATCH 06/13] docs(js): Keep the handleTunnelRequest paragraph, with the non-deprecated signature --- .../platforms/javascript/common/troubleshooting/index.mdx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index d8220f94c01c6..fafcb10a38d65 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -294,20 +294,18 @@ Your tunnel endpoint must: - Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. - Send the envelope only to the host of that DSN. -On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with version `11.10.0`, every server SDK exports it, and the DSN of the active server SDK is always allowed, so `allowedDsns` is optional. It forwards the user agent, client hint, `Origin`, and `Referer` headers, and the visitor's IP address, but never cookies or auth headers. +On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with versions `10.77.1` (v10) and `11.9.0` (v11), it also rejects requests larger than 20 MiB. ```javascript -import * as Sentry from "@sentry/node"; +import { handleTunnelRequest } from "@sentry/core"; export async function POST(request) { - return Sentry.handleTunnelRequest(request, { + return handleTunnelRequest(request, { allowedDsns: ["___PUBLIC_DSN___"], }); } ``` -It also takes Node's `req` and `res`, for example in Express: `app.post("/tunnel", (req, res) => Sentry.handleTunnelRequest(req, res))`. Versions before `11.10.0` take the request as an option instead, `handleTunnelRequest({ request, allowedDsns })`. That form still works, but is deprecated. - If you implement the endpoint yourself, here's an example for your server component: ```csharp From 30ea67f568e13892c69baabd70b3c9df0b7e9c49 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 14:10:21 -0400 Subject: [PATCH 07/13] docs(js): Link browser-only platforms to the Node.js serveTunnel page The serveTunnel page only exists on server platforms, so the links 404'd on browser-only ones. --- .../javascript/common/configuration/options.mdx | 11 +++++++++++ .../javascript/common/troubleshooting/index.mdx | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index b4fefadfe565c..3fd0ee56a2aa5 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -105,7 +105,18 @@ Where the browser SDK sends captured events instead of the Sentry ingest URL. Us + + - `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with `serveTunnelIntegration`. Available since version `11.10.0`. + + + + + +- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/). Available since version `11.10.0`. + + + - An object works like `true`, with these options: - `path`: a fixed tunnel path, used as written without the base path. - `basePath`: the path prefix your app is served under, for example `/docs`. Most framework SDKs set it for you. diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index fafcb10a38d65..19ef920041b6d 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -254,8 +254,18 @@ app.use( ); ``` + + See `serveTunnelIntegration` for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. + + + + +See [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/) for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. + + + From 6b56580c224c62c4b371da2417ebb74f79ff410d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 14:23:26 -0400 Subject: [PATCH 08/13] docs(js): Document only the middleware for serving the tunnel yourself --- .../configuration/integrations/servetunnel.mdx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 4ecdb32c7aa67..dd7e3823b62b6 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -122,14 +122,6 @@ export default { }; ``` -To register the tunnel as a route instead, use `getTunnelPath()`, which returns the path the browser derives from the server's DSN, and `handleTunnelRequest`: +`handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). Without options, it uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. It also takes the same options as the integration. To check a request without reading its body, use `isTunnelRequest(request)`. -```javascript -app.post(Sentry.getTunnelPath(), (req, res) => - Sentry.handleTunnelRequest(req, res) -); -``` - -Both helpers take a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). Without options, they use the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. `handleTunnelRequestIfMatched` also takes the same options as the integration, and `handleTunnelRequest` takes `allowedDsns`. To check a request without reading its body, use `isTunnelRequest(request)`. - -The helpers work without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. +The middleware works without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. From 26e087e894f25bc66b8e7a6c5351063caf937999 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 14:24:50 -0400 Subject: [PATCH 09/13] docs(js): Document handleTunnelRequest for a fixed tunnel path --- .../configuration/integrations/servetunnel.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index dd7e3823b62b6..9f40eac21fafa 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -124,4 +124,19 @@ export default { `handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). Without options, it uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. It also takes the same options as the integration. To check a request without reading its body, use `isTunnelRequest(request)`. -The middleware works without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. +If you'd rather use a fixed path, register it as a route with `handleTunnelRequest`, and set the same path in the browser: + +```javascript {filename:Server} +app.post("/monitoring", (req, res) => Sentry.handleTunnelRequest(req, res)); +``` + +```javascript {filename:Browser} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: { path: "/monitoring" }, +}); +``` + +`handleTunnelRequest` also takes a fetch `Request`, and an `allowedDsns` option for DSNs besides the server's own. + +Both work without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. With a fixed path, pass it as the integration's `path` too: `serveTunnelIntegration({ path: "/monitoring" })`. From 54789bba81ca14062c8ffb4d92ee36080b656929 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Wed, 28 Oct 2026 14:59:19 -0400 Subject: [PATCH 10/13] docs(js): Apply the docs style guide to the managed tunnel docs --- .../integrations/servetunnel.mdx | 40 ++++++++++--------- .../common/troubleshooting/index.mdx | 2 +- .../features/sentryTanstackStart.mdx | 2 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 9f40eac21fafa..21f69186a0c27 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -14,18 +14,16 @@ _Import name: `Sentry.serveTunnelIntegration`_ Ad blockers often drop requests to `*.ingest.sentry.io`. This integration serves a tunnel endpoint from your app's server, so the browser SDK can send its events to your own origin instead. The server forwards them to Sentry. -Set it up on both sides. Add the integration to your server `Sentry.init`: +Set it up on both sides. Add the integration to your server `Sentry.init`, and set `tunnel: true` in your browser `Sentry.init`: -```javascript {filename:Server} +```javascript {tabTitle:Server} Sentry.init({ dsn: "___PUBLIC_DSN___", integrations: [Sentry.serveTunnelIntegration()], }); ``` -And set `tunnel: true` in your browser `Sentry.init`: - -```javascript {filename:Browser} +```javascript {tabTitle:Browser} Sentry.init({ dsn: "___PUBLIC_DSN___", tunnel: true, @@ -64,6 +62,8 @@ export default defineCloudflareOptions((env) => ({ ## Options +Pass these options to `serveTunnelIntegration`. Most apps don't need any of them. + ### `allowedDsns` _Type: `string[]`_ @@ -80,13 +80,15 @@ Sentry.serveTunnelIntegration({ _Type: `string`_ -A fixed tunnel path instead of the one derived from the DSN. The path is served as written, without the base path. Set the same path in the browser with the object form. A string `tunnel` is sent as `text/plain`, which the CSRF protection in SvelteKit and Astro rejects. +A fixed tunnel path instead of the one derived from the DSN. The SDK serves it as written, without the base path. + +Set the same path in the browser with the object form. Don't pass it as a string: the browser SDK then sends `text/plain`, which the CSRF protection in SvelteKit and Astro rejects. -```javascript {filename:Server} +```javascript {tabTitle:Server} Sentry.serveTunnelIntegration({ path: "/monitoring" }); ``` -```javascript {filename:Browser} +```javascript {tabTitle:Browser} Sentry.init({ dsn: "___PUBLIC_DSN___", tunnel: { path: "/monitoring" }, @@ -117,26 +119,28 @@ app.use( ```javascript {tabTitle:Fetch API} export default { fetch(request) { - return Sentry.handleTunnelRequestIfMatched(request) ?? handleApp(request); + return ( + Sentry.handleTunnelRequestIfMatched(request) ?? new Response("Hello") + ); }, }; ``` -`handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). Without options, it uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. It also takes the same options as the integration. To check a request without reading its body, use `isTunnelRequest(request)`. +`handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). It takes the same options as the integration. -If you'd rather use a fixed path, register it as a route with `handleTunnelRequest`, and set the same path in the browser: +Without options, it uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. To check a request without reading its body, use `isTunnelRequest(request)`. -```javascript {filename:Server} -app.post("/monitoring", (req, res) => Sentry.handleTunnelRequest(req, res)); -``` +If you'd rather use a fixed path, register it as a route with `handleTunnelRequest`. Pass the same path to the integration, so tunnel requests don't create server spans: -```javascript {filename:Browser} +```javascript Sentry.init({ dsn: "___PUBLIC_DSN___", - tunnel: { path: "/monitoring" }, + integrations: [Sentry.serveTunnelIntegration({ path: "/monitoring" })], }); + +app.post("/monitoring", (req, res) => Sentry.handleTunnelRequest(req, res)); ``` -`handleTunnelRequest` also takes a fetch `Request`, and an `allowedDsns` option for DSNs besides the server's own. +Set the same path in the browser, as shown in [`path`](#path). `handleTunnelRequest` also takes a fetch `Request`, and an `allowedDsns` option for DSNs besides the server's own. -Both work without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. With a fixed path, pass it as the integration's `path` too: `serveTunnelIntegration({ path: "/monitoring" })`. +Both helpers work without `serveTunnelIntegration`. Add it anyway, so tunnel requests don't create server spans. diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 19ef920041b6d..27c2c6c858ca4 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -246,7 +246,7 @@ Sentry.init({ The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. -The SvelteKit, Nuxt, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: +The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: ```javascript {filename:Server} app.use( diff --git a/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx b/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx index 60c363debc735..717b5fbf6d040 100644 --- a/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx +++ b/docs/platforms/javascript/guides/tanstackstart-react/features/sentryTanstackStart.mdx @@ -120,7 +120,7 @@ sentryTanstackStart({ #### Static path -Pass a string to use a fixed route path. The path is used as written, without the base path. +Pass a string to use a fixed route path. The SDK serves it as written, without the base path. ```typescript {filename:vite.config.ts} sentryTanstackStart({ From 2a75393801fdab7b4c907e2e6169536a2e7adc3d Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Thu, 29 Oct 2026 09:59:30 -0400 Subject: [PATCH 11/13] docs(js): Clarify that serveTunnelIntegration needs a request hook to serve the tunnel On servers without a framework SDK hook, including Cloudflare Workers, the integration only configures the tunnel. --- .../integrations/servetunnel.mdx | 33 +++++++++++-------- .../common/configuration/options.mdx | 4 +-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 21f69186a0c27..02e875d4ecbcf 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -12,7 +12,7 @@ notSupported: _Import name: `Sentry.serveTunnelIntegration`_ -Ad blockers often drop requests to `*.ingest.sentry.io`. This integration serves a tunnel endpoint from your app's server, so the browser SDK can send its events to your own origin instead. The server forwards them to Sentry. +Ad blockers often drop requests to `*.ingest.sentry.io`. With a tunnel on your own origin, the browser SDK sends its events to your server instead, and your server forwards them to Sentry. This integration configures that tunnel on the server. Set it up on both sides. Add the integration to your server `Sentry.init`, and set `tunnel: true` in your browser `Sentry.init`: @@ -32,29 +32,36 @@ Sentry.init({ The browser and the server both derive the tunnel path from the DSN, for example `/qpo967`. You don't need a route file, a build step, or an environment variable. If your app is served under a base path, the SDK adds it on both sides. -The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, [serve it yourself](#serving-the-tunnel-yourself). +The integration doesn't handle requests by itself. The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, like Express, Fastify, Bun, Deno, or Cloudflare Workers, [serve it yourself](#serving-the-tunnel-yourself). -On Cloudflare Workers, import the integration from `@sentry/cloudflare` and add it to the options you pass to `withSentry`, `defineCloudflareOptions`, or `initCloudflareSentryHandle`: +On Cloudflare Workers, add the integration to your Sentry options, and call `handleTunnelRequestIfMatched` at the start of your `fetch` handler: ```javascript -import { - defineCloudflareOptions, - serveTunnelIntegration, -} from "@sentry/cloudflare"; - -export default defineCloudflareOptions((env) => ({ - dsn: "___PUBLIC_DSN___", - integrations: [serveTunnelIntegration()], -})); +import * as Sentry from "@sentry/cloudflare"; + +export default Sentry.withSentry( + (env) => ({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], + }), + { + async fetch(request, env, ctx) { + return ( + (await Sentry.handleTunnelRequestIfMatched(request)) ?? + new Response("Hello") + ); + }, + } +); ``` ## How It Works -- The tunnel answers before your app's own middleware, so auth or CSRF middleware doesn't block it. +- Framework SDKs answer tunnel requests before your app's own middleware, so auth or CSRF middleware doesn't block them. When you serve the tunnel yourself, mount it before that middleware too. - It only forwards envelopes whose DSN is allowed. By default, that's the server's own DSN. Other envelopes get a `403`, so the tunnel can't be used as an open proxy. - It forwards only the user agent, client hint, `Origin`, and `Referer` headers. Cookies and auth headers never reach Sentry. The visitor's IP address is forwarded from the `cf-connecting-ip`, `x-vercel-forwarded-for`, or `x-forwarded-for` header. - Tunnel requests don't create server spans. diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index 3fd0ee56a2aa5..edb06ca709c23 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -107,13 +107,13 @@ Where the browser SDK sends captured events instead of the Sentry ingest URL. Us -- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with `serveTunnelIntegration`. Available since version `11.10.0`. +- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server needs to serve it, as described in `serveTunnelIntegration`. Available since version `11.10.0`. -- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server serves it with [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/). Available since version `11.10.0`. +- `true` sends events to the managed tunnel, a path on your own origin derived from the DSN. Your server needs to serve it, as described in [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/). Available since version `11.10.0`. From d37473ef6a7942e5b5d8abb48c3d9b52c4afcc85 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Thu, 29 Oct 2026 10:03:45 -0400 Subject: [PATCH 12/13] docs(js): Show per-platform tunnel serving notes instead of listing every framework --- .../integrations/servetunnel.mdx | 26 +++++++++++++++++-- .../common/troubleshooting/index.mdx | 26 +++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index 02e875d4ecbcf..fcb2b2f80e44a 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -32,7 +32,29 @@ Sentry.init({ The browser and the server both derive the tunnel path from the DSN, for example `/qpo967`. You don't need a route file, a build step, or an environment variable. If your app is served under a base path, the SDK adds it on both sides. -The integration doesn't handle requests by itself. The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel from their request hooks. On other servers, like Express, Fastify, Bun, Deno, or Cloudflare Workers, [serve it yourself](#serving-the-tunnel-yourself). + + +The SDK serves the tunnel from its request hooks, so this is all the setup you need. + + + + + +In framework mode, the SDK serves the tunnel from its request hooks, so this is all the setup you need. + + + + + +On Remix 3, the SDK serves the tunnel from its request hooks, so this is all the setup you need. On earlier versions, [serve it yourself](#serving-the-tunnel-yourself). + + + + + +The integration doesn't handle requests by itself, so you need to [serve the tunnel yourself](#serving-the-tunnel-yourself). + + @@ -110,7 +132,7 @@ The path prefix your app is served under, for example `/docs`. The SDK reads it ## Serving the Tunnel Yourself -On servers without a framework SDK hook, like Express, Fastify, `node:http`, Bun, or Deno, mount `handleTunnelRequestIfMatched` before your routes and body parsers. It forwards tunnel requests and returns `undefined` for everything else: +On servers without a framework SDK hook, mount `handleTunnelRequestIfMatched` before your routes and body parsers. It forwards tunnel requests and returns `undefined` for everything else: ```javascript {tabTitle:Express} const express = require("express"); diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 27c2c6c858ca4..543869c260ed5 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -228,7 +228,7 @@ You can work around our CDN bundles being blocked by [using our NPM packages](#u -The SDK can serve the tunnel for you. Set `tunnel: true` in your browser `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: +Set `tunnel: true` in your browser `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: ```javascript {tabTitle:Browser} Sentry.init({ @@ -246,7 +246,27 @@ Sentry.init({ The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. -The SvelteKit, Nuxt, Nitro, Astro, React Router (framework mode), TanStack Start, and Remix 3 SDKs serve the tunnel for you and read your app's base path from your framework config. On other servers, like Express, mount `handleTunnelRequestIfMatched` before your routes and body parsers: + + +The SDK serves the tunnel for you and reads your app's base path from your framework config. + + + + + +In framework mode, the SDK serves the tunnel for you and reads your app's base path from your framework config. In other modes, see Serving the Tunnel Yourself. + + + + + +On Remix 3, the SDK serves the tunnel for you and reads your app's base path from your framework config. On earlier versions, see Serving the Tunnel Yourself. + + + + + +The integration doesn't handle requests by itself. Mount `handleTunnelRequestIfMatched` on your server, before your routes and body parsers: ```javascript {filename:Server} app.use( @@ -254,6 +274,8 @@ app.use( ); ``` + + See `serveTunnelIntegration` for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. From 03766f6b51a1380315f25bbda5dddcd74f620826 Mon Sep 17 00:00:00 2001 From: Abdelrahman Awad Date: Fri, 30 Oct 2026 10:54:54 -0400 Subject: [PATCH 13/13] docs(js): Move tunneling docs to their own configuration page Add a Tunneling page under Extended Configuration and move the tunnel content there from Troubleshooting, which now only links to it. Point existing tunneling links at the new page. Also address review feedback on the managed tunnel docs: list serveTunnelIntegration in the server integration tables, add a Fastify example, and tighten the tunnel option wording. --- .../android/troubleshooting/index.mdx | 2 +- .../dotnet/guides/aspnetcore/index.mdx | 2 +- .../img/tunnel.png | Bin .../integrations/servetunnel.mdx | 34 +- .../common/configuration/options.mdx | 52 +++- .../common/configuration/tunneling.mdx | 293 ++++++++++++++++++ .../common/troubleshooting/index.mdx | 267 +--------------- .../javascript/guides/astro/index.mdx | 2 +- .../guides/cordova/configuration/options.mdx | 4 +- .../javascript/guides/ember/index.mdx | 2 +- .../javascript/guides/gatsby/index.mdx | 2 +- .../nextjs/configuration/build/index.mdx | 2 +- .../javascript/guides/nextjs/index.mdx | 2 +- .../javascript/guides/react-router/index.mdx | 2 +- .../guides/react-router/manual-setup.mdx | 2 +- .../javascript/guides/react/index.mdx | 2 +- .../javascript/guides/solid/index.mdx | 2 +- .../javascript/guides/solidstart/index.mdx | 2 +- .../javascript/guides/svelte/index.mdx | 2 +- .../platforms/javascript/guides/vue/index.mdx | 2 +- docs/product/explore/dropped-data.mdx | 2 +- .../integrations/javascript.astro.mdx | 61 ++-- .../integrations/javascript.aws-lambda.mdx | 5 +- .../integrations/javascript.bun.mdx | 13 +- .../integrations/javascript.cloudflare.mdx | 5 +- .../integrations/javascript.deno.mdx | 45 +-- .../integrations/javascript.fastify.mdx | 5 +- .../integrations/javascript.gcp-functions.mdx | 5 +- .../integrations/javascript.hapi.mdx | 5 +- .../integrations/javascript.nestjs.mdx | 5 +- .../integrations/javascript.node.mdx | 5 +- .../integrations/javascript.nuxt.mdx | 61 ++-- .../integrations/javascript.remix.mdx | 61 ++-- .../integrations/javascript.sveltekit.mdx | 59 ++-- .../getting-started-complete/javascript.mdx | 2 +- .../javascript.astro.mdx | 2 +- .../getting-started-tunneling/javascript.mdx | 2 +- .../javascript.nuxt.mdx | 2 +- .../javascript.sveltekit.mdx | 2 +- 39 files changed, 555 insertions(+), 470 deletions(-) rename docs/platforms/javascript/common/{troubleshooting => configuration}/img/tunnel.png (100%) create mode 100644 docs/platforms/javascript/common/configuration/tunneling.mdx diff --git a/docs/platforms/android/troubleshooting/index.mdx b/docs/platforms/android/troubleshooting/index.mdx index f3a6786fae980..b9fa8464e5d99 100644 --- a/docs/platforms/android/troubleshooting/index.mdx +++ b/docs/platforms/android/troubleshooting/index.mdx @@ -199,7 +199,7 @@ If you set up the Sentry SDK and it's not sending any data to Sentry: - Check that you have configured a DSN and that you are passing it to the `dsn` option in `SentryAndroid.init()` or `AndroidManifest`. - When a crash happens or the app closes, the system allows only a short time to handle it before terminating the process. The SDK might not have enough time to send the event, spans, profile, or replay data. In these cases, simply relaunching the app should allow the SDK to send the remaining data. -- An ad-blocker (e.g. [DuckDuckGo's App Tracking Protection](https://duckduckgo.com/duckduckgo-help-pages/p-app-tracking-protection/what-is-app-tracking-protection)) or network restrictions might be preventing the SDK from reaching Sentry's servers. As a workaround, you can use [tunneling](/platforms/javascript/troubleshooting/#using-the-tunnel-option) to proxy Sentry events through your own server. Then you can add the [proxy option](/platforms/android/configuration/options/#proxy) to your SDK configuration. +- An ad-blocker (e.g. [DuckDuckGo's App Tracking Protection](https://duckduckgo.com/duckduckgo-help-pages/p-app-tracking-protection/what-is-app-tracking-protection)) or network restrictions might be preventing the SDK from reaching Sentry's servers. As a workaround, you can use [tunneling](/platforms/javascript/configuration/tunneling/) to proxy Sentry events through your own server. Then you can add the [proxy option](/platforms/android/configuration/options/#proxy) to your SDK configuration. - Set `debug: true` in the `SentryAndroid.init()` or the manifest options and observe your Logcat output when you start your application. The SDK may tell you why it is not sending any data. - Check the [Stats](https://sentry.io/orgredirect/organizations/:orgslug/stats/) and [Subscription](https://sentry.io/orgredirect/organizations/:orgslug/settings/billing/overview/) pages in Sentry. You may be out of quota. diff --git a/docs/platforms/dotnet/guides/aspnetcore/index.mdx b/docs/platforms/dotnet/guides/aspnetcore/index.mdx index 4b33240722ece..6b9e9219f490c 100644 --- a/docs/platforms/dotnet/guides/aspnetcore/index.mdx +++ b/docs/platforms/dotnet/guides/aspnetcore/index.mdx @@ -260,7 +260,7 @@ Opt-in to capture values from [System.Diagnostic.Activity](https://github.com/do ### Tunnel -If events are being logged to Sentry from the client-side, then you should use a [tunnel](/platforms/javascript/troubleshooting/#using-the-tunnel-option). +If events are being logged to Sentry from the client-side, then you should use a [tunnel](/platforms/javascript/configuration/tunneling/). A tunnel is an HTTP endpoint that acts as a proxy between Sentry and your application. Because you control this server, there is no risk of any requests sent to it being blocked. diff --git a/docs/platforms/javascript/common/troubleshooting/img/tunnel.png b/docs/platforms/javascript/common/configuration/img/tunnel.png similarity index 100% rename from docs/platforms/javascript/common/troubleshooting/img/tunnel.png rename to docs/platforms/javascript/common/configuration/img/tunnel.png diff --git a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx index fcb2b2f80e44a..789d9c3ff1a14 100644 --- a/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx @@ -1,6 +1,6 @@ --- title: ServeTunnel -description: "Serves a tunnel on your server so browser events reach Sentry through your own origin, past ad blockers." +description: "Serves a tunnel on your server so Sentry browser SDK events reach Sentry through your own origin, past ad blockers." supportedCategories: - server notSupported: @@ -14,6 +14,8 @@ _Import name: `Sentry.serveTunnelIntegration`_ Ad blockers often drop requests to `*.ingest.sentry.io`. With a tunnel on your own origin, the browser SDK sends its events to your server instead, and your server forwards them to Sentry. This integration configures that tunnel on the server. +For an overview of tunneling, including how to set up your own tunnel endpoint, see Tunneling. + Set it up on both sides. Add the integration to your server `Sentry.init`, and set `tunnel: true` in your browser `Sentry.init`: ```javascript {tabTitle:Server} @@ -46,13 +48,13 @@ In framework mode, the SDK serves the tunnel from its request hooks, so this is -On Remix 3, the SDK serves the tunnel from its request hooks, so this is all the setup you need. On earlier versions, [serve it yourself](#serving-the-tunnel-yourself). +On Remix 3, the SDK serves the tunnel from its request hooks, so this is all the setup you need. On earlier versions, you also need to [mount the tunnel handler](#mounting-the-tunnel-handler). -The integration doesn't handle requests by itself, so you need to [serve the tunnel yourself](#serving-the-tunnel-yourself). +The integration doesn't handle requests by itself, so you also need to [mount the tunnel handler](#mounting-the-tunnel-handler). @@ -83,7 +85,7 @@ export default Sentry.withSentry( ## How It Works -- Framework SDKs answer tunnel requests before your app's own middleware, so auth or CSRF middleware doesn't block them. When you serve the tunnel yourself, mount it before that middleware too. +- Framework SDKs answer tunnel requests before your app's own middleware, so auth or CSRF middleware doesn't block them. When you mount the tunnel handler yourself, put it before that middleware too. - It only forwards envelopes whose DSN is allowed. By default, that's the server's own DSN. Other envelopes get a `403`, so the tunnel can't be used as an open proxy. - It forwards only the user agent, client hint, `Origin`, and `Referer` headers. Cookies and auth headers never reach Sentry. The visitor's IP address is forwarded from the `cf-connecting-ip`, `x-vercel-forwarded-for`, or `x-forwarded-for` header. - Tunnel requests don't create server spans. @@ -130,7 +132,7 @@ _Type: `string`_ The path prefix your app is served under, for example `/docs`. The SDK reads it from your framework config, so you only need this option when it can't. Set the same value in the browser `tunnel` option. -## Serving the Tunnel Yourself +## Mounting the Tunnel Handler On servers without a framework SDK hook, mount `handleTunnelRequestIfMatched` before your routes and body parsers. It forwards tunnel requests and returns `undefined` for everything else: @@ -145,6 +147,24 @@ app.use( ); ``` +```javascript {tabTitle:Fastify} +const Fastify = require("fastify"); +const Sentry = require("@sentry/node"); + +const app = Fastify(); + +app.addHook("onRequest", async (request, reply) => { + const tunnelResponse = Sentry.handleTunnelRequestIfMatched( + request.raw, + reply.raw + ); + if (tunnelResponse) { + await tunnelResponse; + return reply; + } +}); +``` + ```javascript {tabTitle:Fetch API} export default { fetch(request) { @@ -155,9 +175,7 @@ export default { }; ``` -`handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res` (in Fastify, `request.raw` and `reply.raw`). It takes the same options as the integration. - -Without options, it uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. To check a request without reading its body, use `isTunnelRequest(request)`. +`handleTunnelRequestIfMatched` takes a fetch `Request`, or Node's `req` and `res`, and the same options as the integration. Without options, `handleTunnelRequestIfMatched` uses the options of `serveTunnelIntegration`, or the server's own DSN if the integration isn't set up. To check a request without reading its body, use `isTunnelRequest(request)`. If you'd rather use a fixed path, register it as a route with `handleTunnelRequest`. Pass the same path to the integration, so tunnel requests don't create server spans: diff --git a/docs/platforms/javascript/common/configuration/options.mdx b/docs/platforms/javascript/common/configuration/options.mdx index edb06ca709c23..1cf7f9139e533 100644 --- a/docs/platforms/javascript/common/configuration/options.mdx +++ b/docs/platforms/javascript/common/configuration/options.mdx @@ -87,9 +87,9 @@ Environments are case-sensitive. The environment name can't contain newlines, sp -Sets the URL that will be used to transport captured events. This can be used to work around ad-blockers or to have more granular control over events sent to Sentry. Adding your DSN is still required when using this option so necessary attributes can be set on the generated Sentry data. This option **requires the implementation** of a custom server endpoint. Learn more and find examples in [Dealing with Ad-Blockers](/platforms/javascript/troubleshooting/#dealing-with-ad-blockers). +Sets the URL that will be used to transport captured events. This can be used to work around ad-blockers or to have more granular control over events sent to Sentry. Adding your DSN is still required when using this option so necessary attributes can be set on the generated Sentry data. This option **requires the implementation** of a custom server endpoint. Learn more and find examples in Tunneling. -The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). +The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in Setting Up Your Own Tunnel. @@ -99,9 +99,11 @@ The endpoint must forward only the request body to Sentry and accept only your o -Where the browser SDK sends captured events instead of the Sentry ingest URL. Use it to work around ad blockers or to control which events reach Sentry. The DSN is still required, so the SDK can set the attributes it needs on your data. +Where the browser SDK sends captured events instead of the Sentry ingest URL. Use it to work around ad blockers or to control which events reach Sentry. The DSN is still required, so the SDK can initialize correctly and forward the Sentry ingest URL to the tunnel. -- A string (URL or relative path) sends events to it as written. This **requires the implementation** of a custom server endpoint. The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). +The `tunnel` option can be set to the following values: + +- A string (URL or relative path) sends events to it as written. This **requires the implementation** of a custom server endpoint. The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in Setting Up Your Own Tunnel. @@ -147,7 +149,7 @@ Set to `false` to opt out, for example, when using a custom `tunnel` or when run Controls which categories of data the SDK collects automatically. All fields are optional. - By default the SDK collects rich debugging context (including user identity, request/response bodies, and generative AI content) and scrubs values whose keys match the built-in sensitive denylist (`auth`, `token`, `password`, and similar). +By default the SDK collects rich debugging context (including user identity, request/response bodies, and generative AI content) and scrubs values whose keys match the built-in sensitive denylist (`auth`, `token`, `password`, and similar). @@ -338,21 +340,35 @@ The callback gets a second argument (called a "hint") which contains the origina - The JavaScript SDK uses a transport to send events to Sentry. - Transports will drop an event if it fails to send due to a lack of connection. + The JavaScript SDK uses a transport to send events to Sentry. Transports will + drop an event if it fails to send due to a lack of connection. In the browser, a `fetch`-based transport is used by default. - - - On the server, a `https`-based transport is used by default. - + + + On the server, a `https`-based transport is used by default. + - + A `fetch`-based transport is used by default. @@ -590,7 +606,8 @@ The `samplingContext` object passed to the function has the following properties - `name`: The name of the span as it was started. - `attributes`: The initial attributes of the span. - - `location`: The current page or worker URL, if available. Provided by the BrowserTracing integration. + - `location`: The current page or worker URL, if available. Provided by the + BrowserTracing integration. - `normalizedRequest`: Request information of the currently active HTTP @@ -644,7 +661,7 @@ The SDK skips storage operation spans for Durable Object keys whose names start Controls which bindings on `env` receive tracing data over [RPC calls](https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/rpc/) to Durable Objects and other Workers. RPC has no headers, so the SDK appends the trace context as a trailing argument that an instrumented receiver strips again before your method runs. -String entries must match a binding name exactly, so `"DB"` matches `"DB"` but not `"MY_DB"`. Use a regular expression for pattern matching. +String entries must match a binding name exactly, so `"DB"` matches `"DB"` but not `"MY_DB"`. Use a regular expression for pattern matching. This option controls outgoing RPC trace propagation, which is disabled by default. Add bindings to enable it for those receivers. Sentry-instrumented receivers automatically continue incoming traces without configuring this option. @@ -899,7 +916,8 @@ Controls whether the SDK installs runtime hooks that instrument supported depend - On SDK versions below `10.71.0`, logs are opt-in. Set `enableLogs: true` in your `Sentry.init` to send them. + On SDK versions below `10.71.0`, logs are opt-in. Set `enableLogs: true` in + your `Sentry.init` to send them. @@ -911,8 +929,8 @@ This function is called with a log object, and can return a modified log object, ## Metrics Options - **Note:** For Electron, metric options apply to the process where these options - are set. + **Note:** For Electron, metric options apply to the process where these + options are set. diff --git a/docs/platforms/javascript/common/configuration/tunneling.mdx b/docs/platforms/javascript/common/configuration/tunneling.mdx new file mode 100644 index 0000000000000..4843d66e41f4e --- /dev/null +++ b/docs/platforms/javascript/common/configuration/tunneling.mdx @@ -0,0 +1,293 @@ +--- +title: Tunneling +sidebar_order: 35 +description: "Send browser SDK events to Sentry through your own server, so ad blockers don't drop them." +supportedCategories: + - browser + - server +--- + +Ad blockers often block requests to Sentry's ingest endpoints, so errors, sessions, and performance data never reach Sentry. A tunnel is an endpoint on your own origin that forwards these events to Sentry. Ad blockers don't treat requests to your own origin as third-party requests, so they let them through. + +![Tunnel Flow](./img/tunnel.png) + +## Choosing an Approach + + + +- **`tunnelRoute` (recommended):** The Next.js SDK creates the tunnel route for you. See `tunnelRoute`. +- **Your own tunnel:** Point the `tunnel` option at an endpoint you write. See [Setting Up Your Own Tunnel](#setting-up-your-own-tunnel). + + + + + +Point the `tunnel` option at an endpoint you write. See [Setting Up Your Own Tunnel](#setting-up-your-own-tunnel). + + + + + +- **Managed tunnel (recommended):** The SDK picks the tunnel path and your server SDK forwards the events. See [Using the Managed Tunnel](#using-the-managed-tunnel). +- **Your own tunnel:** Point the `tunnel` option at an endpoint you write. Use this on SDK versions before `11.10.0`, or when your server doesn't run a Sentry JavaScript SDK. See [Setting Up Your Own Tunnel](#setting-up-your-own-tunnel). + +## Using the Managed Tunnel + + + +Set `tunnel: true` in your browser `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: + +```javascript {tabTitle:Browser} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: true, +}); +``` + +```javascript {tabTitle:Server} +Sentry.init({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], +}); +``` + +The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. + + + +The SDK serves the tunnel for you, so this is all the setup you need. + + + + + +In framework mode, the SDK serves the tunnel for you. In other modes, you also need to mount the tunnel handler. + + + + + +On Remix 3, the SDK serves the tunnel for you. On earlier versions, you also need to mount the tunnel handler. + + + + + + + + + +The integration doesn't handle requests by itself. Call `handleTunnelRequestIfMatched` at the start of your `fetch` handler: + +```javascript +import * as Sentry from "@sentry/cloudflare"; + +export default Sentry.withSentry( + (env) => ({ + dsn: "___PUBLIC_DSN___", + integrations: [Sentry.serveTunnelIntegration()], + }), + { + async fetch(request, env, ctx) { + return ( + (await Sentry.handleTunnelRequestIfMatched(request)) ?? + new Response("Hello") + ); + }, + } +); +``` + + + + + +The integration doesn't handle requests by itself. Mount the tunnel handler, `handleTunnelRequestIfMatched`, before your routes and body parsers. It forwards tunnel requests and returns `undefined` for everything else: + +```javascript {tabTitle:Express} +const express = require("express"); +const Sentry = require("@sentry/node"); + +const app = express(); + +app.use( + (req, res, next) => Sentry.handleTunnelRequestIfMatched(req, res) ?? next() +); +``` + +```javascript {tabTitle:Fastify} +const Fastify = require("fastify"); +const Sentry = require("@sentry/node"); + +const app = Fastify(); + +app.addHook("onRequest", async (request, reply) => { + const tunnelResponse = Sentry.handleTunnelRequestIfMatched( + request.raw, + reply.raw + ); + if (tunnelResponse) { + await tunnelResponse; + return reply; + } +}); +``` + +```javascript {tabTitle:Fetch API} +export default { + fetch(request) { + return ( + Sentry.handleTunnelRequestIfMatched(request) ?? new Response("Hello") + ); + }, +}; +``` + + + + + +See `serveTunnelIntegration` for all options, like a fixed path or more allowed DSNs, and for registering the tunnel as a route instead. + + + + + +Your server also needs to serve the tunnel. See [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/) for how to set it up, and for all options, like a fixed path or more allowed DSNs. + + + + + +## Setting Up Your Own Tunnel + +Set the `tunnel` option to the URL of your endpoint. We recommend a path on your own origin, like `/tunnel`, so the browser doesn't send a CORS preflight request: + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: "/tunnel", +}); +``` + +The SDK now sends all events to `/tunnel`. Your endpoint must: + +- Forward the request body to Sentry, without cookies or auth headers. +- Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. +- Send the envelope only to the host of that DSN. + +If your server runs a Sentry JavaScript SDK, `handleTunnelRequest` does all of this for you: + +```javascript +// Import from your server SDK. On version 10, import from @sentry/core instead. +import { handleTunnelRequest } from "@sentry/node"; + +export async function POST(request) { + return handleTunnelRequest(request, { + allowedDsns: ["___PUBLIC_DSN___"], + }); +} +``` + + + +```csharp {tabTitle:ASP.NET Core} +// This functionality is now built-in to the Sentry.AspNetCore package. +// See https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/#tunnel +// docs for more information. + +// This example shows how you could implement it yourself: + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text.Json; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; + +// Change host appropriately if you run your own Sentry instance. +const string host = "sentry.io"; +// Set knownProjectIds to a list with your Sentry project IDs which you +// want to accept through this proxy. +var knownProjectIds = new HashSet() { }; + +var client = new HttpClient(); +WebHost.CreateDefaultBuilder(args).Configure(a => + a.Run(async context => + { + context.Request.EnableBuffering(); + using var reader = new StreamReader(context.Request.Body); + var header = await reader.ReadLineAsync(); + var headerJson = JsonSerializer.Deserialize>(header); + if (headerJson.TryGetValue("dsn", out var dsnString) + && Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn)) + { + var projectId = dsn.AbsolutePath.Trim('/'); + if (knownProjectIds.Contains(projectId) && string.Equals(dsn.Host, host, StringComparison.OrdinalIgnoreCase)) { + context.Request.Body.Position = 0; + await client.PostAsync($"https://{dsn.Host}/api/{projectId}/envelope/", + new StreamContent(context.Request.Body)); + } + } + })).Build().Run(); +``` + +```ruby {tabTitle:Rails} +require 'net/http' + +class HomeController < ApplicationController + + SENTRY_HOST = "oXXXXXX.ingest.sentry.io" + SENTRY_PROJECT_IDS = ["123456"] + + def tunnel + envelope = request.body.read + piece = envelope.split("\n").first + header = JSON.parse(piece) + dsn = URI.parse(header['dsn']) + project_id = dsn.path.tr('/', '') + + raise "Invalid sentry hostname: #{dsn.hostname}" if dsn.hostname != SENTRY_HOST + raise "Invalid sentry project id: #{project_id}" unless SENTRY_PROJECT_IDS.include?(project_id) + + upstream_sentry_url = "https://#{SENTRY_HOST}/api/#{project_id}/envelope/" + Net::HTTP.post(URI(upstream_sentry_url), envelope) + + head(:ok) + rescue => e + # handle exception in your preferred style, + # e.g. by logging or forwarding to server Sentry project + Rails.logger.error('error tunneling to sentry') + end + +end +``` + + + +### Credentials on Tunnel Requests + +The browser SDK doesn't set the [`credentials`](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) option of `fetch`. With the default value `same-origin`, the browser sends credentials (cookies and HTTP authentication) to a tunnel on the same origin as your app. A tunnel that forwards request headers sends these credentials to Sentry. + + + +The Next.js `tunnelRoute` option handles this for you. + + + +Forward only the request body, or tell the browser to send no credentials: + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tunnel: "/tunnel", + transportOptions: { + fetchOptions: { credentials: "omit" }, + }, +}); +``` + +If a layer in front of your tunnel requires credentials (for example, Vercel Deployment Protection, Cloudflare Access, or HTTP Basic authentication), it rejects requests without credentials. Keep the default in this case, and make sure that your tunnel doesn't forward the request headers. diff --git a/docs/platforms/javascript/common/troubleshooting/index.mdx b/docs/platforms/javascript/common/troubleshooting/index.mdx index 543869c260ed5..edd637ad1bc85 100644 --- a/docs/platforms/javascript/common/troubleshooting/index.mdx +++ b/docs/platforms/javascript/common/troubleshooting/index.mdx @@ -41,6 +41,7 @@ If you set up the Sentry SDK and it's not sending any data to Sentry: If you update your Sentry SDK to a new major version, you might encounter breaking changes that need some adaption on your end. + Check out our migration guide to learn everything you need @@ -126,7 +127,7 @@ Since Chrome 142, a page needs the user's permission before it can send requests | public | private network or localhost | Permission prompt | | private network | localhost | Permission prompt | -This affects a publicly hosted app reporting to a self-hosted Sentry that is only reachable on an internal address, and Spotlight enabled on a non-localhost page. To avoid the prompt, expose Sentry on a public hostname, or use the [`tunnel` option](#using-the-tunnel-option) to send events through your app's own origin. +This affects a publicly hosted app reporting to a self-hosted Sentry that is only reachable on an internal address, and Spotlight enabled on a non-localhost page. To avoid the prompt, expose Sentry on a public hostname, or use a tunnel to send events through your app's own origin. @@ -213,242 +214,10 @@ Chrome then ignores the SDK stack frames when debugging. -When you are using our CDN, ad-blocking or script-blocking extensions may prevent our SDK from being fetched and initialized properly. Because of this, any call to the SDKs API will fail and may cause your application to behave unexpectedly. - -Additionally, even when the SDK is downloaded and initialized correctly, Sentry endpoints that need to receive captured data may be blocked as well. This prevents any error reports, sessions health, or performance data from being delivered, making it effectively unavailable in [sentry.io](https://sentry.io). - -Furthermore, some browsers, like [Brave](https://brave.com/), have built-in ad-blockers that may block requests sent to our endpoint. Even if users deactivate your domain from blocking, Brave might continue to block [requests made from service workers](https://github.com/getsentry/sentry/issues/47912#issuecomment-1573714875). - -You can work around our CDN bundles being blocked by [using our NPM packages](#using-the-npm-package) and bundling our SDK with your app. However, the endpoint blockage can only be resolved by using a tunnel as explained below. - - - - - - - - -Set `tunnel: true` in your browser `Sentry.init`, and add `serveTunnelIntegration` to your server `Sentry.init`: - -```javascript {tabTitle:Browser} -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tunnel: true, -}); -``` - -```javascript {tabTitle:Server} -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [Sentry.serveTunnelIntegration()], -}); -``` - -The browser then sends its events to a path on your own origin derived from the DSN, and your server forwards them to Sentry. - - - -The SDK serves the tunnel for you and reads your app's base path from your framework config. - - - - - -In framework mode, the SDK serves the tunnel for you and reads your app's base path from your framework config. In other modes, see Serving the Tunnel Yourself. - - - - - -On Remix 3, the SDK serves the tunnel for you and reads your app's base path from your framework config. On earlier versions, see Serving the Tunnel Yourself. - - - - - -The integration doesn't handle requests by itself. Mount `handleTunnelRequestIfMatched` on your server, before your routes and body parsers: - -```javascript {filename:Server} -app.use( - (req, res, next) => Sentry.handleTunnelRequestIfMatched(req, res) ?? next() -); -``` - - - - - -See `serveTunnelIntegration` for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. - - - - - -See [`serveTunnelIntegration`](/platforms/javascript/guides/node/configuration/integrations/servetunnel/) for a fixed path, more allowed DSNs, and how the tunnel handles requests. If you can't use the managed tunnel, set up your own tunnel as explained below. - - - - - - - - - - -The Sentry Next.js SDK has a separate option to make setting up tunnels very -straight-forward, allowing you to skip the setup below. See -`tunnelRoute` to learn how to set up tunneling on Next.js. - -If you do not want to configure `tunnelRoute`, you can follow the guide below. - - - -A tunnel is an HTTP endpoint that acts as a proxy between Sentry and your application. Because you control this server, there is no risk of any requests sent to it being blocked. When the endpoint lives under the same origin (although it does not have to in order for the tunnel to work), the browser will not treat any requests to the endpoint as a third-party request. As a result, these requests will have different security measures applied which, by default, don't trigger ad-blockers. A quick summary of the flow can be found below. - -![Tunnel Flow](./img/tunnel.png) - -Starting with version `6.7.0` of the JavaScript SDK, you can use the `tunnel` option to tell the SDK to deliver events to the configured URL, instead of using the DSN. This allows the SDK to remove `sentry_key` from the query parameters, which is one of the main reasons ad-blockers prevent sending events in the first place. This option also stops the SDK from sending preflight requests, which was one of the requirements that necessitated sending the `sentry_key` in the query parameters. - -To enable the `tunnel` option, provide either a relative or an absolute URL in your `Sentry.init` call. When you use a relative URL, it's relative to the current origin, and this is the form that we recommend. Using a relative URL will not trigger a preflight CORS request, so no events will be blocked, because the ad-blocker will not treat these events as third-party requests. When using tunneling with server-side SDKs like `@sentry/node` or `@sentry/bun` you must provide an absolute URL. +Ad-blocking or script-blocking extensions may block Sentry in two ways: -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tunnel: "/tunnel", -}); -``` - -Once configured, all events will be sent to the `/tunnel` endpoint. This solution, however, requires an additional configuration on the server, as the events now need to be parsed and redirected to Sentry. - -Your tunnel endpoint must: - -- Forward the request body to Sentry, without cookies or auth headers. -- Accept only envelopes whose DSN is on a list of allowed DSNs. Otherwise, anyone can use your endpoint to send requests to other servers. -- Send the envelope only to the host of that DSN. - -On a JavaScript server with Fetch API `Request` and `Response` objects, `handleTunnelRequest` from `@sentry/core` (SDK version `10.40.0` and later) does this for you. Starting with versions `10.77.1` (v10) and `11.9.0` (v11), it also rejects requests larger than 20 MiB. - -```javascript -import { handleTunnelRequest } from "@sentry/core"; - -export async function POST(request) { - return handleTunnelRequest(request, { - allowedDsns: ["___PUBLIC_DSN___"], - }); -} -``` - -If you implement the endpoint yourself, here's an example for your server component: - -```csharp - -// This functionality is now built-in to the Sentry.AspNetCore package. -// See https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/#tunnel -// docs for more information. - -// This example shows how you could implement it yourself: - -using System; -using System.Collections.Generic; -using System.IO; -using System.Net.Http; -using System.Text.Json; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; - -// Change host appropriately if you run your own Sentry instance. -const string host = "sentry.io"; -// Set knownProjectIds to a list with your Sentry project IDs which you -// want to accept through this proxy. -var knownProjectIds = new HashSet() { }; - -var client = new HttpClient(); -WebHost.CreateDefaultBuilder(args).Configure(a => - a.Run(async context => - { - context.Request.EnableBuffering(); - using var reader = new StreamReader(context.Request.Body); - var header = await reader.ReadLineAsync(); - var headerJson = JsonSerializer.Deserialize>(header); - if (headerJson.TryGetValue("dsn", out var dsnString) - && Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn)) - { - var projectId = dsn.AbsolutePath.Trim('/'); - if (knownProjectIds.Contains(projectId) && string.Equals(dsn.Host, host, StringComparison.OrdinalIgnoreCase)) { - context.Request.Body.Position = 0; - await client.PostAsync($"https://{dsn.Host}/api/{projectId}/envelope/", - new StreamContent(context.Request.Body)); - } - } - })).Build().Run(); -``` - -```ruby -require 'net/http' - -class HomeController < ApplicationController - - SENTRY_HOST = "oXXXXXX.ingest.sentry.io" - SENTRY_PROJECT_IDS = ["123456"] - - def tunnel - envelope = request.body.read - piece = envelope.split("\n").first - header = JSON.parse(piece) - dsn = URI.parse(header['dsn']) - project_id = dsn.path.tr('/', '') - - raise "Invalid sentry hostname: #{dsn.hostname}" if dsn.hostname != SENTRY_HOST - raise "Invalid sentry project id: #{project_id}" unless SENTRY_PROJECT_IDS.include?(project_id) - - upstream_sentry_url = "https://#{SENTRY_HOST}/api/#{project_id}/envelope/" - Net::HTTP.post(URI(upstream_sentry_url), envelope) - - head(:ok) - rescue => e - # handle exception in your preferred style, - # e.g. by logging or forwarding to server Sentry project - Rails.logger.error('error tunneling to sentry') - end - -end -``` - -```javascript -const SENTRY_HOST = "oXXXXXX.ingest.sentry.io"; -const SENTRY_PROJECT_IDS = ["123456"]; - -export const postAction = async ({ request }) => { - try { - const envelopeBytes = await request.arrayBuffer(); - const envelope = new TextDecoder().decode(envelopeBytes); - const piece = envelope.split("\n")[0]; - const header = JSON.parse(piece); - const dsn = new URL(header["dsn"]); - const project_id = dsn.pathname?.replace("/", ""); - - if (dsn.hostname !== SENTRY_HOST) { - throw new Error(`Invalid sentry hostname: ${dsn.hostname}`); - } - - if (!project_id || !SENTRY_PROJECT_IDS.includes(project_id)) { - throw new Error(`Invalid sentry project id: ${project_id}`); - } - - const upstream_sentry_url = `https://${SENTRY_HOST}/api/${project_id}/envelope/`; - await fetch(upstream_sentry_url, { method: "POST", body: envelopeBytes }); - - return json({}, { status: 200 }); - } catch (e) { - console.error("error tunneling to sentry", e); - return json({ error: "error tunneling to sentry" }, { status: 500 }); - } -}; -``` - -If your use-case is related to the SDK package itself being blocked, any of the following solutions will help you resolve this issue. +- They block requests to Sentry's ingest endpoints, so captured data never reaches [sentry.io](https://sentry.io). Send events through your own server to avoid this, as described in Tunneling. +- When you load the SDK from our CDN, they may prevent it from being fetched and initialized. Any call to the SDK's API then fails and may cause your application to behave unexpectedly. Any of the following solutions resolves this. ### Using the NPM Package @@ -508,32 +277,6 @@ If you would like to copy and paste the snippet directly, here it is minified: - - -The browser SDK doesn't set the [`credentials`](https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials) option of `fetch`. With the default value `same-origin`, the browser sends credentials (cookies and HTTP authentication) to a tunnel on the same origin as your app. A tunnel that forwards request headers sends these credentials to Sentry. - - - -The Next.js `tunnelRoute` option handles this for you. See `tunnelRoute`. - - - -Forward only the request body, or tell the browser to send no credentials: - -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - tunnel: "/tunnel", - transportOptions: { - fetchOptions: { credentials: "omit" }, - }, -}); -``` - -If a layer in front of your tunnel requires credentials (for example, Vercel Deployment Protection, Cloudflare Access, or HTTP Basic authentication), it rejects requests without credentials. Keep the default in this case, and make sure that your tunnel doesn't forward the request headers. - - - diff --git a/docs/platforms/javascript/guides/astro/index.mdx b/docs/platforms/javascript/guides/astro/index.mdx index 85729298541b1..fe17c7c409c9d 100644 --- a/docs/platforms/javascript/guides/astro/index.mdx +++ b/docs/platforms/javascript/guides/astro/index.mdx @@ -204,7 +204,7 @@ At this point, you should have integrated Sentry into your Astro application. He - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup - Set up Agent Tracing to monitor your AI systems -- Set up tunneling to avoid ad blockers blocking Sentry events +- Set up tunneling to avoid ad blockers blocking Sentry events diff --git a/docs/platforms/javascript/guides/cordova/configuration/options.mdx b/docs/platforms/javascript/guides/cordova/configuration/options.mdx index 6906a9235b502..94c8535356f42 100644 --- a/docs/platforms/javascript/guides/cordova/configuration/options.mdx +++ b/docs/platforms/javascript/guides/cordova/configuration/options.mdx @@ -49,9 +49,9 @@ Environments are case-sensitive. The environment name can't contain newlines, sp -Sets the URL that will be used to transport captured events. This can be used to work around ad-blockers or to have more granular control over events sent to Sentry. Adding your DSN is still required when using this option so necessary attributes can be set on the generated Sentry data. This option **requires the implementation** of a custom server endpoint. Learn more and find examples in [Dealing with Ad-Blockers](/platforms/javascript/troubleshooting/#dealing-with-ad-blockers). +Sets the URL that will be used to transport captured events. This can be used to work around ad-blockers or to have more granular control over events sent to Sentry. Adding your DSN is still required when using this option so necessary attributes can be set on the generated Sentry data. This option **requires the implementation** of a custom server endpoint. Learn more and find examples in Tunneling. -The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in [Using the `tunnel` Option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). +The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in Setting Up Your Own Tunnel. diff --git a/docs/platforms/javascript/guides/ember/index.mdx b/docs/platforms/javascript/guides/ember/index.mdx index 4a12916733b9e..8b944aebf8d2f 100644 --- a/docs/platforms/javascript/guides/ember/index.mdx +++ b/docs/platforms/javascript/guides/ember/index.mdx @@ -154,7 +154,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io) to view the col At this point, you should have integrated Sentry into your Ember application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events diff --git a/docs/platforms/javascript/guides/gatsby/index.mdx b/docs/platforms/javascript/guides/gatsby/index.mdx index ec585fdbbe0d2..c6d51f50c2fa3 100644 --- a/docs/platforms/javascript/guides/gatsby/index.mdx +++ b/docs/platforms/javascript/guides/gatsby/index.mdx @@ -165,7 +165,7 @@ At this point, you should have integrated Sentry into your Gatsby application. H - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup - Set up Agent Tracing to monitor your AI systems -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events diff --git a/docs/platforms/javascript/guides/nextjs/configuration/build/index.mdx b/docs/platforms/javascript/guides/nextjs/configuration/build/index.mdx index 65cc4f66e263a..7bf7f3ce73812 100644 --- a/docs/platforms/javascript/guides/nextjs/configuration/build/index.mdx +++ b/docs/platforms/javascript/guides/nextjs/configuration/build/index.mdx @@ -227,7 +227,7 @@ export const config = { -Learn more about tunneling in the troubleshooting section. +Learn more about tunneling in Tunneling. The tunnel route works in one of two modes: diff --git a/docs/platforms/javascript/guides/nextjs/index.mdx b/docs/platforms/javascript/guides/nextjs/index.mdx index 71fff4aae652d..e520f2719db03 100644 --- a/docs/platforms/javascript/guides/nextjs/index.mdx +++ b/docs/platforms/javascript/guides/nextjs/index.mdx @@ -247,7 +247,7 @@ At this point, you should have integrated Sentry into your Next.js application. - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup - Set up Agent Tracing to monitor agents built with the Vercel AI SDK, LangChain, and more -- Set up tunneling to avoid ad blockers blocking Sentry events, if you didn't enable it in the wizard +- Set up tunneling to avoid ad blockers blocking Sentry events, if you didn't enable it in the wizard diff --git a/docs/platforms/javascript/guides/react-router/index.mdx b/docs/platforms/javascript/guides/react-router/index.mdx index 27fcb45648a80..14c926394cb08 100644 --- a/docs/platforms/javascript/guides/react-router/index.mdx +++ b/docs/platforms/javascript/guides/react-router/index.mdx @@ -82,7 +82,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io) to view the col At this point, you should have integrated Sentry into your React Router Framework application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers blocking Sentry events +- Set up tunneling to avoid ad blockers blocking Sentry events - Read the manual setup guide for advanced configuration diff --git a/docs/platforms/javascript/guides/react-router/manual-setup.mdx b/docs/platforms/javascript/guides/react-router/manual-setup.mdx index aec0eda1e8064..9dc43365e7f9d 100644 --- a/docs/platforms/javascript/guides/react-router/manual-setup.mdx +++ b/docs/platforms/javascript/guides/react-router/manual-setup.mdx @@ -458,7 +458,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io) to view the col At this point, you should have integrated Sentry into your React Router Framework application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers blocking Sentry events +- Set up tunneling to avoid ad blockers blocking Sentry events - Set up Agent Tracing to monitor your AI systems diff --git a/docs/platforms/javascript/guides/react/index.mdx b/docs/platforms/javascript/guides/react/index.mdx index f44073a9ba55a..4b2bc7300c0a9 100644 --- a/docs/platforms/javascript/guides/react/index.mdx +++ b/docs/platforms/javascript/guides/react/index.mdx @@ -276,7 +276,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io) to view the col At this point, you should have integrated Sentry into your React application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events - Explore React-specific features diff --git a/docs/platforms/javascript/guides/solid/index.mdx b/docs/platforms/javascript/guides/solid/index.mdx index 4cfd9c1810a37..3f68538c33adc 100644 --- a/docs/platforms/javascript/guides/solid/index.mdx +++ b/docs/platforms/javascript/guides/solid/index.mdx @@ -152,7 +152,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io/) to view the co At this point, you should have integrated Sentry into your Solid application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events - Explore Solid-specific features diff --git a/docs/platforms/javascript/guides/solidstart/index.mdx b/docs/platforms/javascript/guides/solidstart/index.mdx index f7c7a9f1baade..bb69e18cc532d 100644 --- a/docs/platforms/javascript/guides/solidstart/index.mdx +++ b/docs/platforms/javascript/guides/solidstart/index.mdx @@ -369,7 +369,7 @@ At this point, you should have integrated Sentry into your SolidStart applicatio - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup - Set up Agent Tracing to monitor your AI systems -- Set up tunneling to avoid ad blockers blocking Sentry events +- Set up tunneling to avoid ad blockers blocking Sentry events diff --git a/docs/platforms/javascript/guides/svelte/index.mdx b/docs/platforms/javascript/guides/svelte/index.mdx index 1931db3436219..3a50e8b42a42e 100644 --- a/docs/platforms/javascript/guides/svelte/index.mdx +++ b/docs/platforms/javascript/guides/svelte/index.mdx @@ -192,7 +192,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io/) to view the co At this point, you should have integrated Sentry into your Svelte application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events - Explore Svelte-specific features diff --git a/docs/platforms/javascript/guides/vue/index.mdx b/docs/platforms/javascript/guides/vue/index.mdx index fe85f766b3816..7d1102360a9e6 100644 --- a/docs/platforms/javascript/guides/vue/index.mdx +++ b/docs/platforms/javascript/guides/vue/index.mdx @@ -232,7 +232,7 @@ Now, head over to your project on [Sentry.io](https://sentry.io/) to view the co At this point, you should have integrated Sentry into your Vue application. Here's what to explore next: - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events - Explore Vue-specific features diff --git a/docs/product/explore/dropped-data.mdx b/docs/product/explore/dropped-data.mdx index 93623f10b9f5e..88a2a5cc36adc 100644 --- a/docs/product/explore/dropped-data.mdx +++ b/docs/product/explore/dropped-data.mdx @@ -158,7 +158,7 @@ The request failed without a response. Ad blockers and browser extensions are a - **Browser:** A CORS misconfiguration, the user being offline, or the page unloading before the request completes. - **Server:** No outbound network access from the host or container, an egress firewall, a DNS failure, TLS errors from an intercepting proxy, or proxy settings the SDK is not using. - **Actions:** - - For ad blockers, route events through your own domain with the [`tunnel` option](/platforms/javascript/troubleshooting/#using-the-tunnel-option). + - For ad blockers, route events through your own domain with the [`tunnel` option](/platforms/javascript/configuration/tunneling/). - For browsers, confirm in devtools that requests to your ingest domain are not blocked, and check your CORS configuration. - For servers, verify outbound connectivity to your ingest domain from the host or container. diff --git a/platform-includes/configuration/integrations/javascript.astro.mdx b/platform-includes/configuration/integrations/javascript.astro.mdx index 9d14eb2142664..0e49438125ebd 100644 --- a/platform-includes/configuration/integrations/javascript.astro.mdx +++ b/platform-includes/configuration/integrations/javascript.astro.mdx @@ -8,8 +8,8 @@ Depending on whether an integration enhances the functionality of a particular r ### Common Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | @@ -20,37 +20,37 @@ Depending on whether an integration enhances the functionality of a particular r ### Browser Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | -| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: | -| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | -| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | -| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | -| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | -| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | -| [`interactionsIntegration`](./interactions/) | | | ✓ | | | -| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | -| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | -| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | -| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | -| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | -| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | -| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | -| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | -| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | -| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | -| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | -| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | -| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | -| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | -| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | -| [`statsigIntegration`](./statsig/) | | | | | ✓ | -| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | -| [`unleashIntegration`](./unleash/) | | | | | ✓ | +| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | +| ---------------------------------------------------------------- | :-----------------: | :--------: | :---------: | :--------: | :--------------------: | +| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | +| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | +| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | +| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | +| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | +| [`interactionsIntegration`](./interactions/) | | | ✓ | | | +| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | +| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | +| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | +| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | +| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | +| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | +| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | +| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | +| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | +| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | +| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | +| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | +| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | +| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | +| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | +| [`statsigIntegration`](./statsig/) | | | | | ✓ | +| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | +| [`unleashIntegration`](./unleash/) | | | | | ✓ | ### Node.js Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -97,3 +97,4 @@ Depending on whether an integration enhances the functionality of a particular r | [`firebaseIntegration`](./firebase/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.aws-lambda.mdx b/platform-includes/configuration/integrations/javascript.aws-lambda.mdx index ac3543690d0d9..016c450488ece 100644 --- a/platform-includes/configuration/integrations/javascript.aws-lambda.mdx +++ b/platform-includes/configuration/integrations/javascript.aws-lambda.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`awsIntegration`](./aws/) | ✓ | | ✓ | | | [`awsLambdaIntegration`](./awslambda/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | @@ -55,3 +55,4 @@ | [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | ✓ | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.bun.mdx b/platform-includes/configuration/integrations/javascript.bun.mdx index 8dc423f3b61c6..f0fc5778ce959 100644 --- a/platform-includes/configuration/integrations/javascript.bun.mdx +++ b/platform-includes/configuration/integrations/javascript.bun.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -47,14 +47,15 @@ | [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | ✓ | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | ### Bun Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | -| [`bunServerIntegration`](./bunserver/) | ✓ | ✓ | ✓ | | -| [`bunRuntimeMetricsIntegration`](./bunruntimemetrics/) | | | | ✓ | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ------------------------------------------------------ | :--------------: | :--------: | :---------: | :--------------------: | +| [`bunServerIntegration`](./bunserver/) | ✓ | ✓ | ✓ | | +| [`bunRuntimeMetricsIntegration`](./bunruntimemetrics/) | | | | ✓ | diff --git a/platform-includes/configuration/integrations/javascript.cloudflare.mdx b/platform-includes/configuration/integrations/javascript.cloudflare.mdx index 99a2952b3905b..03a90fa3226b7 100644 --- a/platform-includes/configuration/integrations/javascript.cloudflare.mdx +++ b/platform-includes/configuration/integrations/javascript.cloudflare.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Cron** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Cron** | **Additional Context** | +| ---------------------------------------------------- | :--------------: | :--------: | :---------: | :------: | :--------------------: | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | | [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | | [`fetchIntegration`](./fetchIntegration/) | ✓ | ✓ | ✓ | | | @@ -14,6 +14,7 @@ | [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | | [`instrumentPostgresJsSql`](./postgresjs/) | | | ✓ | | | | [`prismaIntegration`](./prisma/) | | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | | [Mistral AI](./mistral/) is automatically instrumented when built with the Sentry Cloudflare Vite plugin. Without the plugin, use `instrumentMistralAiClient`. diff --git a/platform-includes/configuration/integrations/javascript.deno.mdx b/platform-includes/configuration/integrations/javascript.deno.mdx index 187f4353e9937..e7b056b608096 100644 --- a/platform-includes/configuration/integrations/javascript.deno.mdx +++ b/platform-includes/configuration/integrations/javascript.deno.mdx @@ -1,24 +1,25 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Cron** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :------: | :--------------------: | -| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | -| [`consoleIntegration`](./console/) | ✓ | | | | ✓ | -| [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | | -| [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | -| [`denoContextIntegration`](./denocontext/) | ✓ | | | | ✓ | -| [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | -| [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | | -| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | -| [`linkedErrorsIntegration`](./linkederrors/) | ✓ | ✓ | | | | -| [`captureConsoleIntegration`](./captureconsole/) | | | | | ✓ | -| [`denoCronIntegration`](./denocron/) | | | | ✓ | | -| [`denoRuntimeMetricsIntegration`](./denoruntimemetrics/) | | | | | ✓ | -| [`extraErrorDataIntegration`](./extraerrordata/) | | | | | ✓ | -| [`rewriteFramesIntegration`](./rewriteframes/) | | ✓ | | | | -| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | -| [`instrumentPostgresJsSql`](./postgresjs/) | | | ✓ | | | -| [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | | ✓ | -| [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | -| [`mistralAIIntegration`](./mistral/) | ✓ | | ✓ | | | -| [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | +| | **Auto Enabled** | **Errors** | **Tracing** | **Cron** | **Additional Context** | +| -------------------------------------------------------- | :--------------: | :--------: | :---------: | :------: | :--------------------: | +| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | +| [`consoleIntegration`](./console/) | ✓ | | | | ✓ | +| [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | | +| [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | +| [`denoContextIntegration`](./denocontext/) | ✓ | | | | ✓ | +| [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | +| [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | | +| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | +| [`linkedErrorsIntegration`](./linkederrors/) | ✓ | ✓ | | | | +| [`captureConsoleIntegration`](./captureconsole/) | | | | | ✓ | +| [`denoCronIntegration`](./denocron/) | | | | ✓ | | +| [`denoRuntimeMetricsIntegration`](./denoruntimemetrics/) | | | | | ✓ | +| [`extraErrorDataIntegration`](./extraerrordata/) | | | | | ✓ | +| [`rewriteFramesIntegration`](./rewriteframes/) | | ✓ | | | | +| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | +| [`instrumentPostgresJsSql`](./postgresjs/) | | | ✓ | | | +| [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | | ✓ | +| [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | +| [`mistralAIIntegration`](./mistral/) | ✓ | | ✓ | | | +| [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | | diff --git a/platform-includes/configuration/integrations/javascript.fastify.mdx b/platform-includes/configuration/integrations/javascript.fastify.mdx index eeaf38e2bb06b..12c65cec148eb 100644 --- a/platform-includes/configuration/integrations/javascript.fastify.mdx +++ b/platform-includes/configuration/integrations/javascript.fastify.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | @@ -54,3 +54,4 @@ | [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | ✓ | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.gcp-functions.mdx b/platform-includes/configuration/integrations/javascript.gcp-functions.mdx index 461d95cdd4ff5..f58776e8a9ba9 100644 --- a/platform-includes/configuration/integrations/javascript.gcp-functions.mdx +++ b/platform-includes/configuration/integrations/javascript.gcp-functions.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | @@ -56,3 +56,4 @@ | [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | ✓ | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.hapi.mdx b/platform-includes/configuration/integrations/javascript.hapi.mdx index 7c15ac2ecb127..505c376090908 100644 --- a/platform-includes/configuration/integrations/javascript.hapi.mdx +++ b/platform-includes/configuration/integrations/javascript.hapi.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -55,3 +55,4 @@ | [`trpcMiddleware`](./trpc/) | | ✓ | ✓ | ✓ | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.nestjs.mdx b/platform-includes/configuration/integrations/javascript.nestjs.mdx index b831a6cb44efd..83443a5bc0840 100644 --- a/platform-includes/configuration/integrations/javascript.nestjs.mdx +++ b/platform-includes/configuration/integrations/javascript.nestjs.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -55,3 +55,4 @@ | [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.node.mdx b/platform-includes/configuration/integrations/javascript.node.mdx index e3ee76402e28b..c524b4c269baf 100644 --- a/platform-includes/configuration/integrations/javascript.node.mdx +++ b/platform-includes/configuration/integrations/javascript.node.mdx @@ -1,7 +1,7 @@ ### Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`anrIntegration`](./anr/) | | ✓ | | | | [`captureConsoleIntegration`](./captureconsole/) | | | | ✓ | @@ -55,3 +55,4 @@ | [`firebaseIntegration`](./firebase/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.nuxt.mdx b/platform-includes/configuration/integrations/javascript.nuxt.mdx index dee5ac6b1717e..6c45aa884a350 100644 --- a/platform-includes/configuration/integrations/javascript.nuxt.mdx +++ b/platform-includes/configuration/integrations/javascript.nuxt.mdx @@ -8,8 +8,8 @@ Depending on whether an integration enhances the functionality of a particular r ### Common Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | @@ -20,37 +20,37 @@ Depending on whether an integration enhances the functionality of a particular r ### Browser Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | -| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: | -| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | -| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | -| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | -| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | -| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | -| [`interactionsIntegration`](./interactions/) | | | ✓ | | | -| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | -| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | -| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | -| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | -| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | -| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | -| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | -| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | -| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | -| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | -| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | -| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | -| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | -| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | -| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | -| [`statsigIntegration`](./statsig/) | | | | | ✓ | -| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | -| [`unleashIntegration`](./unleash/) | | | | | ✓ | +| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | +| ---------------------------------------------------------------- | :-----------------: | :--------: | :---------: | :--------: | :--------------------: | +| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | +| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | +| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | +| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | +| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | +| [`interactionsIntegration`](./interactions/) | | | ✓ | | | +| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | +| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | +| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | +| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | +| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | +| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | +| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | +| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | +| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | +| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | +| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | +| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | +| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | +| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | +| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | +| [`statsigIntegration`](./statsig/) | | | | | ✓ | +| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | +| [`unleashIntegration`](./unleash/) | | | | | ✓ | ### Node.js Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -96,3 +96,4 @@ Depending on whether an integration enhances the functionality of a particular r | [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.remix.mdx b/platform-includes/configuration/integrations/javascript.remix.mdx index 80d9715cfff34..3205a5ad16569 100644 --- a/platform-includes/configuration/integrations/javascript.remix.mdx +++ b/platform-includes/configuration/integrations/javascript.remix.mdx @@ -8,8 +8,8 @@ Depending on whether an integration enhances the functionality of a particular r ### Common Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | @@ -20,37 +20,37 @@ Depending on whether an integration enhances the functionality of a particular r ### Browser Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | -| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: | -| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | -| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | -| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | -| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | -| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | -| [`interactionsIntegration`](./interactions/) | | | ✓ | | | -| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | -| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | -| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | -| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | -| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | -| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | -| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | -| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | -| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | -| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | -| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | -| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | -| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | -| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | -| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | -| [`statsigIntegration`](./statsig/) | | | | | ✓ | -| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | -| [`unleashIntegration`](./unleash/) | | | | | ✓ | +| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | +| ---------------------------------------------------------------- | :-----------------: | :--------: | :---------: | :--------: | :--------------------: | +| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | +| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | +| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | +| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | +| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | +| [`interactionsIntegration`](./interactions/) | | | ✓ | | | +| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | +| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | +| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | +| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | +| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | +| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | +| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | +| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | +| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | +| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | +| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | +| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | +| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | +| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | +| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | +| [`statsigIntegration`](./statsig/) | | | | | ✓ | +| [`supabaseIntegration`](./supabase/) | | ✓ | ✓ | | | +| [`unleashIntegration`](./unleash/) | | | | | ✓ | ### Node.js Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -96,3 +96,4 @@ Depending on whether an integration enhances the functionality of a particular r | [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/configuration/integrations/javascript.sveltekit.mdx b/platform-includes/configuration/integrations/javascript.sveltekit.mdx index c832017405940..eeb1e1b65ce3e 100644 --- a/platform-includes/configuration/integrations/javascript.sveltekit.mdx +++ b/platform-includes/configuration/integrations/javascript.sveltekit.mdx @@ -8,8 +8,8 @@ Depending on whether an integration enhances the functionality of a particular r ### Common Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`dedupeIntegration`](./dedupe/) | ✓ | ✓ | | | | [`eventFiltersIntegration`](./eventfilters/) | ✓ | ✓ | | | | [`functionToStringIntegration`](./functiontostring/) | ✓ | | | | @@ -20,36 +20,36 @@ Depending on whether an integration enhances the functionality of a particular r ### Browser Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | -| ----------------------------------------------------- | :--------------: | :--------: | :---------: | :--------: | :--------------------: | -| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | -| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | -| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | -| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | -| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | -| [`interactionsIntegration`](./interactions/) | | | ✓ | | | -| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | -| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | -| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | -| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | -| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | -| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | -| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | -| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | -| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | -| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | -| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | -| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | -| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | -| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | -| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | -| [`statsigIntegration`](./statsig/) | | | | | ✓ | -| [`unleashIntegration`](./unleash/) | | | | | ✓ | +| | **Auto Enabled** | **Errors** | **Tracing** | **Replay** | **Additional Context** | +| ---------------------------------------------------------------- | :-----------------: | :--------: | :---------: | :--------: | :--------------------: | +| [`breadcrumbsIntegration`](./breadcrumbs/) | ✓ | | | | ✓ | +| [`browserApiErrorsIntegration`](./browserapierrors/) | ✓ | ✓ | | | | +| [`browserSessionIntegration`](./browsersession/) | ✓ | | | | ✓ | +| [`browserTracingIntegration`](./browsertracing/) | ✓ | | ✓ | | ✓ | +| [`fetchStreamPerformanceIntegration`](./fetchstreamperformance/) | | | ✓ | | | +| [`interactionsIntegration`](./interactions/) | | | ✓ | | | +| [`userTimingIntegration`](./usertiming/) | | | ✓ | | | +| [`webVitalsIntegration`](./webvitals/) | With BrowserTracing | | ✓ | | | +| [`globalHandlersIntegration`](./globalhandlers/) | ✓ | ✓ | | | | +| [`httpContextIntegration`](./httpcontext/) | ✓ | | | | ✓ | +| [`browserProfilingIntegration`](./browserprofiling/) | | | ✓ | | | +| [`contextLinesIntegration`](./contextlines/) | | ✓ | | | | +| [`featureFlagsIntegration`](./featureflags/) | | | | | ✓ | +| [`graphqlClientIntegration`](./graphqlclient/) | | | | | ✓ | +| [`httpClientIntegration`](./httpclient/) | | ✓ | | | | +| [`launchDarklyIntegration`](./launchdarkly/) | | | | | ✓ | +| [`moduleMetadataIntegration`](./modulemetadata/) | | | | | ✓ | +| [`openFeatureIntegration`](./openfeature/) | | | | | ✓ | +| [`replayCanvasIntegration`](./replaycanvas/) | | | | ✓ | | +| [`replayIntegration`](./replay/) | | | | ✓ | ✓ | +| [`reportingObserverIntegration`](./reportingobserver/) | | ✓ | | | | +| [`statsigIntegration`](./statsig/) | | | | | ✓ | +| [`unleashIntegration`](./unleash/) | | | | | ✓ | ### Node.js Integrations -| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | -| --------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | +| | **Auto Enabled** | **Errors** | **Tracing** | **Additional Context** | +| ---------------------------------------------------------- | :--------------: | :--------: | :---------: | :--------------------: | | [`amqplibIntegration`](./amqplib/) | ✓ | | ✓ | | | [`consoleIntegration`](./console/) | ✓ | | | ✓ | | [`contextLinesIntegration`](./contextlines/) | ✓ | ✓ | | | @@ -96,3 +96,4 @@ Depending on whether an integration enhances the functionality of a particular r | [`typesafeIntegration`](./typesafe/) | ✓ | | ✓ | | | [`zodErrorsIntegration`](./zodErrors/) | | | | ✓ | | [`pinoIntegration`](./pino/) | | ✓ | | | +| [`serveTunnelIntegration`](./servetunnel/) | | | | | diff --git a/platform-includes/getting-started-complete/javascript.mdx b/platform-includes/getting-started-complete/javascript.mdx index 2730660e61b65..1b1b1c3960a73 100644 --- a/platform-includes/getting-started-complete/javascript.mdx +++ b/platform-includes/getting-started-complete/javascript.mdx @@ -205,7 +205,7 @@ At this point, you should have integrated Sentry into your JavaScript applicatio - Explore [practical guides](/get-started/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) -- Set up tunneling to avoid ad blockers from blocking Sentry events +- Set up tunneling to avoid ad blockers from blocking Sentry events diff --git a/platform-includes/getting-started-tunneling/javascript.astro.mdx b/platform-includes/getting-started-tunneling/javascript.astro.mdx index b99782cc63ad6..afe1a499ac32a 100644 --- a/platform-includes/getting-started-tunneling/javascript.astro.mdx +++ b/platform-includes/getting-started-tunneling/javascript.astro.mdx @@ -16,4 +16,4 @@ Sentry.init({ }); ``` -Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see the Tunneling page. diff --git a/platform-includes/getting-started-tunneling/javascript.mdx b/platform-includes/getting-started-tunneling/javascript.mdx index 12c290d10e01f..886a6e9ce6727 100644 --- a/platform-includes/getting-started-tunneling/javascript.mdx +++ b/platform-includes/getting-started-tunneling/javascript.mdx @@ -1,6 +1,6 @@ You can prevent ad blockers from blocking Sentry events using tunneling. Use the `tunnel` option in `Sentry.init` to add an API endpoint in your application that forwards Sentry events to Sentry servers. -This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. The endpoint must forward only the request body to Sentry and accept only your own DSN. You can find a detailed explanation on how to do this on our Troubleshooting page. +This will send all events to the `tunnel` endpoint. However, the events need to be parsed and redirected to Sentry, so you'll need to do additional configuration on the server. The endpoint must forward only the request body to Sentry and accept only your own DSN. You can find a detailed explanation on how to do this on the Tunneling page. ```javascript {3} Sentry.init({ diff --git a/platform-includes/getting-started-tunneling/javascript.nuxt.mdx b/platform-includes/getting-started-tunneling/javascript.nuxt.mdx index ba7feb068a7f0..11d401510531d 100644 --- a/platform-includes/getting-started-tunneling/javascript.nuxt.mdx +++ b/platform-includes/getting-started-tunneling/javascript.nuxt.mdx @@ -16,4 +16,4 @@ Sentry.init({ }); ``` -Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see the Tunneling page. diff --git a/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx b/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx index db41cd6335b34..43e69cd3c094b 100644 --- a/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx +++ b/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx @@ -16,4 +16,4 @@ Sentry.init({ }); ``` -Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see our Troubleshooting page. +Learn more about the options in `serveTunnelIntegration`. To set up your own tunnel endpoint instead, see the Tunneling page.