Fejlrapporter inde fra din app — med beviserne vedhæftet.

"Gem-knappen gør ingenting" kan man ikke handle på. BugBottle samler det, der faktisk foregik, da nogen lagde mærke til fejlen — siden, viewporten, de seneste console errors, det element de peger på, og eventuelt et screenshot — og sender det som JSON til en route, du allerede ejer. Du tegner formularen; biblioteket klarer indsamlingen.

MIT-licens, ingen runtime-afhængigheder, ingen hosted service. npm install bugbottle

Hvad det gør

Error trackers fanger det, der kaster en exception. De kan ikke fange det, der bare ser forkert ud, og de fortæller sjældent, hvad personen var i gang med. BugBottle står på den anden side: en person siger "det her er forkert", og rapporten kommer med nok kontekst til at reproducere det.

Headless
Du ejer din markup. Biblioteket ejer state, indsamling og afsendelse — som en React hook eller som tre almindelige funktioner, der virker med ethvert framework eller uden.
Dit eget backend
En rapport er en JSON-body på et fetch. Modtageren er en route, du selv skriver; valideringshjælpere til den følger med i samme pakke.
Lille
Kernen cirka 0,8 kB gzippet. Med element picker og React hook 3,9 kB. Det færdige panel 6,9 kB. Alt-i-ét script tag 11,6 kB.
Sender videre
Server-side hjælpere sender en rapport videre til e-mail via Resend, Slack, Discord, en almindelig webhook eller et GitHub issue. Nøglerne bliver på serveren.
Dit sprog, dit brand
Otte sprog med i pakken, alle tekster kan overskrives, og det valgfrie panel styles med en håndfuld CSS-variabler.
Defensiv på serveren
Hvert felt, en browser sender, trimmes, klippes og tjekkes, før det når lageret — inklusive PNG-signatur og størrelse på et screenshot.

Hvad det ikke er: ikke et dashboard, ikke session replay, ikke en hosted service. Vil du have annoterede issues oprettet i Jira af en leverandør, så kig på Marker.io eller Jam. Vil du optage alt, en bruger gør, så kig på rrweb. BugBottle er det mindste, der gør "det virker ikke" til en reproducerbar payload.

Hvem det er til

Teams, der bygger en webapp og vil have en "rapportér et problem"-knap, som giver brugbare rapporter — uden en tredjepartstjeneste, et script fra et fremmed domæne eller endnu en månedlig regning. Det passer til interne værktøjer, SaaS-produkter og kundeprojekter, hvor data skal blive på egen infrastruktur.

Installation og brug

npm install bugbottle
npm install html-to-image   # valgfrit, kun hvis du vil have screenshots

Uden npm: npm install github:mahope/bugbottle#v0.4.0, eller importér de byggede filer fra jsDelivr — dist/ er committet netop til det.

1. Optag console errors, byg så en formular (React)

import { initConsoleBuffer } from "bugbottle";
import { useBugReport } from "bugbottle/react";
import { htmlToImage } from "bugbottle/html-to-image"; // valgfrit

initConsoleBuffer(); // én gang, så tidligt som muligt

function ReportForm() {
  const report = useBugReport({
    endpoint: "/api/feedback",
    screenshot: htmlToImage, // udelad for at slå screenshots fra
  });
  return (
    <form data-bugbottle onSubmit={(e) => { e.preventDefault(); void report.submit(); }}>
      {report.types.map((t) => (
        <button key={t} type="button" onClick={() => report.setType(t)}>{t}</button>
      ))}
      <textarea value={report.message} onChange={(e) => report.setMessage(e.target.value)} />
      <button type="submit" disabled={report.status === "sending"}>Send</button>
    </form>
  );
}

2. Alle andre steder: tre funktioner

import { captureScreenshot, pickElement, buildReport, sendReport } from "bugbottle";
import { htmlToImage } from "bugbottle/html-to-image";

const screenshot = await captureScreenshot(htmlToImage); // PNG data URL
const element = await pickElement();                     // null hvis brugeren trykkede Escape
const report = buildReport({ type: "bug", message, screenshotDataUrl: screenshot, elements: element ? [element] : [] });
const { id } = await sendReport("/api/feedback", report);

Vil du helst ikke bygge en formular? bugbottle/ui monterer en flydende knap og en lille dialog i en shadow root, og dist/bugbottle.js gør det samme fra ét <script>-tag med attributterne data-endpoint, data-locale og data-brand.

3. Modtag den på serveren

import {
  decodeScreenshotDataUrl, InvalidScreenshotError, isReportType,
  normaliseConsole, normaliseContext, normaliseElements, normaliseMessage,
} from "bugbottle/server";

export async function POST(req: Request) {
  const payload = await req.json();
  const message = normaliseMessage(payload.message);
  if (!message) return Response.json({ error: "Skriv en besked først" }, { status: 400 });
  const type = isReportType(payload.type) ? payload.type : "other";
  const context = normaliseContext(payload.context);
  const console = normaliseConsole(payload.console);
  const elements = normaliseElements(payload.elements);
  let screenshot: Uint8Array | null = null;
  try {
    if (payload.screenshotDataUrl) screenshot = decodeScreenshotDataUrl(payload.screenshotDataUrl);
  } catch (err) {
    if (!(err instanceof InvalidScreenshotError)) throw err; // et dårligt billede må ikke fejle rapporten
  }
  const { id } = await save({ type, message, context, console, elements, screenshot });
  return Response.json({ id }, { status: 201 });
}

Virker uændret i en Next.js route handler, Hono, Cloudflare Workers, Bun, Deno eller alt andet bygget på web-Request. Hjælperne beholder de seneste 50 console-linjer og verificerer den rigtige PNG-signatur, før et screenshot når dit lager. Fuld API i README (engelsk).

Bundle-størrelser

  • Kerne (buildReport, sendReport, console buffer)~0,8 kB gzip
  • Kerne + element picker + React hook3,9 kB gzip
  • Færdigt panel (bugbottle/ui)6,9 kB gzip
  • Ét script tag (dist/bugbottle.js)11,6 kB gzip

Pris

Gratis. MIT-licens, ingen hosted komponent, intet at abonnere på. Har du brug for hjælp til at integrere det i et produkt, er det den slags arbejde, mahoje.dk laver.

Spørgsmål

Hvor ender rapporterne?

Dér, hvor dit endpoint lægger dem. BugBottle taler aldrig med en server, der er dets egen. Eksemplet ovenfor gemmer i din database; server-hjælperne kan også sende videre til Slack, Discord, e-mail eller et GitHub issue.

Virker screenshots på alle sider?

Screenshots bruger html-to-image, som tegner DOM'en til et canvas. Cross-origin-billeder uden CORS-headers, visse CSS-features og meget store sider kan give ufuldstændige billeder. Derfor er screenshot valgfrit, og derfor fejler et dårligt screenshot aldrig rapporten.

Hvad med persondata?

Rapporten indeholder det, du vælger at samle: beskeden, URL'en, viewport, user agent, seneste console-linjer, det valgte elements selector og, hvis slået til, et screenshot. Console-linjer og screenshots kan indeholde persondata, så behandl endpointet som ethvert andet sted, hvor brugerinput lander — normalise-hjælperne klipper størrelser, men de redigerer ikke indhold.

Virker det uden React?

Ja. React-hooken er et tyndt lag oven på buildReport og sendReport. Vue, Svelte, ren JavaScript og script-tag-udgaven bruger alle samme kerne.

Er det stabilt?

Nuværende release er 0.4.x. Det bruges i produktion, men det offentlige API kan stadig ændre sig før 1.0. Ændringer står i GitHub releases.

Hvem står bag

BugBottle er bygget af Mads Holst Jensen, selvstændig udvikler i Odense, under navnet mahoje.dk. Det blev trukket ud af et kundeprojekt, hvor "kan du tilføje en rapportér-en-fejl-knap" blev til spørgsmålet om, hvad en fejlrapport egentlig bør indeholde. Issues og pull requests på GitHub.

Læs mere: tilføj en fejlrapport-formular til enhver hjemmeside, bugrapporter i din CI-pipeline.