Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c284811
docs(js): Document the managed tunnel and serveTunnelIntegration
logaretm Oct 27, 2026
56f876d
docs(js): Document serving the managed tunnel on any server
logaretm Oct 27, 2026
552e8be
docs(js): Align the managed tunnel docs with the 11.10.0 release
logaretm Oct 28, 2026
2807cbe
docs(js): Hide the managed tunnel docs from Next.js for now
logaretm Oct 28, 2026
f5d4bf8
docs(js): Align the tunnel endpoint rules with handleTunnelRequest
logaretm Oct 28, 2026
cd71dcf
docs(js): Keep the handleTunnelRequest paragraph, with the non-deprec…
logaretm Oct 28, 2026
26dd854
docs(js): Link browser-only platforms to the Node.js serveTunnel page
logaretm Oct 28, 2026
809d61f
docs(js): Document only the middleware for serving the tunnel yourself
logaretm Oct 28, 2026
ebe5801
docs(js): Document handleTunnelRequest for a fixed tunnel path
logaretm Oct 28, 2026
c246c5e
docs(js): Apply the docs style guide to the managed tunnel docs
logaretm Oct 28, 2026
9efd075
docs(js): Clarify that serveTunnelIntegration needs a request hook to…
logaretm Oct 29, 2026
17286bd
docs(js): Show per-platform tunnel serving notes instead of listing e…
logaretm Oct 29, 2026
e33f929
docs(js): Move tunneling docs to their own configuration page
logaretm Oct 30, 2026
b9425c4
docs(js): Document the managed tunnel served by the runtime
logaretm Nov 11, 2026
d08f9da
docs(js): Fix the tunnelRoute note and mark fixed tunnel paths as 11.…
logaretm Nov 11, 2026
b758cac
docs(js): Link the Next.js Cloudflare quick start to the Tunneling page
logaretm Nov 11, 2026
acacaef
docs(js): Link Cordova tunnel option to the JavaScript Tunneling page
logaretm Nov 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/platforms/android/troubleshooting/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion docs/platforms/dotnet/guides/aspnetcore/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,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.

Expand Down
Comment thread
logaretm marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
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
---

<PlatformSection notSupported={["javascript.nextjs"]}>

<AvailableSince version="11.12.0" />

</PlatformSection>

<PlatformSection supported={["javascript.nextjs"]}>

<AvailableSince version="11.13.0" />

</PlatformSection>

_Import name: `Sentry.serveTunnelIntegration`_

This integration serves the tunnel that the browser SDK uses when you set `tunnel: true`. The tunnel forwards the browser's events to Sentry, so ad blockers don't drop them. To set it up, see <PlatformLink to="/configuration/tunneling/">Tunneling</PlatformLink>.

```javascript
Sentry.init({
dsn: "___PUBLIC_DSN___",
integrations: [Sentry.serveTunnelIntegration()],
});
```

## Options

Most apps don't need any of these options.

### `allowedDsns`

_Type: `string[]`_

DSNs to forward besides the server's own. Use this when the browser uses a different DSN than the server. The server's own DSN is always allowed.

```javascript
Sentry.serveTunnelIntegration({
allowedDsns: ["___PUBLIC_DSN___"],
});
```

### `path`

_Type: `string`_

A fixed tunnel path instead of the one derived from the DSN. The SDK serves it as written, without the base path. Set the same path in the browser, as described in <PlatformLink to="/configuration/tunneling/#using-a-fixed-path">Using a Fixed Path</PlatformLink>.

### `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.

### `intercept`

_Type: `boolean`_
_Default: `true`_

Whether the SDK answers tunnel requests before they reach your app. Set it to `false` to answer them from your own code with `handleTunnelRequestIfMatched`, for example behind your own middleware. Tunnel requests still don't show up in your traces:

```javascript
import express from "express";
import * as Sentry from "@sentry/node";

const app = express();

app.use(
(req, res, next) => Sentry.handleTunnelRequestIfMatched(req, res) ?? next()
);
```

<PlatformSection supported={["javascript.nextjs"]}>

On Vercel, the route that `withSentryConfig` adds at build time still answers tunnel requests.

</PlatformSection>
83 changes: 68 additions & 15 deletions docs/platforms/javascript/common/configuration/options.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,51 @@ Environments are case-sensitive. The environment name can't contain newlines, sp

</SdkOption>

<PlatformCategorySection notSupported={['browser']}>

<SdkOption name="tunnel" type='string'>

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 <PlatformLink to="/configuration/tunneling/">Tunneling</PlatformLink>.

The endpoint must forward only the request body to Sentry and accept only your own DSNs. Learn more in <PlatformLink to="/configuration/tunneling/#setting-up-the-tunnel-manually">Setting Up the Tunnel Manually</PlatformLink>.

</SdkOption>

</PlatformCategorySection>

<PlatformCategorySection supported={['browser']}>

<SdkOption name="tunnel" type='string | true | object'>

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, a URL or a path, sends events to that endpoint. You serve the endpoint yourself, as described in <PlatformLink to="/configuration/tunneling/#setting-up-the-tunnel-manually">Setting Up the Tunnel Manually</PlatformLink>.
- `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 <PlatformLink to="/configuration/tunneling/#setting-up-the-tunnel">Setting Up the Tunnel</PlatformLink>.
- 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.

<PlatformSection notSupported={["javascript.nextjs"]}>

`true` and the object are available since version `11.12.0`.

</PlatformSection>

<PlatformSection supported={["javascript.nextjs"]}>

`true` and the object are available since version `11.13.0`.

</PlatformSection>

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`.

</SdkOption>

</PlatformCategorySection>

<PlatformSection supported={['javascript.aws-lambda']}>

<SdkOption name="useLayerExtension" type='boolean' defaultValue='true' envVar='SENTRY_LAYER_EXTENSION'>
Expand All @@ -108,7 +145,7 @@ Set to `false` to opt out, for example, when using a custom `tunnel` or when run
<SdkOption name="dataCollection" type='DataCollection' availableSince="10.57.0">

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).

<PlatformSection notSupported={["javascript.electron"]}>

Expand Down Expand Up @@ -299,21 +336,35 @@ The callback gets a second argument (called a "hint") which contains the origina
<SdkOption name="transport" type="(transportOptions: TransportOptions) => Transport">

<PlatformSection notSupported={["javascript.electron"]}>
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.
</PlatformSection>

<PlatformCategorySection supported={["browser"]}>
In the browser, a `fetch`-based transport is used by default.
</PlatformCategorySection>

<PlatformSection notSupported={["javascript.bun", "javascript.elysia", "javascript.deno", "javascript.cloudflare"]}>
<PlatformCategorySection supported={["server", "serverless"]}>
On the server, a `https`-based transport is used by default.
</PlatformCategorySection>
<PlatformSection
notSupported={[
"javascript.bun",
"javascript.elysia",
"javascript.deno",
"javascript.cloudflare",
]}
>
<PlatformCategorySection supported={["server", "serverless"]}>
On the server, a `https`-based transport is used by default.
</PlatformCategorySection>
</PlatformSection>

<PlatformSection supported={["javascript.bun", "javascript.elysia", "javascript.deno", "javascript.cloudflare"]}>
<PlatformSection
supported={[
"javascript.bun",
"javascript.elysia",
"javascript.deno",
"javascript.cloudflare",
]}
>
A `fetch`-based transport is used by default.
</PlatformSection>

Expand Down Expand Up @@ -551,7 +602,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.
<PlatformCategorySection supported={["browser"]}>
- `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.
</PlatformCategorySection>
<PlatformCategorySection supported={["server", "serverless"]}>
- `normalizedRequest`: Request information of the currently active HTTP
Expand Down Expand Up @@ -605,7 +657,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.

Expand Down Expand Up @@ -882,7 +934,8 @@ Controls whether the SDK installs runtime hooks that instrument supported depend
</PlatformSection>

<Alert>
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.
</Alert>

<SdkOption name="beforeSendLog" type='(log: Log) => Log | null'>
Expand All @@ -894,8 +947,8 @@ This function is called with a log object, and can return a modified log object,
## Metrics Options

<PlatformSection supported={["javascript.electron"]}>
**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.
</PlatformSection>

<SdkOption name="beforeSendMetric" type='(metric: Metric) => Metric | null'>
Expand Down
Loading
Loading