Why users abandon bug reports
A typical feedback form asks the user to describe the problem in words. Most don't. They can't see the console, they don't know their viewport size, and writing out steps takes effort. The result: you hear about maybe one in fifty real problems, each with just enough detail to be unusable.
Console errors
The actual stack trace is already sitting in the user's browser. Capturing it removes the single hardest part of debugging remotely.
Context
User agent, viewport, language, timestamp, page URL. Collected automatically instead of guessed over email.
Screenshot
One picture replaces ten back-and-forth messages about "the thing that looks weird".
The three-second version
Bugbottle is an open-source (MIT) JavaScript library that does exactly this. Drop it on any page:
<script type="module">
import {
initConsoleBuffer, getConsoleBuffer,
collectContext, captureScreenshot
} from 'https://cdn.jsdelivr.net/npm/bugbottle/dist/index.js';
initConsoleBuffer(); // start capturing console errors now
document.getElementById('report-btn').addEventListener('click', async () => {
let screenshotDataUrl;
if (document.getElementById('include-shot').checked) {
screenshotDataUrl = await captureScreenshot();
}
const res = await fetch('/api/bug-reports', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: 'User clicked report',
screenshotDataUrl,
console: getConsoleBuffer(),
context: collectContext(),
})
});
});
</script>
The library is dependency-free and ships as plain ESM, so it works straight from jsDelivr — no bundler, no npm install for your visitors, nothing to compile.
"But I don't have a backend"
You have three realistic options, all of them free at hobby scale:
1. A Worker or Function
Cloudflare Workers, Vercel functions or Netlify functions accept a POST and store the JSON anywhere — KV, R2, a database table. Bugbottle ships a matching server-side validator (bugbottle/server) so you reject malformed payloads in three lines.
2. A form service
Any endpoint that accepts JSON POSTs can receive a report — Formspree, Basin, or your own Google Apps Script web app. Validate before storing.
3. GitHub Actions
The bugbottle-action (mahope/bugbottle-action@v1) validates collected reports inside CI — useful when reports are exported as files in your repo.
See it working end to end: the live bugbottle demo runs the real library from jsDelivr against a real endpoint. Submit a report, then watch it arrive with type, message, console entries and context attached.
Privacy: what not to collect
Bug reports are personal data under GDPR the moment they can identify someone. Keep the footprint small:
Collect: error messages, stack traces, page URL, viewport size, browser family, language.
Skip by default: IP addresses, cookies, form contents, full DOM snapshots. If you screenshot, remember the visible screen may contain the user's own data — let them preview and delete before sending.
Mention the collection in your privacy policy under the same section as analytics. It is one sentence: "Users may submit voluntary error reports containing technical diagnostics."
Frequently asked questions
Does this work on WordPress / Shopify / Webflow sites?
Yes — anything where you can add a custom HTML block or edit the footer template. The library is platform-agnostic plain ESM.
How big is it?
A few kilobytes minified, zero dependencies. It loads lazily when the report button is used, not on page load.
Screenshots of every visit?
No — only when the user actively submits a report, and you choose whether to request one. Nothing is captured passively.
Can I self-host everything?
Yes. MIT licensed, host the dist files yourself and point the import at your own CDN if you don't want third-party requests.
Keeping websites online? DeskUptime is a free desktop uptime & SSL-expiry monitor for macOS, Linux and Windows.
Dansk version: Tilføj en fejlrapport-formular til enhver hjemmeside