SDK reference

Getting started

Install @bugjar/reporter with two script tags — a bugjar:ready handler that calls BugJar.init({...}) with your hooks, and the SDK loader. Every config option documented in one place.

Two script tags in your HTML. Your customers can file consent-gated bug reports.

Install

Drop the snippet from Settings → Projects → Your project → Install into the <head> of any page where bug reporting should be available:

<script>
  window.addEventListener('bugjar:ready', () => {
    BugJar.init({
      // your config + hooks go here
      // onReportSubmitted: (id) => { ... },
      // ui: { position: 'bottom-right' },
    });
  });
</script>
<script src="https://console.bugjar.app/sdk/proj_live_yourkey.js" type="module" async></script>

Two <script> tags: the first registers a handler for the SDK's bugjar:ready event and calls BugJar.init({...}) with your config and hooks; the second loads the SDK from your project's URL. The URL identifies your project, so init() doesn't need a projectKey — the server inlines it ahead of the bundle. The trigger button appears bottom-right of every page where the snippet is loaded.

Ordering: the synchronous inline script registers the listener during HTML parse, before the deferred module SDK script can fire the event. Listener is always registered in time — no race condition.

Changes you make in the dashboard propagate within ~60 seconds on the next page load — no need to re-paste the snippet when you flip a setting.

The SDK ships from BugJar's own origin — no third-party CDN reference in your HTML, no extra origin in your Content-Security-Policy allowlist. Copy the snippet from your dashboard so the project key is pre-filled.

Get your project key

The project key lives in your BugJar dashboard at Settings → Projects → Your project. It looks like proj_live_01kqt7z6f5.... The key is safe to embed client-side — it identifies the project, not the user, and the redaction + presigned-URL flow keeps customer data out of our servers regardless.

Configuration

BugJar.init(config) accepts the following. All fields are optional — projectKey is auto-filled from the inlined window.__BUGJAR_CONFIG__ the dashboard serves alongside the SDK bundle.

Top-level

Option Type Default Notes
projectKey string from inlined config Override only if you need to target a different project from the one this SDK URL was generated for (rare).
user { id, metadata? } none Identifies the end user reporting the bug. Attached to every submission from this session.
userToken string (JWT) none Server-signed JWT identifying the user. Required when the project is in HMAC verification mode. Sign on your backend, never in the browser. See User identity.
strictMode boolean false When true, every redaction category — including the optional ones the dashboard would normally let you relax via capture invitations — is enforced. Use for compliance-critical surfaces.
captureTokenParam string 'bugjar_capture' Query-string parameter name the SDK reads to pick up a capture-invitation token. Rename if it collides with your routing.
onReportSubmitted (reportId: string) => void noop Fires after a successful upload. Useful for analytics, success toasts, or chaining your own UI.
onError (err: Error) => void noop Fires on upload, capture, or token-resolution failures. Errors are also surfaced inside the consent panel; this hook is for your monitoring.

capture — what gets recorded

BugJar.init({
    projectKey: 'proj_live_...',
    capture: {
        maxDurationSec: 90,
        captureNetwork: true,
        captureConsole: true,
        captureMicrophone: true,
        networkBufferSize: 100,
        consoleBufferSize: 500,
    },
});
Option Default Notes
maxDurationSec 90 Hard cap on how long a single recording can run. The user can stop earlier; this is the ceiling.
captureNetwork true Buffer the last N HTTP requests in memory. Headers and bodies pass through the redaction pipeline before joining the manifest.
captureConsole true Buffer the last N console.* calls and unhandled errors. Same redaction pipeline.
captureMicrophone true Offer microphone narration in the consent panel. The user still grants browser permission at record time — this just shows or hides the option.
networkBufferSize 100 Ring-buffer size for network entries. Lower if your app is chatty and you don't need the full window.
consoleBufferSize 500 Ring-buffer size for console entries.

DOM replay (rrweb) and the in-page drawing tool are always on when the user enables them in the consent panel — there are no init flags for those. To exclude specific DOM nodes from replay, mark them with data-bugjar-block (excluded entirely) or data-bugjar-mask (layout kept, content masked). See Redaction for the full list of attributes and the always-mask categories.

ui — trigger appearance and behavior

BugJar.init({
    projectKey: 'proj_live_...',
    ui: {
        position: 'bottom-right',
        primaryColor: '#ea580c',
        showTrigger: true,
        showOnError: false,
        triggerLabel: 'Report a bug',
    },
});
Option Default Notes
position 'bottom-right' One of 'bottom-right', 'bottom-left', 'top-right', 'top-left'.
primaryColor '#ea580c' Any CSS color string. Drives the trigger fill, the consent-panel accent, and the record button.
showTrigger true When false, the SDK doesn't render its built-in pill. You bring your own UI element and call BugJar.open() from your click handler.
showOnError false When true, the trigger stays hidden until the page hits a console.error, an unhandled exception, or a 4xx/5xx response. After that it appears and stays for the rest of the page. Composes with showTrigger: if showTrigger is false, this does nothing.
triggerLabel 'Report a bug' Label inside the built-in trigger. Override to match your product voice ('Send feedback', 'Found something?', etc.).

User identity

Two ways to attach the end user to reports — pick whichever matches your project's verification mode (set in Settings → Projects → Verification).

Open mode — pass user directly:

BugJar.init({
    projectKey: 'proj_live_...',
    user: { id: 'usr_42', metadata: { plan: 'pro', orgId: 'org_8' } },
});

The metadata object is opaque to BugJar — anything JSON-serializable works. Shown alongside the report in the dashboard.

HMAC mode — sign a JWT on your backend, pass userToken:

// Server (any language). HS256, signed with the project's signing_secret.
// Required claims: sub (user id), exp (≤ 1 hour after iat).
// Optional: email, metadata.
const token = jwt.sign({ sub: 'usr_42', email: '[email protected]' }, SIGNING_SECRET, { expiresIn: '1h' });

// Browser
BugJar.init({
    projectKey: 'proj_live_...',
    userToken: token,
});

The SDK forwards the token; the BugJar API verifies the signature and rejects unsigned submissions. Use this whenever you need to prove the report came from the user it claims — support escalation flows, paid-tier gating, anything you'd otherwise need to cross-reference against your auth system.

Custom triggers

If showTrigger: false, drive the SDK from your own UI:

BugJar.init({ projectKey: 'proj_live_...', ui: { showTrigger: false } });

document.querySelector('#my-feedback-button').addEventListener('click', () => {
    BugJar.open();
});

BugJar.close() cancels an in-progress capture. See Customize the trigger for header-menu, hotkey, and contextual-button patterns, or API reference for the complete runtime surface.

What happens next

When the user clicks the trigger:

  1. A consent panel explains what's about to be recorded.
  2. They choose what to capture (replay, microphone, drawing).
  3. They reproduce the bug, narrate, draw — for up to maxDurationSec seconds.
  4. They review the redacted output, then click Send.
  5. Your dashboard pings. The replay is ready.

For redaction details, see Redaction.