@spectosh/browser
v0.2.5
Published
Specto session-replay recorder for bundler users — rrweb DOM capture, console/network/error/rage signals, privacy-masked in the browser.
Maintainers
Readme
@spectosh/browser
Specto's session-replay recorder for bundler users (npm/pnpm/yarn). Same engine as the script-tag snippet: rrweb DOM capture, console/network/error/ rage signals, SPA navigations — with inputs masked, sensitive attributes and PII-looking text scrubbed in the visitor's browser before anything is uploaded.
npm i @spectosh/browserimport { startRecording, identify, track } from '@spectosh/browser'
// in your entry file, before the app renders
const rec = startRecording({
key: 'pk_your_key', // pk_…@eu.specto.sh / pk_…@your-host: the Install page shows yours
privacy: 'strict', // optional: mask ALL text, not just inputs
sampleRate: 0.5, // optional: record half of all sessions
consent: 'required', // optional: record nothing until grantConsent()
})
identify('user_42', { email: '[email protected]', plan: 'pro' }) // find this user's sessions
track('checkout_started', { items: 3 }) // custom timeline event
rec.sessionId // current session id
rec.sessionUrl() // link to this replay in Specto (handy for support tools)
rec.stop()The key is the whole install. A bare pk_… belongs to the hosted
service; a project in another region or on a self-hosted instance has a key
that carries its home — pk_…@eu.specto.sh, pk_…@replay.example.com. The
SDK asks that host for the project's settings before sending anything, so a
key it doesn't know records nothing (and says why in the console) instead of
sending data to the wrong place. host overrides the key's — e.g. your own
domain proxying to Specto.
Recording starts at once. Errors, console output, requests and the DOM are captured from the first moment and held in memory while the project's settings load; then they're filtered by those settings and sent — or dropped. Start it as early as you can and the first requests and errors of a page load are in the replay.
React
import { createRoot } from 'react-dom/client'
import { SpectoProvider, SpectoErrorBoundary, spectoErrorHandler, useSpecto } from '@spectosh/browser/react'
createRoot(document.getElementById('root'), {
onCaughtError: spectoErrorHandler(), // React 19: errors React catches → Issues
onUncaughtError: spectoErrorHandler(),
}).render(
<SpectoProvider apiKey="pk_your_key" user={user}>
<App />
</SpectoProvider>
)
const { identify, track, captureError, sessionUrl } = useSpecto()SpectoProvider starts recording during its first render — before any
component's effects run — once per page (StrictMode, remounts and hot reloads
reuse it; unmounting never stops it), and does nothing on the server, so it
works as-is in a Next.js App Router 'use client' provider. user is
identified whenever it changes; every other prop is a startRecording
option. On React 18, SpectoErrorBoundary reports render errors with their
component stack. React is an optional peer dependency (17+). TypeScript
types ship with the package.
Sessions
A session is one visitor's continuous activity. It survives page loads (it
lives in sessionStorage), ends after 30 minutes without interaction and
rotates after 4 hours. Batches are numbered, so retries after a network
failure, 429 or 503 never duplicate data; quota_exceeded stops
recording, and a full DOM checkpoint is taken every 5 minutes so a lost batch
never ruins the rest of a replay.
Privacy & consent
- Inputs are always masked;
privacy: 'strict'masks all text, drops console text and keeps only the path of recorded URLs (requests, navigations, the page address: no query strings, no hash-route parameters). CSS classesspecto-mask(mask text) andspecto-block(drop element) give per-element control. - Heatmap events carry a click's page position, the viewport width and a selector built from tag, id and classes — never text — plus how far each page view scrolled.
data-*,title,alt,placeholder,aria-labelandvalueattributes are scrubbed; emails, JWTs, bearer tokens, API keys and card-like numbers are redacted from console lines, error messages and URLs.- Do-Not-Track and Global Privacy Control are honored automatically.
consent: 'required'records and stores nothing untilgrantConsent();revokeConsent(),optOut()andoptIn()are exported too.- The project's settings in Specto (strict privacy, console, network details, sampling, a recording kill switch) are fetched at start; the stricter of those and your options always wins.
Full docs live at /docs on your Specto instance.
Build from the monorepo: pnpm run build:npm (outputs packages/browser/dist,
ESM + CJS for both entries, worker inlined); pnpm --filter @spectosh/browser
test runs the unit tests and checks the types. Releases go out via pnpm run release locally or
the tag-triggered workflow (.github/workflows/release.yml).
