@debugbundle/sdk-browser
Browser SDK for DebugBundle.
Use this package to capture frontend exceptions, breadcrumbs, first-party request failures, browser device context, trace headers, and probe data. The recommended transport is a browser relay served by your backend.
Installation
npm install @debugbundle/sdk-browser
Keep @debugbundle/sdk-browser and @debugbundle/sdk-node on the same release version. If you pin the core-owned support packages directly, keep @debugbundle/shared-types and @debugbundle/redaction on the same version too.
Quick Start
import { createDebugBundleBrowserSdk } from "@debugbundle/sdk-browser";
const debugbundle = createDebugBundleBrowserSdk();
debugbundle.init({
transportMode: "relay",
endpoint: "/debugbundle/browser",
service: "web",
environment: "production"
});
The browser SDK starts capture only after init() is called. Importing the package has no side effects.
Transport Modes
| Mode | Configuration | Use when |
|---|---|---|
| Relay | transportMode: "relay", plus /debugbundle/browser or an absolute backend relay URL |
Recommended for full-stack apps. Browser events go to your backend first. |
| Direct cloud | projectToken plus the hosted endpoint |
Frontend-only apps without a backend. Use a dedicated write-only token with allowed-origin restrictions. |
For relay setup, see https://debugbundle.com/docs/sdks/browser-relay.
Configuration source precedence
- Explicit
init(...)fields win. - Omitted values fall back to package defaults such as
service: "browser-app"andenvironment: "development". - Capture-policy fields are server-owned and arrive from
GET /v1/sdk/config; they are not accepted from local browser config.
Relay mode should configure only transportMode, the relay endpoint, and service/environment names. The same-origin relay path case, such as /debugbundle/browser, is inferred as relay for compatibility. Absolute backend relay URLs require transportMode: "relay" so the browser SDK stays credential-free and sends the relay batch shape. Direct-cloud mode requires a dedicated public write-only token and a real ingestion endpoint URL.
What It Captures
- Frontend exceptions and unhandled promise rejections
- Recent breadcrumbs from clicks, route changes, console warnings/errors, and first-party network requests
- First-party request failures that should become incident signals
- Browser and device context such as user agent, viewport, screen, locale, connection type, and color scheme
X-DebugBundle-Trace-Idheaders on allowed outgoing requests for frontend/backend correlation- Always-on probe ring buffers that flush with exceptions
Breadcrumbs are kept in memory and attached to frontend exceptions by default. They are not independently shipped unless configured.
Browser-native window.error and resource-load failures include sanitized browser_event metadata when the browser exposes it: event kind, message/file/line/column, opaque-error flag, technical resource target details, and page lifecycle state. URLs are stripped to origin plus path for absolute URLs or path only for relative URLs.
Global unhandledrejection captures include a bounded rejection_reason summary when the browser exposes the original reason. Error reasons preserve name/message, string reasons preserve a truncated preview, object reasons may preserve sanitized name/message plus type preview, and null/undefined reasons are represented explicitly.
The Browser SDK exposes a synchronous beforeSend hook for app-owned final redaction or local suppression before an event is buffered. Use project capture rules first for known operational noise because they are centralized and auditable, and use networkFilter for network breadcrumb/request capture choices.
Network wrapping is designed to preserve normal browser behavior. The SDK supports fetch() calls with string, URL, and Request inputs, and preserves caller headers provided as Headers, header tuple arrays, or records. When trace propagation is enabled for a request, the SDK adds X-DebugBundle-Trace-Id to the effective header set without dropping existing headers such as Authorization.
Configuration
| Option | Default | Purpose |
|---|---|---|
endpoint |
derived from transport | Relay or ingestion endpoint. |
transportMode |
inferred | Explicit "relay" or "direct" transport selection. Use "relay" for absolute backend relay URLs. |
projectToken |
none | Direct cloud write-only token for frontend-only deployments. Omit when using relay. |
service |
browser-app |
Frontend service name shown on incidents and bundles. |
environment |
development |
Runtime environment such as production, staging, or development. |
enabled |
true |
Disable all capture without removing instrumentation. |
redactFields |
common sensitive fields | Additional field names to redact. |
sampleRate |
1.0 |
Per-event sampling rate. |
sessionSampleRate |
1.0 |
Per-session capture sampling rate. |
batchSize |
10 |
Events per batch before flushing. |
flushInterval |
3000 |
Flush interval in milliseconds. |
logLevel |
warning |
Minimum captured browser log severity. |
maxBreadcrumbs |
10 |
Breadcrumb ring-buffer size. |
breadcrumbsOnErrorOnly |
true |
Attach breadcrumbs to exceptions instead of shipping them independently. |
captureNetwork |
true |
Capture first-party network breadcrumbs and failure signals. |
captureClicks |
true |
Capture click breadcrumbs. |
captureRouteChanges |
true |
Capture route-change breadcrumbs. |
captureConsole |
false |
Capture console warnings and errors. |
networkFilter |
default failure filtering | Include or exclude requests by URL, status, or response time. |
maxEventsPerSession |
100 |
Cap non-exception events per browser session. |
tracePropagationTargets |
same-origin | URLs allowed to receive X-DebugBundle-Trace-Id. |
maxProbeLabels |
50 |
Maximum distinct probe labels buffered in memory. |
maxProbeEntriesPerLabel |
10 |
Maximum entries retained per probe label. |
probeFlushOnError |
true |
Attach buffered probe data to captured exceptions. |
requestTimeoutMs |
5000 |
Transport timeout in milliseconds. |
transport |
fetch transport | Custom transport function for tests or advanced routing. |
beforeSend |
none | Synchronous hook that receives a fully built event before buffering; return an event to keep it or null to drop it locally. |
tracePropagationTargets is separate from the relay endpoint. Same-origin application requests receive trace headers by default. For split frontend/backend deployments, add the backend API origin, such as https://api.example.com, when cross-origin first-party requests should receive X-DebugBundle-Trace-Id and be eligible for policy-driven request-failure promotion. Third-party absolute URLs are not traced by default.
Handled HTTP responses do not need to throw an exception to become request incidents. A failed response can emit a standalone request_event when it is first-party for trace propagation and matches the active capture preset, immediate_client_error_statuses, or an immediate_client_error_path_rules entry. Unpromoted 4xx responses remain breadcrumbs/context.
Local beforeSend hook
Use beforeSend for app-owned local policy such as final redaction, tenant-specific suppression, or filtering a browser signal that should never leave the page. The hook runs after the SDK builds the event and before project capture rules, sampling, suppression, and transport.
debugbundle.init({
transportMode: "relay",
endpoint: "/debugbundle/browser",
service: "web",
environment: "production",
beforeSend(event) {
if (event.event_type === "frontend_exception" && event.payload.message === "Expected local-only error") {
return null;
}
return event;
}
});
If the hook throws or returns an invalid event, the SDK keeps the original event. Browser SDK failures are swallowed so host pages keep running.
Service naming guidance
Keep the browser service name distinct from backend deployables inside the same DebugBundle project. A common pattern is checkout-web for the browser frontend and checkout-api for the backend relay host.
When you send through a relay, the browser service name should stay browser-owned. The backend relay should not overwrite it unless you intentionally want a shared surface name.
Explicit Capture
debugbundle.captureException(error, { route: window.location.pathname });
debugbundle.captureLog("checkout warning", "warning", { cartId });
debugbundle.captureMessage("user started checkout");
debugbundle.probe("checkout.cart", { itemCount: cart.items.length });
await debugbundle.flush();
Safety and Privacy
- SDK failures are caught internally and do not break the host page.
- Sensitive fields are redacted before transport.
- Duplicate event storms are suppressed locally.
- Browser project tokens are never needed when using relay mode.
- Breadcrumb and probe buffers are in-memory only.
Safe startup behavior
- Relay mode keeps browser-visible credentials out of the page and does not require a token in frontend config.
- Invalid relay paths or missing direct-cloud credentials fail closed without crashing the host page.
status()exposes whether the SDK is healthy, degraded, or disconnected.- Auth-rejected direct-cloud responses stop pretending capture is healthy and clear buffered events only after the endpoint explicitly rejects the token.
First-event verification
Minimal application check:
import { createDebugBundleBrowserSdk } from "@debugbundle/sdk-browser";
const debugbundle = createDebugBundleBrowserSdk();
debugbundle.init({
transportMode: "relay",
endpoint: "/debugbundle/browser",
service: "checkout-web",
environment: "development"
});
debugbundle.captureException(new Error("debugbundle browser smoke"));
await debugbundle.flush();
console.log(debugbundle.status());
Repository-level verification runs the same clean-install smoke used by CI and release:
pnpm build
pnpm smoke:packed
Documentation
- Browser SDK docs: https://debugbundle.com/docs/sdks/browser
- Browser relay: https://debugbundle.com/docs/sdks/browser-relay
- SDK overview: https://debugbundle.com/docs/sdks
- Repository: https://github.com/debugbundle/debugbundle-js
License
AGPL-3.0-only.