Handling Ad Blockers and Safari's Intelligent Tracking Prevention (ITP)
Last updated: June 11, 2026
Ad blockers and Safari's Intelligent Tracking Prevention (ITP) can silently prevent browser telemetry from reaching Honeycomb. The SDK initializes without errors, but events never arrive.
This can affect any application using the Honeycomb Web SDK (@honeycombio/opentelemetry-web) when end users have ad blockers installed or are using Safari.
What Gets Blocked and Why
There are three ways blockers can interfere with browser telemetry:
Third-party script loading: Loading the Honeycomb Web SDK via a
<script>tag from an external CDN makes it look like a third-party tracking script. Ad blockers can flag and block the script load entirely, preventing the SDK from initializing.Third-party endpoint requests: Even when the SDK is bundled into your app, sending telemetry directly to
api.honeycomb.iocan be blocked. Ad blockers maintain lists of known analytics and telemetry endpoints, and Honeycomb's API domain may appear on some of these lists.CNAME uncloaking: Setting up a subdomain like
metrics.yourdomain.comas a CNAME pointing to Honeycomb does not reliably work. Advanced blockers (Safari ITP, uBlock Origin, AdGuard) resolve the underlying IP address or DNS chain and block requests when the resolved destination doesn't match the first-party origin.
Recommended Fix
The fix uses the setup we already recommend for production: bundle the SDK and send telemetry through your own OpenTelemetry Collector.
Install the SDK via npm and bundle it
Install the Honeycomb Web SDK as an npm dependency and bundle it with your application using your existing build tool (webpack, Vite, Rollup, esbuild, etc.):
npm install @honeycombio/opentelemetry-webWhen bundled, the SDK becomes part of your application's own JavaScript. There is no external CDN request and nothing for a blocker to flag as third-party.
Send telemetry to your own OpenTelemetry Collector
Configure the SDK to point at a Collector endpoint on your own infrastructure instead of sending directly to Honeycomb:
import { HoneycombWebSDK } from "@honeycombio/opentelemetry-web";
const sdk = new HoneycombWebSDK({
endpoint: "https://otel-collector.yourdomain.com",
serviceName: "your-frontend",
skipOptionsValidation: true, // required when not providing an apiKey
});
sdk.start();skipOptionsValidation: trueis required because the API key is no longer in the browser — it lives in the Collector configuration instead.Configure the Collector to receive browser telemetry
The Collector needs an OTLP/HTTP receiver with CORS enabled so the browser can send to it, and an exporter that forwards telemetry to Honeycomb with your API key.
See the Honeycomb Collector docs for the full configuration: OpenTelemetry Collector setup — see the "Browser Telemetry" section for CORS configuration and the exporter setup for forwarding to Honeycomb.
Why this works
Telemetry requests from the browser go to otel-collector.yourdomain.com — a first-party domain under your control. To the browser and any ad blocker, this is indistinguishable from a normal API call to your own backend. The Collector then forwards to Honeycomb server-side, completely outside the browser's view.
No special path disguising or domain tricks are needed in most cases.
Additional Considerations
If your frontend is embedded as an iframe on a third-party site, the Collector endpoint must be on the same origin as the iframe content for requests to be treated as first-party.
If you use Refinery for tail-based sampling, you can place it between the Collector and Honeycomb. Using a Collector in front of Refinery is the more common pattern and gives you CORS support out of the box.
This issue is likely to become more common as browser privacy features continue to get stricter.
Related Docs
Honeycomb Web SDK setup — see "Sending to OpenTelemetry Collector"
OpenTelemetry Collector setup — see "Browser Telemetry" for CORS configuration