SDK guides
Web SDK
@fixback/sdk is a tiny, self-isolating on-page feedback widget. It mounts a launcher
only when a submission would be accepted, isolates its styles in a Shadow DOM, and — if Fixback
can't be reached — stays completely silent. It never throws into your page.- MIT-licensed and dependency-free.
- Isolated styles — the launcher and overlay each live in a Shadow DOM, so the host page's CSS can't reach in and the SDK's CSS can't leak out.
- Private by default — input values are masked before the screenshot is captured, so private text never leaves the page.
- Two builds — an ESM entry for bundlers and a single minified
<script>file for no-build sites.
Install
No build step — a script tag exposes a Fixback global from any npm CDN:
<script src="https://unpkg.com/@fixback/sdk"></script><script> Fixback.init({ key: "pk_live_your_publishable_key" });</script>With a bundler, import init. It returns a promise resolving to an instance with a destroy() method:
import { init } from "@fixback/sdk";const fixback = await init({ key: "pk_live_…" });// later, to tear the launcher down:fixback.destroy();The launcher
The launcher is a bottom-right Feedback pill, and it stays out of the way:
- Hover-peek & tuck-away — a chevron tucks it off-screen behind a small edge nub; hovering the corner (or the nub) peeks it back. This also covers pointers that can't hover — touch and keyboard.
- First-visit welcome — a one-time toast greets a new visitor, once per publishable key per browser.
- Reduce motion — pass
reduceMotion: trueto still the pulse and transitions; the launcher also honours the visitor's OSprefers-reduced-motionon its own.
All of this chrome lives inside the launcher's Shadow DOM, so it never adds a global style or touches your markup.
The launch event
Activating the launcher opens the SDK's report overlay and dispatches a composed,
bubbling fixback:launch event from the SDK's host element, so your page can react
too:
import { LAUNCH_EVENT } from "@fixback/sdk";document.addEventListener(LAUNCH_EVENT, () => { // the report overlay is opening — react here if you need to});Automatic error capture
The SDK's signature capability: errors report themselves, with no prompt. Two
capture-phase handlers turn uncaught exceptions and unhandled promise rejections into
error-source Feedback (classified Kind = bug server-side) for the current session —
carrying the same masked screenshot and Trace a manual report does. It's on by default; pass autoCapture: false to turn it off.
- Deduped & rate-limited. The same error collapses to one Feedback with a rising occurrence count; a burst limiter and per-session cap keep a runaway loop from flooding the queue, and a
429from ingest backs auto-reporting off. - Gated like a manual report. Auto-capture only runs where a submission would be accepted, so a public visitor's crash is tracked at their server-derived tier — never auto-shipped.
console.erroris not promoted to a report; it stays breadcrumb-only Evidence. - Private by default. Every auto-report passes through the same
beforeSendscrub choke point as a manual one.
Connect — reporting as yourself
A reporter is an Account. The overlay's identity chip shows "Anonymous · Sign in"; clicking it opens the platform's connect page in a popup (a full redirect when it is blocked), the person signs in with Google, GitHub, Apple, or an email magic link, and returns to your page as their Account — the chip then shows their name and tier, and the SDK holds a Reporter session that keeps recognising them on later visits (refreshed on boot, revocable). Nothing about identity is entered in your page, and the tier is always the server's to derive from the Account.
On an Open Project the launcher and chip mount for everyone. On a gated Project nothing is shown to a signed-out visitor — entry is a Fixback-issued
link (which carries a ?fixback= code the SDK exchanges on load) or a call from your
own UI:
import { Fixback } from "@fixback/sdk";// From your own UI — e.g. a "Report a bug" menu item on a gated site:await Fixback.signIn();signIn / signOut / identity are also methods on the instance init returns. Signing out clears the Reporter session.
How the boot gate works
On init, the SDK POSTs to /api/ingest/boot with your key
(the browser attaches the Origin header). The server answers with canSubmit, and the launcher mounts only when that is true. Any non-answer
— an unreachable API, a refused key, an unexpected error — is treated as "don't show the
launcher", silently.