SDK options
release, environment, sampling, ignoring errors, opt-in breadcrumbs and attachments, delivery and queue limits.
On this page
Options for init (browser, React, TanStack Start client) and for the withBelvador callback (Cloudflare Workers, TanStack Start server). Every option except dsn is optional. Invalid values fall back to the default instead of throwing.
Common options#
| Option | Type | Default | What it does |
|---|---|---|---|
dsn | string | — (required in the browser) | The project DSN. On Workers it can come from BELVADOR_DSN instead. |
release | string | not set | Your app's version (build number, commit). Used to find regressions and to match source maps. |
environment | string | "production" | production, staging, preview… Shown and filterable on issues. |
dist | string | not set | A build variant within one release, if you ship several. |
sampleRate | number 0–1 | 1 | Share of error events to send. 0.25 sends about a quarter. |
ignoreErrors | (string | RegExp)[] | [] | Errors to drop. A string matches part of the message; a RegExp is tested against it. |
captureAborted | boolean | false | Also report work the visitor cancelled: an AbortError (or an error caused by one), or a server error thrown after the client disconnected. Off because a closed tab is not a bug. A TimeoutError is always reported. Since 0.2.0. |
tracePropagation | { targets: (string | RegExp)[], baggage?: boolean } | off | Add traceparent and sentry-trace headers to requests to these URLs, so errors and job runs across your services link up. See Link errors across tiers. Since 0.3.0. |
beforeSend | (event, hint) => event | null | not set | Change or drop an event. Return null to drop. May return a promise. |
beforeBreadcrumb | (crumb, hint) => crumb | null | not set | Change or drop a breadcrumb. |
maxBreadcrumbs | number 0–100 | 50 | How many recent breadcrumbs travel with an event. |
attachments | boolean | false | Allow attachments to be sent. Off means attachments are dropped in your app. |
privacyPolicy | privacyPolicy(json) | not set | Apply the project's privacy rules in your app too, from Copy as code on the Privacy page. Your node applies them either way. See Data protection. Since 0.6.0. |
preview | boolean | false | Print each envelope as it would be sent and send nothing. On servers BELVADOR_PREVIEW=1 does the same. Since 0.6.0. |
debug | boolean | false | Log the SDK's decisions to the console. Turn off again for production. |
disabled | boolean | false | Keep the SDK off, for example in tests. |
beforeSend and beforeBreadcrumb run before Belvador's mandatory scrubbing, so they cannot add data the scrubber would remove. If a hook throws or its promise rejects, that event or breadcrumb is dropped.
init({ dsn: "https://<public-key>@ingest.belvador.dev/<project-id>", release: import.meta.env.VITE_APP_VERSION, environment: import.meta.env.MODE, sampleRate: 1, ignoreErrors: ["ResizeObserver loop completed with undelivered notifications"], beforeSend(event) { // Drop errors from an internal admin tool. if (event.request?.url?.includes("/internal-admin/")) return null; return event; },});Breadcrumbs#
Breadcrumbs are the steps before an error. Automatic breadcrumbs are off in Belvador's SDKs: they record what users click and which URLs they call, which can include personal data. Turn on only what you need.
Browser (@belvador/browser, @belvador/react, TanStack Start client):
init({ dsn: "https://<public-key>@ingest.belvador.dev/<project-id>", instrument: { console: true, dom: true, fetch: true, xhr: true, history: true },});Workers (withBelvador callback): instrument: { console: true, fetch: true }.
Breadcrumbs you add with addBreadcrumb are always recorded and need no option.
Browser-only options#
| Option | Default | What it does |
|---|---|---|
instrument | all off | Automatic breadcrumbs, see above. |
wrapBrowserApis | false | Wraps timers, requestAnimationFrame and event listeners so errors inside them carry more context. |
allowUrls | all | Only report errors whose stack comes from these script URLs (strings or RegExps). |
denyUrls | none | Ignore errors from these script URLs. Browser extension URLs are always ignored. |
captureViewTransitionSkips | false | Also report a View Transition the browser skipped on purpose (page hidden, another transition started, skipTransition()). Off because the browser is working as designed. Since 0.3.0. |
offline | false | Keep errors that fail on the network in this browser (IndexedDB) and send them when it is back online or on the next load. See Offline and durable delivery. Since 0.6.0. |
Workers-only behaviour#
The withBelvador callback returns the same options without a required dsn, plus instrument: { console, fetch }. Values not returned come from Worker variables:
| Setting | Taken from, in order |
|---|---|
| DSN | callback dsn → BELVADOR_DSN |
| Release | callback release → BELVADOR_RELEASE → CF_VERSION_METADATA.id |
| Environment | callback environment → BELVADOR_ENVIRONMENT → production |
| Off switch | callback disabled → BELVADOR_DISABLED = 1 or true |
Fixed by Belvador#
These cannot be changed, so the SDK sends only errors and never adds personal data on its own:
personal data from the SDK (
sendDefaultPii) is always off;tracing, session replay, logs and profiling are off and their data is dropped;
no tunnel, no Spotlight, no default integrations beyond what Belvador sets up;
string values are cut at 8,192 characters.
How sending works#
| Rule | Value |
|---|---|
| Waiting to be sent | at most 30 envelopes, 1 MiB in total (6 MiB with attachments) |
| One attachment | at most 5 MiB |
| One attempt | aborted after 10 seconds |
Network errors and 500/502/503/504 | up to 5 attempts; each wait is random, below 1, 2, 4, then 8 seconds (full jitter, since 0.6.0); the same envelope and event id every time |
503 with Retry-After | waits as asked, up to 60 seconds |
429 | follows the rate-limit headers: new events of that kind are dropped in your app until the limit lifts |
401 / 403 | the key is invalid or revoked: sending stops for the life of the page or Worker isolate |
| Storage | memory only — nothing is written to disk or localStorage, unless you turn on offline (browser) or use @belvador/spool (servers) |
When a page is closing, the SDK sends with keepalive within the browser's limits (up to 60,000 bytes, 15 requests at a time). Events that do not fit, or that are still waiting when the page closes, are lost — unless offline: true keeps them for the next load.
Posts on this topic
All posts- Unhandled promise rejections vs caught errors: what your tracker receives14 browser failures run through an error tracker: which arrive, which vanish when caught and logged, and why rejecting with a string loses the stack.
- How to scrub PII from error monitoring without losing contextA real data scrubber on 16 synthetic error samples: what pattern rules remove, what they miss, what they remove by mistake, and what to add in beforeSend.
Spotted something wrong or missing? Tell us: hello@belvador.dev