See what happened
right before it broke.
Replay the pages, clicks, and requests of a visit, next to the errors it hit. Inputs are masked before anything leaves the browser, and every request links to its trace.
Before they leave the browser
With the minute before it
Each request, its exact span
Nothing recorded before it
One integration, after consent
Replay is an integration of the browser SDK you already use for errors and analytics. It does nothing until the visitor agrees: the recorder only loads after grantConsent().
- Records 10% of sessions by default, plus any session that hits an error
- One recording per tab, continued across reloads on the same site
- revokeConsent() stops capture and erases what the browser kept
import { errors, initMonocle, network } from '@monocle.sh/browser-sdk'
import { replay } from '@monocle.sh/browser-sdk/replay'
const sessionReplay = replay({
sessionSampleRate: 0.1,
captureOnError: true,
})
export const monocle = initMonocle({
dsn,
environment: 'production',
integrations: [network(), errors(), sessionReplay],
})
// From your consent banner
await sessionReplay.grantConsent()The minute before the error
Sessions that were not sampled are buffered in the browser. When an exception is captured, Monocle keeps up to 60 seconds before it and records the rest of the visit.
- Open the replay from the exact occurrence of an issue
- Pages, clicks, requests, and exceptions on the timeline and in the event list
- Each request links to its trace and span by ID, never guessed from timestamps
buffered in the browser, up to 60 s before the error
14:31:12 navigation /checkout
14:31:49 click Pay $148.00
14:31:50 request POST /api/payments 504 → its trace
14:32:07 error PaymentTimeoutError → its issue
then recorded until the visit endsPrivate by default
Masking runs in the browser, before events are buffered or sent. Input values are always replaced, and you choose which text and which parts of the page never get recorded.
- Every input value replaced with ***, unless you opt a field back in
- Canvas, video, audio, request bodies, and headers are never captured
- Query strings and fragments are dropped from page URLs
<!-- Input values are masked by default -->
<input name="card-number" autocomplete="cc-number" />
<!-- This text is masked too -->
<p data-monocle-replay-mask>{{ customer.address }}</p>
<!-- Never recorded, replaced by an empty box -->
<section data-monocle-replay-block>
<SupportChat />
</section>Plugs into your stack
Browser SDK
The replay() integration
Issues
Replay from the occurrence
Traces
Requests linked to their span
Consent banner
grantConsent() and revokeConsent()
Visitor identity
Opt in with captureUser
Same-site reloads
One recording per tab
See what your apps
are really doing.
Traces, logs, errors and metrics for every app you ship. Bring it all into focus.
