diff --git a/docs/platforms/android/troubleshooting/index.mdx b/docs/platforms/android/troubleshooting/index.mdx
index f3a6786fae9809..b9fa8464e5d991 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 4b33240722ecea..6b9e9219f490c6 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
new file mode 100644
index 00000000000000..789d9c3ff1a147
--- /dev/null
+++ b/docs/platforms/javascript/common/configuration/integrations/servetunnel.mdx
@@ -0,0 +1,193 @@
+---
+title: ServeTunnel
+description: "Serves a tunnel on your server so Sentry browser SDK events reach Sentry through your own origin, past ad blockers."
+supportedCategories:
+ - server
+notSupported:
+ - javascript.nextjs
+ - javascript.solidstart
+---
+
+
+
+_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}
+Sentry.init({
+ dsn: "___PUBLIC_DSN___",
+ integrations: [Sentry.serveTunnelIntegration()],
+});
+```
+
+```javascript {tabTitle: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 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, you also need to [mount the tunnel handler](#mounting-the-tunnel-handler).
+
+
+
+
+
+The integration doesn't handle requests by itself, so you also need to [mount the tunnel handler](#mounting-the-tunnel-handler).
+
+
+
+
+
+On Cloudflare Workers, add the integration to your Sentry options, and 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")
+ );
+ },
+ }
+);
+```
+
+
+
+## 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 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.
+- 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
+
+Pass these options to `serveTunnelIntegration`. Most apps don't need any of them.
+
+### `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 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 {tabTitle:Server}
+Sentry.serveTunnelIntegration({ path: "/monitoring" });
+```
+
+```javascript {tabTitle: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.
+
+## 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:
+
+```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")
+ );
+ },
+};
+```
+
+`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:
+
+```javascript
+Sentry.init({
+ dsn: "___PUBLIC_DSN___",
+ integrations: [Sentry.serveTunnelIntegration({ path: "/monitoring" })],
+});
+
+app.post("/monitoring", (req, res) => Sentry.handleTunnelRequest(req, res));
+```
+
+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 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 68134bd8e631c7..1cf7f9139e533f 100644
--- a/docs/platforms/javascript/common/configuration/options.mdx
+++ b/docs/platforms/javascript/common/configuration/options.mdx
@@ -83,14 +83,55 @@ 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 Setting Up Your Own Tunnel.
+
+
+
+
+
+
+
+
+
+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.
+
+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.
+
+
+
+
+
+- `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 needs to serve it, as described in [`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.
+ - `trailingSlash`: appends a trailing slash to the tunnel path, for servers that redirect paths without one.
-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).
+On the server, `tunnel` only takes a URL. It's where the server SDK sends its own events, and it's independent from `serveTunnelIntegration`.
+
+
+
+
@@ -108,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).
@@ -299,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.
@@ -551,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
@@ -605,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.
@@ -860,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.
@@ -872,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 00000000000000..4843d66e41f4ed
--- /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.
+
+
+
+## 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 1fb9a9adef7e9d..edd637ad1bc855 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,175 +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.
-
-
-
-
-
-
-
-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.
-
-
-
-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.
-
-```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 only the request body to Sentry, without the request 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 });
- }
-};
-```
+Ad-blocking or script-blocking extensions may block Sentry in two ways:
-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
@@ -441,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 85729298541b1b..fe17c7c409c9df 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 6906a9235b5026..94c8535356f424 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 4a12916733b9e7..8b944aebf8d2fb 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 ec585fdbbe0d23..c6d51f50c2fa3b 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 65cc4f66e263a2..7bf7f3ce738122 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 71fff4aae652d8..e520f2719db03e 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 27fcb45648a807..14c926394cb087 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 aec0eda1e80641..9dc43365e7f9dd 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 f44073a9ba55a5..4b2bc7300c0a92 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 4cfd9c1810a377..3f68538c33adc1 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 f7c7a9f1baade9..bb69e18cc532df 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 1931db34362199..3a50e8b42a42e0 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/tanstackstart-react/features/createSentryTunnelRoute.mdx b/docs/platforms/javascript/guides/tanstackstart-react/features/createSentryTunnelRoute.mdx
index d3244d9717c84b..e27f458929227f 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 5663884faf889f..717b5fbf6d0406 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 SDK serves it 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 a9c893db8c2492..b8e980f5bb13b9 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/docs/platforms/javascript/guides/vue/index.mdx b/docs/platforms/javascript/guides/vue/index.mdx
index fe85f766b38162..7d1102360a9e6f 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 93623f10b9f5e6..88a2a5cc36adc0 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 9d14eb2142664e..0e49438125ebda 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 ac3543690d0d99..016c450488ece7 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 8dc423f3b61c6c..f0fc5778ce959b 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 99a2952b3905bc..03a90fa3226b7d 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 187f4353e9937e..e7b056b608096e 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 eeaf38e2bb06bb..12c65cec148eb7 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 461d95cdd4ff56..f58776e8a9ba92 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 7c15ac2ecb127e..505c3760909086 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 b831a6cb44efd0..83443a5bc0840f 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 e3ee76402e28b4..c524b4c269baf7 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 dee5ac6b1717ef..6c45aa884a3500 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 80d9715cfff34d..3205a5ad165693 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 c8320174059407..eeb1e1b65ce3e0 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 2730660e61b65e..1b1b1c3960a737 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-complete/javascript.nuxt.mdx b/platform-includes/getting-started-complete/javascript.nuxt.mdx
index 8847328ac123f5..e3a96e9137b121 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 00000000000000..afe1a499ac32a3
--- /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 the Tunneling page.
diff --git a/platform-includes/getting-started-tunneling/javascript.mdx b/platform-includes/getting-started-tunneling/javascript.mdx
index 12c290d10e01f9..886a6e9ce67277 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
new file mode 100644
index 00000000000000..11d401510531d4
--- /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 the Tunneling page.
diff --git a/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx b/platform-includes/getting-started-tunneling/javascript.sveltekit.mdx
index 3b1ef2770c630f..43e69cd3c094bf 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 the Tunneling page.