Welcome to BugerZ
BugerZ is a zero-dependency JavaScript widget that you can drop into any site to collect bug reports complete with
- Full-page screenshots
- Console logs & runtime events
- Custom metadata & user context
- Instant API delivery
1. Quick Setup
Include the client script and initialize with your publicKey:
<script src="https://cdn.jsdelivr.net/gh/msj121/bugerz@main/bugerz.min.js"></script>
<script>
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
addButton: true
});
</script>
Alternative urls:
https://msj121.github.io/bugerz/bugerz.min.js
Non-minified urls:
https://cdn.jsdelivr.net/gh/msj121/bugerz@main/bugerz.js
https://msj121.github.io/bugerz/bugerz.js
This injects the “Report Bug” button in the corner of the page.
2. Custom Button
You can create your own button to trigger the BugerZ form, for example with Tailwind css:
<button id="bugButton" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded">Report Bug</button>
<div id="bugButton" class="group py-1 px-1.5 mr-4 border border-black rounded-full hover:bg-gray-300 cursor-pointer">
<svg fill="#000000" height="20" width="20" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" >
<path d="M498.667,290.667H404V240c0-1.016,0.313-2.036,0.291-3.055C452.4,231.927,480,200.272,480,148.333v-12 c0-7.364-5.971-13.333-13.333-13.333s-13.333,5.969-13.333,13.333v12c0,38.399-17.005,58.821-51.885,62.167 c-6.069-27.025-20.875-50.381-45.537-55.7c-3.745-28.54-21.413-52.689-46.115-65.227c10.321-10.501,16.871-24.887,16.871-40.74V37 c0-7.364-5.971-13.333-13.333-13.333S300,29.636,300,37v11.833C300,66.203,285.536,80,268.167,80h-23 c-17.369,0-31.833-13.797-31.833-31.167V37c0-7.364-5.971-13.333-13.333-13.333S186.667,29.636,186.667,37v11.833 c0,15.853,6.549,30.239,16.871,40.741c-24.701,12.537-42.453,36.687-46.199,65.227c-24.695,5.324-39.465,28.736-45.519,55.808 c-35.759-2.96-53.153-23.403-53.153-62.276v-12c0-7.364-5.971-13.333-13.333-13.333S32,128.969,32,136.333v12 c0,52.415,27.439,84.168,76.375,88.739C108.353,238.048,108,239.025,108,240v50.667H13.333C5.971,290.667,0,296.636,0,304 s5.971,13.333,13.333,13.333H108v23c0,10.628,1.469,20.993,3.608,30.992C60.659,374.777,32,406.773,32,460.333v12 c0,7.364,5.971,13.333,13.333,13.333s13.333-5.969,13.333-13.333v-12c0-41.795,20.151-62.291,61.565-62.649 c22.451,53.208,75.151,90.649,136.435,90.649c61.276,0,113.971-37.432,136.425-90.629c40.519,0.784,60.241,21.283,60.241,62.629 v12c0,7.364,5.971,13.333,13.333,13.333S480,479.697,480,472.333v-12c0-53.1-28.823-85.013-78.96-88.921 c2.151-10.025,2.96-20.421,2.96-31.079v-23h94.667c7.363,0,13.333-5.969,13.333-13.333S506.029,290.667,498.667,290.667z M242.667,460.855c-60.333-6.964-108-58.353-108-120.521V240c0-20.793,6.948-50.531,24.483-58.035 c6.627,18.368,24.56,31.368,45.184,31.368h38.333V460.855z M204.333,186.667c-11.58,0-21-9.42-21-21c0-32.532,26.468-59,59-59 h2.833h23H271c32.532,0,59,26.468,59,59c0,11.58-9.42,21-21,21H204.333z M377.333,340.333c0,62.627-47.027,114.32-108,120.673 V213.333H309c20.624,0,37.891-13,44.517-31.368c17.535,7.504,23.816,37.241,23.816,58.035V340.333z"/> </path>
</svg>
</div>
Then use JavaScript to toggle the form:
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
addButton: false, // Disable default button
});
document.getElementById('bugButton').addEventListener('click', () => {
window.BugerZ.toggle();
});
That allows you to place the button anywhere on your page and for it to be fully customized.
3. Customization
For basic css customization, see below how to override these defaults under cssVars:
'--bz-bg': '#ffffff',
'--bz-color': '#333333',
'--bz-border': '#e0e0e0',
'--bz-radius': '8px',
'--bz-zindex': '10000',
'--bz-font': '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',
'--bz-anti-primary': '#ffffff', // contrast color for text on primary buttons
'--bz-primary': '#4F46E5',
'--bz-success': '#10B981',
'--bz-error': '#EF4444',
'--bz-overlay': 'rgba(0, 0, 0, 0.5)'
For basic screenshot modifications here are the current defaults:
screenshotOptions: {
type: 'jpeg', // 'png' or 'jpeg'
quality: 0.5, // only for jpeg: 0.0–1.0
pixelRatio: 0.5, // scale down to 50% resolution (for both png/jpeg)
skipFonts: true, // skip font embedding to avoid CORS issues
cacheBust: false, // disable cache busting for better performance
imagePlaceholder: undefined, // optional: transparent placeholder for failed images
filter: undefined // optional: function(node) => boolean to exclude problematic nodes
// width: 800, // you can also force an explicit width (only jpg)
// height: 600
},
filterCrossOrigin: false // quick flag to auto-filter cross-origin resources
🛡️ Handling CORS Issues with Screenshots
If your website includes images, iframes, or stylesheets from external domains, you may encounter CORS (Cross-Origin Resource Sharing) errors during screenshot capture. BugerZ provides multiple solutions:
Solution 1: Quick Auto-Filter (Recommended for Most)
Set filterCrossOrigin: true to automatically exclude cross-origin resources:
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
screenshot: true,
filterCrossOrigin: true // Auto-exclude cross-origin images/iframes/stylesheets
});
This will exclude images, iframes, and stylesheets from external domains.
Solution 2: Custom Filter Function (Advanced Control)
For fine-grained control, provide a custom filter function:
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
screenshot: true,
screenshotOptions: {
type: 'jpeg',
quality: 0.3,
pixelRatio: 0.3,
skipFonts: true,
cacheBust: false,
// Custom filter to control what gets included
filter: (node) => {
// Skip external images and iframes that cause CORS issues
if (node.tagName === 'IMG' || node.tagName === 'IFRAME') {
const src = node.src || (node.getAttribute && node.getAttribute('src')) || '';
// Skip if it's a cross-origin resource (not same origin or data URI)
if (src && !src.startsWith('data:') &&
!src.startsWith(window.location.origin) &&
!src.startsWith('/')) {
return false; // exclude this node
}
}
// Skip external stylesheets
if (node.tagName === 'LINK' && node.rel === 'stylesheet') {
const href = node.href || '';
if (href && !href.startsWith(window.location.origin) &&
!href.startsWith('/')) {
return false;
}
}
// You can add custom logic here for other elements
// For example, skip elements with a specific class:
// if (node.classList && node.classList.contains('no-screenshot')) {
// return false;
// }
return true; // include all other nodes
}
}
});
Solution 3: Use Image Placeholder
Replace problematic images with a transparent placeholder:
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
screenshot: true,
screenshotOptions: {
type: 'jpeg',
quality: 0.3,
pixelRatio: 0.3,
skipFonts: true,
// Use a transparent 1x1 pixel PNG as placeholder
imagePlaceholder: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
}
});
When Should You Use These Options?
- Use
filterCrossOrigin: truewhen your site has external images/iframes and you're getting CORS errors - Use custom
filterwhen you need precise control over what's captured (e.g., exclude specific elements by class) - Use
imagePlaceholderwhen you want to keep the layout but replace problematic images with a placeholder - Use
skipFonts: true(default) to avoid font-related CORS issues with Google Fonts or other CDN fonts
⚠️ Note
These options help avoid CORS errors, but excluded elements won't appear in screenshots.
If you need full screenshots including external resources, you'll need to either:
1. Set up CORS headers on the external domains (if you control them)
2. Proxy the external resources through your own domain
3. Accept partial screenshots with these filters enabled
You can override any of the core defaults:
| Option | Type | Default | Description |
|---|---|---|---|
publicKey |
String (required) | — | Your project’s API public key. |
endpoint |
String | 'https://bugerz.com/api/report' |
Custom API URL to POST reports to. |
placement |
String | 'bottom-right' |
Button corner:
'bottom-right', 'bottom-left',
'top-right', 'top-left'
|
addButton |
Boolean | true |
Show the “Report Bug” toggle button. |
buttonText |
String | 'Report Bug' |
Label for the toggle button. |
openOnInit |
Boolean | false |
Open form immediately on init. |
autoSendOnError |
Boolean | false |
If true, any console.error(...) will queue an automatic report. |
autoSendLimit |
Number | 5 |
Max auto-sent reports per session before supression (to stop overflowing your issues). |
autoSendDelay |
Number | 1000 |
Debounce window (ms) between auto‑reports, so that if an error occurs and 500ms later another error occurs, just send the latter report. |
autoSendMaxDebounceCount |
Number | 3 |
If "autoSendDelay" keeps causing no report to be sent, because every 500ms there is a new error and the debounce, resets the timer, this will stop that loop after 3 times (default) and send the current report. |
trackConsole |
Boolean | true |
Capture console logs. |
consoleBufferSize |
Number | 100 |
Max log entries to keep. |
trackEvents |
Boolean | false |
Capture user clicks/keys. |
eventBufferSize |
Number | 100 |
Max event entries to keep. |
allowPublicSubmission |
Boolean | false |
Whether anyone can submit without auth. |
showPublicCheckbox |
Boolean | false |
Show “Make public” toggle. |
showEmailField |
Boolean | true |
Show user email input. |
screenshot |
Boolean | true |
Capture a page screenshot. |
screenshotLibUrl |
String | 'https://unpkg.com/html-to-image…' |
html-to-image bundle URL. |
formContainerSelector |
String|null | null |
Selector for custom container. |
filterCrossOrigin |
Boolean | false |
Auto-exclude cross-origin images, iframes, and stylesheets to avoid CORS errors. |
screenshotOptions |
Object | — see defaults above | Fine‑tune type, quality, ratio, and CORS handling. Includes: type, quality, pixelRatio, skipFonts, cacheBust, imagePlaceholder, filter function. |
cssVars |
Object | — see defaults above | Custom CSS variables for theming. |
onSuccess |
Function | (res) => … | Callback on successful report. There is a default green popup that reports the user. To override this you should check the non-minified javascript and alter to match your desired code. |
onError |
Function | (err) => … | Callback on failure. There is a default red popup that reports the user. To override this you should check the non-minified javascript and alter to match your desired code. |
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
placement: 'bottom-right',
addButton: true,
openOnInit: false,
autoSendOnError: true,
autoSendLimit: 10,
autoSendDelay: 2000,
autoSendMaxDebounceCount: 5,
trackConsole: true,
consoleBufferSize: 100,
trackEvents: false,
eventBufferSize: 100,
allowPublicSubmission: false,
showPublicCheckbox: false,
showEmailField: true,
screenshot: true,
screenshotLibUrl: 'https://unpkg.com/html-to-image@1.9.1/dist/html-to-image.min.js',
formContainerSelector: null,
screenshotOptions: { //you can override these defaults as per html-to-image code - see their library for more details
type: 'image/png',
ratio: 0.5
},
cssVars: {
'--bz-bg': '#ffffff',
'--bz-color': '#333333',
'--bz-border': '#e0e0e0',
'--bz-radius': '8px',
'--bz-zindex': '10000',
'--bz-font': '"Segoe UI", Tahoma, Geneva, Verdana, sans-serif',
'--bz-anti-primary': '#ffffff', // contrast color for text on primary buttons
'--bz-primary': '#4F46E5',
'--bz-success': '#10B981',
'--bz-error': '#EF4444',
'--bz-overlay': 'rgba(0, 0, 0, 0.5)'
},
onSuccess: res => {
console.log('Report submitted successfully:', res);
// Custom success handling here
},
onError: err => {
console.error('Report submission failed:', err);
// Custom error handling here
}
});
4. API Reference
BugerZ.init(options)- Initialize widget and merge
optionswith defaults, see customization above. BugerZ.show()- Programmatically show the report form.
BugerZ.hide()- Hide the form and overlay.
BugerZ.toggle()- Toggle visibility. If visible will hide and vice versa.
5. Examples
Auto open when started
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
openOnInit: true
});
Handle CORS Issues with External Images (Simple)
// Quick solution: automatically filter cross-origin resources
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
screenshot: true,
filterCrossOrigin: true // One-liner solution!
});
Handle CORS Issues with Custom Control
// Advanced: full control with custom filter and placeholder
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
addButton: true,
screenshot: true,
screenshotOptions: {
type: 'jpeg',
quality: 0.3,
pixelRatio: 0.3,
skipFonts: true,
cacheBust: false,
// Transparent placeholder for cross-origin images that fail
imagePlaceholder: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',
// Filter to exclude problematic cross-origin elements
filter: (node) => {
// Skip external images and iframes
if (node.tagName === 'IMG' || node.tagName === 'IFRAME') {
const src = node.src || (node.getAttribute && node.getAttribute('src')) || '';
if (src && !src.startsWith('data:') &&
!src.startsWith(window.location.origin) &&
!src.startsWith('/')) {
return false;
}
}
// Skip external stylesheets
if (node.tagName === 'LINK' && node.rel === 'stylesheet') {
const href = node.href || '';
if (href && !href.startsWith(window.location.origin) &&
!href.startsWith('/')) {
return false;
}
}
// Skip elements with specific class
if (node.classList && node.classList.contains('no-screenshot')) {
return false;
}
return true;
}
}
});
Optimize for Performance and File Size
// Aggressive optimization for large pages
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
screenshot: true,
screenshotOptions: {
type: 'jpeg',
quality: 0.2, // Lower quality = smaller file
pixelRatio: 0.25, // 25% resolution
skipFonts: true,
cacheBust: false
},
filterCrossOrigin: true
});
Auto-Report Errors with Screenshots
// Automatically capture and report console errors
window.BugerZ.init({
publicKey: 'YOUR_PUBLIC_KEY',
addButton: true,
autoSendOnError: true,
autoSendLimit: 10,
autoSendDelay: 2000,
screenshot: true,
filterCrossOrigin: true, // Avoid CORS issues on auto-reports
screenshotOptions: {
type: 'jpeg',
quality: 0.3,
pixelRatio: 0.3
}
});
6. FAQ
I am getting issues uploading screenshots
Make sure you have https site, and that you descale the size of the images. Sometimes images captured can be too large.
I'm getting CORS errors when taking screenshots
This is a common issue when your website includes images, iframes, or stylesheets from external domains (like CDNs, social media embeds, ads, etc.). The browser blocks html-to-image from accessing these cross-origin resources for security reasons.
Quick Fix: Set filterCrossOrigin: true in your init options. This automatically excludes problematic external resources.
Advanced Fix: Use a custom filter function in screenshotOptions for precise control over what gets included/excluded. See the "Handling CORS Issues" section above for examples.
Note: Filtered elements won't appear in screenshots. If you need them included, you'll need to proxy those resources through your own domain or set up CORS headers on the external domain (if you control it).
Include a link to my public issues
Yes, by including a reference with project_id, "https://buggerz.com/issues?project_id=1", which you can get from your issues page and select the project from the dropdown - check url or click link button, or go to project management and get link by clicking chain link button.
What do users see?
Public issues or shared via link users cannot see: screencapture, author email, ip address, machine info, events, logs, additional custom data.
Can I self-host client file?
Yes—grab the script from GitHub and host it on your own server.
How large is the bundle?
~15 KB & mininified ~11kb.
Can I modify the code?
Yes, the key compoennt of our code is that it hits our api to upload the saved variables. We only require that if using our code you are our client. You can modify the code to suit your needs, but please keep in mind that we are not responsible for any issues that may arise from custom modifications.
Can I use BugerZ on a static site?
Yes, BugerZ works on any static HTML page. Just include the script and initialize with your public key.
How do I report bugs?
Click the “Report Bug” button, fill out the form, and submit. You can also use the API to send reports programmatically.
Do my users need to type anything to get a report?
set autoSendOnError: true (and tune autoSendLimit, autoSendDelay, etc.) in your init call. Now any errors to console will cause Bugerz to keep a record. Note: to not be overwhelmed, you shouldn't expect any errors, so when they happen and you are alerted, you know these must be taken care of.
7. Changelog
| Version | Date | Highlights |
|---|---|---|
| v1.3.0 | 2025-10-22 | Added CORS handling: filterCrossOrigin flag, custom filter function support, imagePlaceholder, skipFonts, and cacheBust options for screenshots. Comprehensive CORS documentation added. |
| v1.2.0 | 2025-07-20 | Beta release, made cssVars available to be modified |
| v1.1.0 | 2025-05-10 | Introduced trackEvents option |
| v1.0.0 | 2025-01-15 | Initial alpha release |