spectra-sdk-browser
v0.1.23
Published
Spectra Browser SDK: rrweb-based session capture and incident slicing
Readme
Spectra Browser SDK
Product Overview
- Spectra captures real user sessions in production using rrweb, detects incidents deterministically on the client (network and UX signals), and uploads minimal event windows to the Spectra backend.
- It exists to provide precise, privacy-safe visibility when something goes wrong in production without adding overhead or requiring developers to reproduce issues locally.
- It solves the gap between coarse error logging and full session replay by sending only the slice around an incident, enabling deterministic replays and optional automated tests downstream.
- In production debugging, Spectra acts as a signal collector: it records DOM changes and network failures, decides when a window should be sent, and leaves deeper analysis and visualization to the backend.
Installation
- Using a package manager:
# npm
npm install @spectra/sdk-browser rrweb
# yarn
yarn add @spectra/sdk-browser rrweb
# pnpm
pnpm add @spectra/sdk-browser rrweb- Using script tags (CDN):
<!-- rrweb runtime -->
<script src="https://unpkg.com/rrweb/dist/rrweb.min.js"></script>
<!-- Spectra SDK UMD bundle -->
<script src="https://unpkg.com/@spectra/sdk-browser/dist/spectra.umd.js"></script>Note: rrweb is not bundled by Spectra by default to keep the init size small. Ensure rrweb.record is available at runtime.
Quick Start
import { Spectra } from "@spectra/sdk-browser";
Spectra.init({
apiKey: "pk_xxx",
endpoint: "https://ingest.spectra.dev",
sampleRate: 1.0,
});What happens after init:
- The SDK starts rrweb recording for DOM changes (canvas and cross-origin iframes disabled), patches fetch and XHR to observe failures, and begins buffering events.
- A simple rule engine evaluates incoming network_error events. If an incident is detected, the SDK slices a small window of events (5s before, inclusive of the error at t), and uploads just that slice.
- Recording continues. The SDK is invisible to users and avoids any blocking or noisy behavior.
- Script tag usage:
<script src="https://unpkg.com/rrweb/dist/rrweb.min.js"></script>
<script src="https://unpkg.com/@spectra/sdk-browser/dist/spectra.umd.js"></script>
<script>
Spectra.init({
apiKey: "pk_xxx",
endpoint: "https://ingest.spectra.dev",
sampleRate: 1.0,
});
</script>Both installation methods use the same SDK and public API; only the delivery mechanism differs (module import vs global).
How It Works
- rrweb capture
- Starts rrweb.record and routes emitted events into the SDK as
{ type: "rrweb", data, ts }. - Canvas and cross-origin iframe recording are disabled to reduce payload size and avoid third-party data collection.
- Starts rrweb.record and routes emitted events into the SDK as
- Buffering
- A rolling buffer stores recent events. IndexedDB is preferred when available; memory fallback is used otherwise.
- Retention is time-based (default ~60s), and the buffer is trimmed opportunistically.
- Rule-based incident detection
- The rule engine ingests only network_error events and uses deterministic thresholds to decide when to cut a window.
- No ML or complex classification; rules are transparent and predictable.
- Event slicing
- On incident, the SDK computes a time window [t-5s, t] and retrieves all events in range.
- To ensure replays have DOM and viewport, the SDK prepends the latest rrweb FullSnapshot (type 2) and Meta (type 4) that occurred before the window start if available (kept in memory even when the buffer trims).
- Backend processing
- The SDK POSTs a single payload with sdkVersion, sessionId, incidentId, and events. Retries once if needed, then drops silently.
- The backend creates deterministic replays, incident objects, and (optionally) Playwright tests based on these slices.
Text Diagram (conceptual):
- Start → rrweb+network capture → buffer events (rolling) → rule engine monitors network_error → incident? → yes → slice window → POST to backend → continue recording
- Incident windows are small, independent uploads with unique incident IDs.
Incident Detection Rules
- Triggers:
- Any network_error with HTTP status ≥ 500.
- Three network_error events within 10 seconds.
- Non-triggers:
- HTTP 4xx client errors (unless they accumulate to 3 within the window).
- Success responses or non-network error events.
- Why this avoids noise:
- Most transient client-side issues won’t meet the threshold.
- Server-side failures (≥ 500) are immediately captured without waiting.
- Simple rules are easy to reason about and communicate to teams.
Privacy & Performance
- Privacy
- No request bodies are captured.
- No response bodies are captured.
- No headers are captured.
- No PII by default.
- Performance
- Lightweight TypeScript SDK with low CPU and memory usage.
- rrweb features are restricted to minimize payload size.
- IndexedDB buffering avoids large in-memory footprints when available.
- Transport retries once and drops silently; no blocking behavior.
Configuration
apiKey: string- Required. Sent via
X-API-Keyheader on incident uploads.
- Required. Sent via
endpoint: string- Required. Spectra ingest endpoint for POSTing incident payloads.
sampleRate?: number- Optional. Range 0–1. Fraction of sessions to record. Defaults to
1(100%). - Purpose: reduces capture overhead by recording only a percentage of sessions. Sampling is decided at init time; if a session is skipped, the SDK does not start recording.
- Recommended: keep
1in development; consider values like0.1(10%) in production for high-traffic sites. Not required — omit to capture 100% of sessions.
- Optional. Range 0–1. Fraction of sessions to record. Defaults to
verbose?: boolean- Optional. Defaults to
false. Whentrue, prints informational logs:- Initialization success and sampling decisions
- Recording started
- Incident detected and window slicing details
- Send start and completion (or failure). No logs are printed when
verboseisfalse.
- Optional. Defaults to
clearOnSend?: boolean- Optional. Defaults to
false. Post-send cleanup strategy:- The buffer always trims events before the end of the sent window.
- When
true, the buffer is fully cleared after trimming. - The SDK keeps the latest rrweb FullSnapshot (type 2) and Meta (type 4) in memory to preserve replay fidelity across subsequent incidents even if the buffer is cleared.
- Optional. Defaults to
baselineSearchBackMs?: number- Optional. Defaults to
0. How far to scan backwards (in ms) in the buffer to find a baseline rrweb FullSnapshot (type 2) and Meta (type 4) to prepend to the incident window. - When
0, the SDK relies on forcing a fresh snapshot at incident time (if rrweb supports it) and the latest baseline kept in memory. - Recommended: small values (e.g., 10_000) if you want a fallback search; keep
0to minimize disk scans and rely on the fresh snapshot.
- Optional. Defaults to
FAQ
- Does this affect users?
- No. The SDK runs unobtrusively with minimal overhead and avoids any UI changes or blocking logic. Failures are silent.
- What happens if the network fails?
- The transport will retry once. If both attempts fail, the incident slice is dropped silently to avoid impact on the end user.
- Can I disable it?
- You control initialization. If you no longer want capture, avoid calling
Spectra.init. A future enhancement may include a runtime toggle.
- You control initialization. If you no longer want capture, avoid calling
- Is this like Sentry or Hotjar?
- Spectra is neither a general error logger nor a full session replay analytics tool. It collects minimal slices around incidents for deterministic replays and optional tests. Think “precision incident windows” rather than “comprehensive logging” or “behavior analytics”.
Roadmap
- DOM text masking and input redaction
- IndexedDB persistence enhancements and offline queueing
- Custom rule configuration
- Mobile SDKs (iOS/Android)
Source Overview
- Public API: index.ts exposes
Spectra.init. - rrweb and network interception: recorder.ts
- Rolling buffer: buffer.ts
- Minimal rules: rules.ts
- Transport: transport.ts
- Session and IDs: session.ts
Conventions
- TypeScript, ES2020+ targets, no frameworks.
- rrweb is expected at runtime (CDN or package install).
- Silent failure policy: the SDK never logs in production.
