Session Replay
Usero records the session in the browser and links each report to the moment the user hit submit. You see exactly what they did, then the AI drafts the fix as a GitHub PR you review and merge.
A bug report without a replay is a guessing game. "It broke" with no steps means you reproduce from scratch, or you reply asking for details the user will never send.
Standalone session-replay tools record everything and leave you to scrub through hours of recordings hunting for the moment something went wrong. The opposite problem, a feedback widget with no recording, gives you a report that says "the export is broken" and nothing else, so you burn an afternoon trying to reproduce a state you cannot see. The gap is that the replay and the report live in two different products that do not talk to each other. You have the recording in one tab and the complaint in another, and stitching them together by timestamp is manual archaeology. What you actually want is narrow: the few seconds of context around the exact moment a user decided something was wrong, sitting right next to what they typed.
How it works
Disclosure: I build Usero, so weigh that. Replay here is built for the feedback case rather than general analytics. Recording streams while the user is on the page, and it works standalone too: one import from @usero/sdk/replay and a .start() call records sessions with no widget on the page at all. When a user opens the widget and submits, the recording of what they just did is attached to that exact report. In the dashboard each feedback with a replay gets a "Watch session replay" link that opens the player at the moment the feedback was given, not at the start of the session. Then the wedge runs: Usero clusters the duplicate reports, reads the replay context, and opens a GitHub pull request with a first pass at the fix. You watch the replay, review the diff, and merge it yourself. Nothing auto-merges. The replay is the evidence; the PR is the action.
Instead of "please describe what you were doing", the replay shows it. The five seconds where the user clicked the broken button, the form state they were in, the route they were on. The single highest-effort part of a good bug report is captured automatically, so even a one-line complaint becomes actionable.
You do not scrub through a 20-minute session to find the relevant 10 seconds. The player jumps to the offset where the user submitted, because the widget sends the replay offset alongside the report. You watch the part that matters and nothing else.
Inputs and textareas are masked out of the box via maskAllInputs. You tag anything sensitive with data-usero-mask (masked) or data-usero-block (never recorded). The recording uses rrweb and is gzipped in the browser before it leaves the page, so you control what is captured at the source.
rrweb ships in a separate chunk that only loads if you import the plugin, and even then it lazy-loads at runtime after an engagement gate you set (startAfterMs). You can sample a fraction of sessions with sampleRate. The widget stays light, the replay only costs you bytes on the sessions you actually record.
The honest objection
If you need full-session replay across your whole product for analytics, funnels, and rage-click detection, keep your dedicated tool. Usero does not replace it. Usero ties each recording to the feedback a user submits, so the replay exists to explain a specific report rather than to analyze every session. The reason to use Usero is the next step: the replay feeds an AI that drafts the fix as a pull request. A standalone replay tool shows you the bug and stops. Usero shows you the bug and opens the PR. If you only want recordings, stay where you are.
FAQ
The recording covers the session: events stream to Usero in gzipped chunks while the user is on the page and the recording ends when the page is hidden or closed. The player opens at the feedback offset, not the session start, so you land on the relevant moment.
No. Since @usero/sdk v1.2.0, sessionReplay from @usero/sdk/replay records standalone: call .start() with your clientId and recording begins with no widget and no UI. React apps can use the useSessionReplay hook. If the widget mounts later on the same page, it links feedback to the recording that is already running instead of starting a second one.
Inputs and textareas are masked by default (maskAllInputs). You mask any text with the data-usero-mask attribute and exclude whole subtrees from recording with data-usero-block. Recordings are gzipped in the browser via the native CompressionStream API before upload, so you control capture at the source.
No. rrweb lives in a separate plugin chunk that only loads if you import it, and even then it lazy-loads at runtime after an engagement gate (startAfterMs) you set. Consumers who never import the plugin pay zero rrweb bytes. You can also record only a fraction of sessions with sampleRate.
When a recording exists, the widget sends sessionReplayId and replayOffsetMs alongside the submission. If you post feedback through the API yourself, those two fields are how a replay gets attached to a report. See the session replay docs for the full reference.
Free tier. No credit card. Two-minute install. The AI opens the PR, you merge it.