One preset, safe defaults
const widget = createFeedbackWidget({
project: "acme",
preset: "production", // masking + consent + scrub + dismiss
connectors: [new HttpConnector("/api/feedback", () => session.token)],
identity: { userId: user.id, email: user.email }, // → reporter in artifacts
custom: { plan: user.plan, appVersion: APP_VERSION },
});
const ui = mountFeedbackWidget(widget);
footerLink.onclick = () => ui.show(); // rescue path after dismisspreset: "production" turns on, all at once: input masking in screenshots, a screenshot-consent
checkbox, PII text scrubbing, a dismiss ✕, and forced-off console.warn capture. Every option
can still be overridden explicitly. See the preset table.
What PII protection actually means here
- Screenshots: every input, textarea and select is redacted before the render; anything marked
data-privateis always redacted. The live DOM is untouched — masking happens only in the rendered image. - Text: emails →
[email], long digit runs →[digits], hex/base64 tokens →[token]— across element text, URLs, error messages and the action trail. Dates, versions and stack-trace line numbers survive, so reports stay readable. - The trail records facts, not content: typing is logged as a character count; password fields aren't logged at all; navigation paths drop the query string.
- Collected automatically: URL path, viewport, browser/OS, timezone, color scheme, recent errors. Deliberately not collected: full user agent, IP, cookies, storage, geolocation.
Your infrastructure, not ours
There is no sluglist server. Reports go to connectors you configure — the recommended shape is a ~50-line API route in front of your own storage, holding the credentials server-side. The widget makes no other network requests, and that claim is enforced by an automated test.
It cannot break your app
Everything the widget wraps (fetch, console.error, history) always calls the original;
after repeated internal failures it uninstalls itself and gets out of the way. Undelivered reports
persist in an IndexedDB outbox and retry on the next load.
Real users, real languages
Label bundles ship for English, Russian, Ukrainian, Spanish and German — one line to apply, with correct plural rules. Your own copy (categories, checklist titles, form labels) stays yours. See Localization.
Then what?
A user report is the same artifact a teammate or an agent produces, so it drops straight into the fix loop: pull the session folder into the repo and the agent reads it exactly as if you had clicked it yourself.
Before you ship
Walk the production checklist: env gating, a delivery token, server-side validation, retention, and a privacy-policy paragraph to adapt.