Reporting widget
The widget lets your visitors record a bug on your site and send it. The recording runs the same pipeline as everything else in SceneRecap, so what lands in your Inbox is not a video to watch — it is a written report with numbered repro steps, expected vs actual, the first bad moment, and every claim linked to its second in the recording.
Install
Create a site key in Settings → Reporting widget, then paste one tag before </body>:
<script async src="https://scenerecap.com/w.js" data-key="sr_site_…"></script>That renders a small launcher in the bottom-right corner. We recommend turning it off and calling the widget from your own UI instead — a menu item or a link in your help centre gets used, a floating bubble mostly gets ignored:
<script async src="https://scenerecap.com/w.js" data-key="sr_site_…" data-launcher="none"></script>
<button onclick="SceneRecap.open()">Report a problem</button>Options
data-key— your site key. Required. It is public by design (see below).data-launcher—auto(default) ornoneto only useSceneRecap.open().data-position—bottom-right(default) orbottom-left.data-console—on(default) oroffto disable console and network capture entirely.data-accent— a hex colour such as#ff5a5fto match the panel to your own brand. Anything that is not a plain#rrggbbvalue is ignored rather than escaped, because it is used as a colour, not as markup.
Removing the “Recorded and explained with SceneRecap” mark is a plan setting rather than an attribute — it is decided server-side from your workspace, so it cannot be switched on by editing the snippet.
What it costs your page
The loader is about 3 KB gzipped. It draws the launcher and watches for JavaScript errors and failed requests, so that when someone does report a problem the report already contains the error that prompted it. No cookies, no storage writes, no network request — not even to us — until a visitor actually clicks. The panel and the recorder are separate chunks fetched only at that point.
What it watches is held in memory, capped at the most recent 100 errors and 100 failed requests, and discarded when the page unloads. Nothing leaves the browser unless a visitor completes a report and presses Send — so nothing is transmitted about people who never click. We keep the error message, and the method, path and status code of failed requests. We never keep request bodies, headers, form values, or query strings. Set data-console="off" to turn it off completely.
Everything renders inside a shadow root with a full style reset: your CSS cannot reach into the widget and the widget cannot leak into your page.
Content Security Policy
If your site sends a CSP — and it should — allow these:
script-src https://scenerecap.com
connect-src https://api.scenerecap.com
media-src blob:media-src blob: is what lets the visitor watch their own recording back before sending it. If the launcher never appears, a blocked script-src is almost always why — the widget is deliberately silent when it cannot load, rather than throwing errors on your page.
Site keys and origins
A site key ships in your HTML, so it is not a secret and we do not pretend otherwise. What protects it is the exact origin allowlist on the key: every widget request is checked against it, and a key used on any other origin is refused before an upload can start. List each origin in full (https://example.com, https://app.example.com) — no wildcards, up to ten per key. Revoking a key stops it working immediately.
Each key can also carry a retention window: set it and reports filed through that key are deleted, media and all, once they pass it. It is off by default and off means keep forever, so nothing disappears unless you ask for it. It applies only to that key’s reports — your own recordings are never touched by it.
What the visitor sees
- A short form: what went wrong, in their words.
- A priming screen telling them the browser is about to ask what to share, and to pick This Tab. Screen recording always requires the browser's own permission dialog — we cannot and would not bypass it.
- The panel collapses to a small pill (timer, stop, cancel) so they can actually reproduce the problem.
- A mandatory review step. They watch it back, optionally leave an email, and tick a consent line before anything is sent. Nobody sends you a recording of their desktop by accident.
The evidence that travels with a report
The widget is already on the page when something breaks, so a report does not arrive as a video and a guess. Alongside the recording we send a small event log: uncaught JavaScript errors and unhandled promise rejections, failed fetch and XMLHttpRequestcalls with their method, path, status and duration, and the browser, OS, viewport, locale and timezone. That is what turns “the button did nothing” into POST /api/cart returned 500 at 0:14.
It is held in memory only — capped at the most recent 100 errors and 100 failed requests, discarded when the page unloads, and transmitted only if a visitor completes a report and presses Send. Nothing is collected from people who never click. We keep the error message and the request path; never request bodies, never headers, never form values, and never query strings.
Duplicate reports
When several visitors hit the same bug you get one Inbox row marked ×5, not five videos. Reports are grouped only when they share a page path and are close in meaning, so “Pay now does nothing” and “Cannot pay — I get a red error” collapse together while unrelated complaints stay apart. The threshold is deliberately tight: wrongly merging two bugs would hide one of them, and that costs more than a duplicate row.
What we store
- The recording, and the title the visitor typed.
- The page path — query strings and fragments are stripped before storage, so tokens in URLs never reach us.
- Browser, OS and viewport, derived from the request.
- A truncated hash of IP + user agent, used only for rate limiting. We never store the raw IP.
- The reporter's email, only if they typed one. It never becomes an account.
For your visitors' data you are the controller and we are the processor. Recordings live in the EU (europe-west1) for every customer. See Privacy and Security.
Limits
A report is capped at 2 minutes and 200 MB, and there are per-visitor and per-site ceilings so a bad day on your site cannot run up an unbounded bill. If you go over your plan's analysis quota we still accept the report and tell you — a visitor's bug report is never silently dropped, and your billing state is never shown to them.
Browser support
Desktop Chrome, Edge, Firefox and other Chromium browsers record the tab directly. Screen recording does not exist on iOS Safari and is effectively absent on Android, so on phones the widget asks the visitor to record with their own device’s screen recorder and pick the file instead — same report, same review step before anything is sent. Annotated screenshots are still on the roadmap.