SupportShot
Shadow-DOM Bug Report Widget With Privacy-Scoped Capture
Jul 2026
Bug-report widget shipped as one IIFE in a shadow root, with no host dependencies and privacy-scoped capture.
A single-script bug-report widget that runs isolated inside any host page, paired with a Next.js app that ingests tickets and emails them to recipients who never need an account.
Visit SupportShotOverview
SupportShot is a bug-report widget dropped into any website with a single script tag. A visitor describes the problem and annotates a screenshot, and the resulting ticket carries the last 200 console entries and JS errors, failed network requests, the page URL, and browser, OS, and viewport, enough to reproduce the bug without a back-and-forth.
My Role
I designed, built, shipped, and run SupportShot end to end: the embeddable widget, the ingest API, the dashboard, billing, and ticket email delivery.
Architecture
- A monorepo split between the widget and the app that receives its output.
- The widget is built with tsup into a single IIFE with no SDK and no dependency on the host page, rendered inside a shadow root.
- A Next.js app serves the marketing site, docs, dashboard, ingest API, billing, and a mail outbox that emails tickets to one or more recipients.
- Postgres stores projects and tickets behind the ingest API.
Key Engineering Decisions
- Shadow-root isolation. The widget runs inside someone else’s page, so a shadow root stops host styles reaching it and its own styles leaking out, without depending on anything already loaded.
- Start error capture when the script begins executing. The widget loads asynchronously so it never blocks render, so capture begins before initialization finishes, otherwise early errors would be lost.
- Mail outbox with no recipient account. The flow from click to inbox has to hold up with zero setup on either end, so receiving a ticket needs no signup.
Reliability & Security
- Capture is deliberately scoped: screenshots cover the visible page only, and request bodies, headers, cookies, and keystrokes are never touched.