@brizz/browser
v0.3.0
Published
Brizz product analytics SDK for browsers
Readme
@brizz/browser
Brizz product analytics SDK for browser apps. Emits track('event_name', {...}) calls as
OpenTelemetry log records to your Brizz gateway, so frontend interactions are correlated with
backend agent traces in the same Brizz session.
Lightweight and dependency-light: a small bundle, no framework lock-in, and PII masking built in.
Drop it into any web app via npm or a CDN <script> tag and start sending events in a few lines.
Building analytics into a Node backend instead? Use
@brizz/sdk.
Install
npm install @brizz/browser
# or
pnpm add @brizz/browserOr via CDN:
<script src="https://unpkg.com/@brizz/browser/dist/index.iife.js"></script>
<script>
const brizz = Brizz.init({ dsn: 'https://[email protected]/acme-web' });
brizz.setSessionId('session-from-your-backend');
brizz.track('clicked_submit', { plan: 'pro' });
</script>Quick start
import { Brizz } from '@brizz/browser';
const brizz = Brizz.init({
dsn: 'https://[email protected]/<service-name>',
});
// Same session_id your backend uses on agent traces:
brizz.setSessionId('session-from-your-backend');
brizz.track('clicked_submit', { plan: 'pro', step: 'checkout' });Init options
| Option | Type | Notes |
| -------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| dsn | string | Client DSN URL: https://brizz-ing-c-<bearer>@<host>/<service>. Mutually exclusive with apiKey/baseUrl/appName. |
| apiKey | string | Bearer token. Use instead of dsn if you prefer explicit options. Must be a Client DSN (brizz-ing-c-). |
| baseUrl | string | Gateway origin, e.g. https://gateway.brizz.dev. Required without dsn. |
| appName | string | Service name; becomes service.name. Required without dsn. |
| disableBatch | boolean | Flush each event immediately. Default false (events batch for ~5 sec). |
| logLevel | 'debug' \| 'info' \| 'warn' \| 'error' \| 'none' | Default 'warn'. |
| masking | boolean \| object | Enable PII masking with built-in patterns (true) or supply a custom config. |
| headers | Record<string, string> | Optional extra HTTP headers attached to each OTLP request. |
Session correlation
The browser SDK does not mint, rotate, or persist session ids. You decide where the id comes
from — typically your own backend mints it and propagates it to both the frontend (this SDK) and
your agent backend (the Node SDK). Each track() call attaches the id as
LogAttributes['brizz.session.id'] (canonical Brizz key — same one the Node SDK uses) so Brizz can
join the two halves in the dashboard. The event name is similarly mirrored into
LogAttributes['event.name'].
Default session
For the common single-session case, set the id once and every subsequent track() uses it:
brizz.setSessionId('whatever-the-customer-decides'); // sticky across track() calls
brizz.track('clicked_submit', { plan: 'pro' });
brizz.setSessionId(null); // e.g. on logoutParallel sessions
When a single page hosts more than one logical session (e.g. two chat widgets, side-by-side
compares, an in-product copilot opened alongside a support chat), use brizz.session(id) to get a
session-bound emitter. Every track() on that emitter stamps the bound id, independent of the
default.
const supportChat = brizz.session('support-thread-7');
const copilot = brizz.session('copilot-session-42');
supportChat.track('typed', { length: 12 });
copilot.track('accepted_suggestion', { tool: 'rename' });Scoped emitters are cheap — cache one per session and reuse, or create on the fly. They share the
same underlying transport, so brizz.flush() flushes everything; supportChat.flush() is a
convenience that delegates to the parent.
Prefer brizz.session(id) over swapping the default with setSessionId back and forth when
sessions are concurrent — async event handlers crossing a swap would otherwise stamp the wrong id.
Auto-context
Every track() call automatically attaches the following attributes, all under the
brizz.internal.browser.* namespace:
brizz.internal.browser.current_url,brizz.internal.browser.referrer,brizz.internal.browser.page_titlebrizz.internal.browser.browser,brizz.internal.browser.browser_version,brizz.internal.browser.os,brizz.internal.browser.os_version,brizz.internal.browser.user_agentbrizz.internal.browser.locale,brizz.internal.browser.screen_width,brizz.internal.browser.screen_height
These come from window, document, navigator, and screen at the moment the event fires.
Session-replay correlation
If your page also runs FullStory, Mixpanel Session Replay, or LogRocket, Brizz auto-correlates the recording with the matching session. A deep-link badge appears on the Brizz session in the dashboard — one click to the replay.
| Provider | Setup | Opt out |
|---|---|---|
| FullStory | None — auto-detected when their snippet is on the page | disableFullStory: true |
| Mixpanel | None — auto-detected when Session Replay is enabled on the project | disableMixpanel: true |
| LogRocket | None for CDN snippet. For the npm package, see below. | disableLogRocket: true |
For the LogRocket npm package, add one side-effect import:
import { Brizz } from '@brizz/browser';
import '@brizz/browser/integrations/logrocket';
import LogRocket from 'logrocket';
LogRocket.init('myapp/myapp');
Brizz.init({ dsn: '...' });Wire format
Each track() produces one OTel log record, batched by BatchLogRecordProcessor and exported as
OTLP-JSON to <baseUrl>/v1/logs:
POST https://gateway.brizz.dev/v1/logs
Authorization: Bearer brizz-ing-c-9k3xPq2v...
X-Brizz-Service-Name: acme-web
Content-Type: application/json
{ "resourceLogs": [...] }The gateway then:
- Authenticates the Client DSN bearer
- Checks
Originagainst the allowed-origins for that DSN - Rewrites the resource
service.namefromX-Brizz-Service-Name - Publishes to NATS unchanged
Bundle size
The package ships in three forms:
| Build | Size (gzipped) | Use |
| --------------------------- | -------------- | ------------------------------------------------------------- |
| ESM (dist/index.js) | ~8 KB | npm + bundler (Vite/Webpack/Rollup). OTel deps stay external. |
| CJS (dist/index.cjs) | ~8 KB | npm for CommonJS consumers. |
| IIFE (dist/index.iife.js) | ~19 KB | CDN <script> tag. OTel deps bundled. |
CI fails if either bundle exceeds its size budget (size-limit config in package.json).
Browser support
Targets ES2022 — runs in modern evergreen browsers (Chrome, Safari, Firefox, Edge).
License
Apache-2.0
