Integrations
Integration

Capture browser sessions with the Sazabi Browser SDK

By Sazabi Team

Last verified on Nov 8, 2026.

Server logs tell you a request failed. They do not tell you the page the user was on, the button they pressed three times first or the script error that fired a second before. The browser holds that context, and most teams never see it.

@sazabi/browser is Sazabi's own browser SDK. Sazabi is an AI-native observability and security platform, and this SDK sends browser events to the same intake as your backend logs. Sazabi's Browser and React Native SDKs capture errors, console output, network calls with trace context, user interactions, navigation and session identity from web and mobile apps. They do not capture Core Web Vitals or session replay.

What each source sends

The SDK is a single package with one flow: it posts OTLP log records from the browser to your intake URL. It has no dependencies, and the URL is its only required setting. It emits a session-scoped stream, and every event carries session.id, session.window_id, session.distinct_id, app.screen.url and an app.event_type.

The Sazabi docs for this source list the event types:

  • navigation: page loads and in-app route changes, including pushState.
  • click, rage_click and dead_click: taps and keyboard clicks, plus repeated or no-op clicks.
  • error: uncaught exceptions and unhandled rejections, with exception.type, exception.message and exception.stacktrace.
  • network: fetch and XMLHttpRequest calls with method, status, duration and trace context.
  • input, pointer, log, custom, lifecycle and sdk_health for field engagement, contact episodes, your own log lines, marks from addEvent(), tab visibility and the SDK's own delivery problems.

By default console.error and console.warn are mirrored into the stream as well. Privacy comes first in the design. Input values are never captured, element names come only from developer-written sources such as aria-label, and consent can hold all capture until it resolves true.

Questions it answers

  • Which JavaScript errors did users hit after yesterday's deploy, grouped by exception.message?
  • What did a visitor do in the minute before an error event?
  • Which routes collect rage_click events?
  • Which network calls returned a 500, and what did the backend log for the same trace_id?
  • Does one session.distinct_id span several tabs?
  • Is the SDK dropping data, according to sdk_health events?

A worked example: a checkout button that does nothing

A user reports that the pay button hangs. In the stream you find one session. These records are shortened and invented, and every field is named on the Sazabi page.

app.event_type=rage_click   app.screen.url=https://shop.example.com/checkout
app.event_type=network      app.screen.url=https://shop.example.com/checkout
                            (POST, status 500, 8.1 s, trace context injected)
app.event_type=error        exception.type=TypeError
                            exception.message=Cannot read properties of undefined (reading 'id')
                            exception.stacktrace=at submitOrder (checkout.js:88)
session.id=s-91c4  session.distinct_id=user_123

Read it top to bottom. The user clicked repeatedly, the POST came back 500 after eight seconds, and then the client threw while handling the response. Two bugs, one chain. Ask the Sazabi agent in a thread, or from the terminal:

sazabi logs ask "for session.id s-91c4, show the backend logs that share the trace_id of the failed POST on /checkout"

The join works because the SDK injected a traceparent header and your backend ran inside that trace context. The backend line tells you why the order failed. The exception.stacktrace tells you why the page did not cope. Fix both, or the next backend error will look the same.

Setting up trace joins

Same-origin requests carry traceparent by default. For an API on another origin, add it to network.allowlist. Your CORS rules must also allow traceparent, or the browser preflight fails. The SDK additionally records platform request ids such as x-request-id as app.network.request_id. A join key against CDN logs needs no backend change.

How it fits with other integrations

Frontend telemetry is most useful next to backend sources. The OpenTelemetry integration covers the backend side of a shared trace_id, and AWS or Cloudflare logs can supply the edge request that sat between the two. If you already run another browser tool, the Sentry and PostHog SDKs can be pointed at the same intake. Browse every source on the integrations page.

Log sources

  • Sazabi Browser SDK (manual log source, sdks): Capture browser sessions — navigation, clicks, errors, and network calls with trace context — with the Sazabi browser SDK.

What Sazabi detects from these logs today

These detections are on for every production project, with no monitors or alert rules to write. Sazabi opens an issue when one fires.

  • Novel event: A kind of error that has never appeared before.
  • Client errors: JavaScript exceptions, failed fetches and hydration errors.

Frequently Asked Questions

Is it safe to put the intake URL in a browser bundle?

The URL embeds a write-only public key. It can write telemetry into your project and never read from it. Because anyone can extract it from a page, treat every field on these events, including session.distinct_id, as a client claim and not as proof of identity.

Does the SDK record what users type?

No. An input event records which field was engaged, for how long, how many edits and whether content was pasted. It never records keystrokes or contents, and request and response bodies are never captured. Add data-sazabi-mask to suppress text capture for a subtree.

How does a browser event join a backend log?

Same-origin requests get a traceparent header by default, and you can add other origins to network.allowlist. Your backend must run each request inside the incoming trace context, and your API's CORS rules must allow traceparent. Then the frontend call and the backend log lines share a trace_id.

What about older SDK versions?

Versions before 0.3.0 emit the same keys under a web. prefix, such as web.event_type and web.page.url. Those rows keep that shape until the app upgrades.

Sources

  1. The Sazabi Browser SDK connects to Sazabi as a manual log source (accessed Nov 8, 2026)
  2. The app.event_type values, session.id, session.window_id and session.distinct_id, exception.* fields on error events, traceparent injection, the network.allowlist option, input and privacy rules, and the 5000 ms flush interval (accessed Nov 8, 2026)
  3. What the SDK captures, and that Sentry or PostHog SDKs can also be pointed at the intake URL (accessed Nov 8, 2026)
  4. Reference for every init option, capture type and API of @sazabi/browser (accessed Nov 8, 2026)