bichito

Widget

The embeddable script your end users see. What it does, what it ships, and how the API key is treated.

The widget is a single <script> tag. It renders a floating "Report a bug" button, opens a modal when clicked, posts the report to your honeycomb's inbox, and optionally lets the user attach an image.

Install

<script
  src="https://bichito-api.fly.dev/widget.js"
  data-key="sk_your_project_key"
  async
></script>

That's it — no SDK to install, no build step. The data-key is your project's publishable API key (more on what that means in Transparency below).

For framework-specific snippets (Next.js, React, Vue, Astro, WordPress), use the Onboarding → Install step inside the dashboard — it generates the right one with your key already filled in.

Image attachments

The widget always lets the user attach one image per report, up to 2 MB. Allowed types: PNG, JPEG, WEBP.

The user clicks "Attach image", picks a file from their device, and sees a preview before submitting. They can also paste an image with Ctrl+V while the modal is open. There is no setting to enlarge the cap, lower it, or disable it — same contract on every plan.

If you want the widget to also offer a "Capture screen" button that screenshots the current page (uses html2canvas, ~50 KB lazy-loaded), opt in:

<script
  src="https://bichito-api.fly.dev/widget.js"
  data-key="sk_your_project_key"
  data-screenshots="true"
  async
></script>

The 2 MB cap applies to screen captures too — html2canvas downscales the page to fit on most viewports, but on very dense screens you may want to omit the option.

Configuration

All knobs are data-* attributes on the <script> tag.

AttributeDefaultEffect
data-keyRequired. Your project's API key. Starts with sk_.
data-positionbottom-rightLauncher button position. One of bottom-right, bottom-left, top-right, top-left.
data-buttontrueSet to false to hide the floating button (open the modal yourself via window.BugWidget.open()).
data-show-emailtrueShow the email field on the form.
data-require-emailfalseMake the email field required.
data-langauto-detectForce es or en. Auto-detects from navigator.language.
data-screenshotsfalseAdd a "Capture screen" button alongside the file picker.

CSS variables let you re-skin without forking — see the theming section.

Theming

The widget ships its own styles inside a Shadow DOM, so it can't break your CSS and your CSS can't break it. To customize, set CSS variables on :root (they're inherited into the Shadow DOM):

:root {
  --bugw-primary: oklch(0.78 0.17 75);     /* launcher + submit button */
  --bugw-primary-hover: oklch(0.74 0.18 70);
  --bugw-radius: 18px;                      /* modal corner radius */
  --bugw-launcher-radius: 999px;            /* round launcher */
  --bugw-z-index: 2147483000;               /* float above your modals */
}

Full list of variables in the widget.js source.

Transparency

Is the sk_ key in my HTML a security risk?

No — and we want to be upfront about why.

The widget runs inside your end-user's browser, so the sk_… key has to ship to the browser. Anyone visiting your site can read it from DevTools → Network. We treat it the way Stripe treats pk_… keys or Sentry treats DSNs: publishable by design, not secret.

What that means in practice:

  • The key only grants the right to POST a bug report for the project it belongs to. It cannot read other reports, see your dashboard, change project settings, or touch other projects.
  • It is rate-limited to 60 reports / minute / key (rate-limits doc) so a leaked key cannot be used to DDoS your inbox.
  • Free plans are additionally capped at 100 reports / month.
  • Image uploads go through a presigned URL flow, gated server-side by the same key, with the 2 MB hardcoded cap mentioned above.
  • If you ever suspect a key is being abused, rotate it from your honeycomb's Settings → Additional API keys (the old key stops working immediately).

What we don't do

  • We don't try to "hide" the key by minifying or obfuscating it. That gives a false sense of security.
  • We don't gate POST behind a server-side proxy — that would make the widget useless for static-site embedders and add a hop without changing the security model.

When env vars are still a good idea

Even though the key is publishable, storing it in an env var (NEXT_PUBLIC_BICHITO_KEY, VITE_BICHITO_KEY, etc.) and templating it into your snippet is good hygiene: a leaked source repo doesn't leak the key, and you can rotate without touching code. We recommend it where your framework supports it. For pure HTML / WordPress / static sites with no build step, inlining the key is fine.

Calling the widget from JS

The script exposes a tiny global once it loads:

window.BugWidget.open();   // open the modal programmatically
window.BugWidget.close();  // close it
window.BugWidget.identify({
  user_id: "user_123",     // anything that helps you find this user
  email: "you@example.com" // pre-fills + saves you asking
});

If you set data-button="false", you get no floating button and you're expected to call open() from your own UI (e.g. a "Report a problem" link in your footer).

Branding

On the Free plan the modal shows a small "Powered by bichito" link in the footer. Pro projects hide it automatically — no data-* flag to toggle, the widget reads your project's plan from /api/v1/widget/info on init and decides for itself. The badge stays hidden on errors too, so if the bootstrap call fails (offline, blocked) Pro customers never see a stray badge.

On this page