Lightweight embeddable bug reporting widget for SaaS applications. Captures screenshots, console logs, network requests, and system information.
npm install saasbox-bug-reporterA lightweight, embeddable JavaScript widget that helps SaaS customers report bugs easily. The widget captures screenshots, console logs, network activity, and system information automatically.
- ✅ Flexible Screenshot Capture - Full viewport or area selection mode
- ✅ Interactive Annotation Tools - Add arrows, text, and freehand drawings to screenshots
- ✅ Undo/Redo Functionality - Full history management for annotations
- ✅ Color Selection - Multiple colors for annotations (red, green, blue)
- ✅ Console Log Collection - Captures the last 50 console logs
- ✅ Network Request Monitoring - Tracks the last 20 network requests
- ✅ System Information - Collects browser, OS, and device details
- ✅ Simple Text Description - Users can describe the issue
- ✅ Lightweight - Under 57KB minified (83% smaller than before!)
- ✅ Cross-Browser Compatible - Works on Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
- ✅ Easy Installation - Just add two script tags
Add these two lines to your HTML, just before the closing
tag:
``html`
Alternative CDNs:
`html`
Version Options:
- @1.0.1 - Specific version (recommended for production)@1.0
- - Latest patch version (auto-updates 1.0.x)@1
- - Latest minor version (auto-updates 1.x.x)@latest
- - Always latest version (not recommended for production)
`bash`
npm install saasbox-bug-reporter
`javascript
import BugReporter from 'saasbox-bug-reporter';
BugReporter.init({
apiEndpoint: 'https://saasbox.app/api/bug-reports', // or your self-hosted api endpoint
saasBoxKey: 'YOUR_SAASBOX_KEY',
saasBoxSecret: 'YOUR_SAASBOX_SECRET'
});
`
#### Next.js Applications
Option 1: Using Script Component (Recommended for Next.js 13+ App Router)
`typescript
// components/BugReporter.tsx
'use client';
import Script from 'next/script';
declare global {
interface Window {
BugReporter?: {
init: (config: {
apiEndpoint: string;
saasBoxKey: string;
saasBoxSecret: string;
screenshotMode?: string;
position?: string;
offsetX?: number;
offsetY?: number;
buttonSize?: number;
buttonShape?: string;
buttonIcon?: string;
buttonColor?: string;
buttonShadow?: string;
buttonIconColor?: string;
modalTitle?: string;
modalHeaderColor?: string;
modalHeaderTextColor?: string;
modalBodyColor?: string;
modalBodyTextColor?: string;
modalPrimaryColor?: string;
modalDescriptionLabel?: string;
modalDescriptionPlaceholder?: string;
modalDescriptionTextColor?: string;
modalDescriptionPlaceholderColor?: string;
modalSubmitText?: string;
modalCancelText?: string;
modalSubmitButtonColor?: string;
modalCancelButtonColor?: string;
buttonShadowHover?: string;
modalBorderColor?: string;
modalDisabledButtonColor?: string;
modalCancelButtonBackground?: string;
messageBackgroundColor?: string;
messageTextColor?: string;
messageBorderColor?: string;
messageInfoBackground?: string;
messageInfoText?: string;
messageInfoBorder?: string;
messageErrorBackground?: string;
messageErrorText?: string;
messageErrorBorder?: string;
messageSuccessBackground?: string;
messageSuccessText?: string;
messageSuccessBorder?: string;
selectionOverlayColor?: string;
selectionBorderColor?: string;
selectionInfoBackground?: string;
selectionInfoText?: string;
overlayColor?: string;
toolbarBackgroundColor?: string;
toolbarButtonBackground?: string;
toolbarButtonColor?: string;
toolbarButtonHoverBackground?: string;
toolbarButtonActiveBackground?: string;
toolbarButtonDisabledBackground?: string;
toolbarButtonActiveShadow?: string;
colorButtonBackground?: string;
colorButtonBorder?: string;
colorButtonHoverBorder?: string;
colorButtonActiveBorder?: string;
colorButtonActiveShadow?: string;
textAnnotationBackground?: string;
textAnnotationColor?: string;
textAnnotationBorder?: string;
}) => void;
};
}
}
export function BugReporter() {
return (
src="https://unpkg.com/saasbox-bug-reporter@1.0.8/dist/bug-reporter.min.js"
strategy="afterInteractive"
onLoad={() => {
if (typeof window !== 'undefined' && window.BugReporter) {
window.BugReporter.init({
apiEndpoint: ${process.env.NEXT_PUBLIC_SITE_URL}/api/bug-reports,${process.env.NEXT_PUBLIC_SAASBOX_CREDENTIAL_KEY}
saasBoxKey: ,${process.env.NEXT_PUBLIC_SAASBOX_CREDENTIAL_SECRET}
saasBoxSecret: ,`
// Screenshot capture mode
screenshotMode: 'selection',
// Trigger button customization
position: 'bottom-left',
offsetX: 15,
offsetY: 15,
buttonSize: 55,
buttonShape: 'rounded',
buttonIcon: '🐞',
buttonColor: '#f8f2e5',
buttonIconColor: '#000000',
buttonShadow: '0 6px 20px #ed9a56',
buttonShadowHover: '0 8px 25px #ed9a56',
// Modal customization
modalTitle: 'Report a Bug',
modalHeaderColor: '#f8f2e5',
modalHeaderTextColor: '#000000',
modalBodyColor: '#ffffff',
modalBodyTextColor: '#333333',
modalPrimaryColor: '#ed9a56',
modalDescriptionLabel: 'Describe the issue',
modalDescriptionPlaceholder: 'Please tell us what went wrong...',
modalDescriptionTextColor: '#333333',
modalDescriptionPlaceholderColor: '#999999',
modalSubmitText: 'Submit',
modalCancelText: 'Cancel',
modalSubmitButtonColor: '#ffffff',
modalCancelButtonColor: '#6c757d',
// Advanced color customization
modalBorderColor: '#e1e5e9',
modalDisabledButtonColor: '#cccccc',
modalCancelButtonBackground: 'transparent',
messageBackgroundColor: '#f8f9fa',
messageTextColor: '#333',
messageBorderColor: '#dee2e6',
messageInfoBackground: '#d1ecf1',
messageInfoText: '#0c5460',
messageInfoBorder: '#bee5eb',
messageErrorBackground: '#f8d7da',
messageErrorText: '#721c24',
messageErrorBorder: '#f5c6cb',
messageSuccessBackground: '#d4edda',
messageSuccessText: '#155724',
messageSuccessBorder: '#c3e6cb',
// Annotation and selection colors
selectionOverlayColor: 'rgba(0, 0, 0, 0.7)',
selectionBorderColor: '#ed9a56',
selectionInfoBackground: 'rgba(0, 0, 0, 0.8)',
selectionInfoText: 'white',
overlayColor: 'rgba(0, 0, 0, 0.5)',
toolbarBackgroundColor: '#ed9a56',
toolbarButtonBackground: 'rgba(255, 255, 255, 0.2)',
toolbarButtonColor: 'white',
toolbarButtonHoverBackground: 'rgba(255, 255, 255, 0.3)',
toolbarButtonActiveBackground: 'rgba(255, 255, 255, 0.4)',
toolbarButtonDisabledBackground: 'rgba(255, 255, 255, 0.1)',
toolbarButtonActiveShadow: '0 2px 8px rgba(0, 0, 0, 0.2)',
// Color picker and annotation colors
colorButtonBackground: '#ef4444',
colorButtonBorder: 'rgba(255, 255, 255, 0.3)',
colorButtonHoverBorder: 'rgba(255, 255, 255, 0.6)',
colorButtonActiveBorder: '#ffffff',
colorButtonActiveShadow: '0 0 0 2px rgba(255, 255, 255, 0.5)',
textAnnotationBackground: 'rgba(255, 255, 255, 0.8)',
textAnnotationColor: '#ef4444',
textAnnotationBorder: 'transparent'
});
}
}}
/>
);
}
Then import and use it in your layout or page:
`typescript
// app/layout.tsx or app/(root)/layout.tsx
import { BugReporter } from '@/components/BugReporter';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (