https://github.com/zudsniper/bugs
a bug reporter for reactjs that autoreports (with lots of diagnostic info) to linear/gh issues/etc
https://github.com/zudsniper/bugs
Last synced: 5 months ago
JSON representation
a bug reporter for reactjs that autoreports (with lots of diagnostic info) to linear/gh issues/etc
- Host: GitHub
- URL: https://github.com/zudsniper/bugs
- Owner: zudsniper
- License: mit
- Created: 2025-08-24T07:25:01.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2025-08-24T07:51:32.000Z (10 months ago)
- Last Synced: 2025-08-24T14:27:56.349Z (10 months ago)
- Language: TypeScript
- Size: 73.2 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# 🐛 @zudsniper/bugs
A comprehensive, standalone bug reporter widget for React and Next.js applications with screenshot capture, console logging, and multiple integration options.

## ✨ Features
- **📸 Screenshot Capture** - Automatic screenshot with privacy controls
- **📝 Console Log Capture** - Automatic console log collection with filtering
- **🌐 Network Request Monitoring** - Track API calls and network issues
- **🔗 Multiple Integrations** - GitHub Issues, Linear, Jira, Slack, Discord, webhooks, and email
- **🎨 Customizable UI** - Themes, positioning, and custom styling
- **📱 Responsive Design** - Mobile-friendly interface
- **🔐 Privacy First** - Configurable data redaction and exclusions
- **⌨️ Keyboard Shortcuts** - Customizable hotkeys
- **📁 File Upload Support** - Drag & drop, paste, and click to upload
- **🔄 TypeScript Support** - Full type safety and IntelliSense
## 🚀 Quick Start
### Installation
```bash
# npm
npm install @zudsniper/bugs
# yarn
yarn add @zudsniper/bugs
# pnpm
pnpm add @zudsniper/bugs
```
### Basic Usage
> ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
import { BugReporter, defaultConfigs } from '@zudsniper/bugs';
import '@zudsniper/bugs/styles';
function App() {
const config = defaultConfigs.github('owner/repo', 'github-token');
return (
My App
);
}
```
That's it! Your users can now report bugs by clicking the floating bug icon.
## 📖 Documentation
### Configuration
The bug reporter is highly configurable through the `BugReporterConfig` object:
> ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
import { BugReporter, mergeConfigs, defaultConfigs } from '@zudsniper/bugs';
const config = mergeConfigs(
defaultConfigs.github('owner/repo', 'token'),
{
ui: {
title: 'Report a Bug',
theme: 'auto',
position: 'bottom-right',
primaryColor: '#3b82f6'
},
capture: {
captureScreenshot: true,
maxConsoleLogs: 50,
maxNetworkRequests: 25
},
validation: {
requireTitle: true,
requireDescription: true,
requireEmail: false
}
}
);
```
### Integrations
#### GitHub Issues
> ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
const config = defaultConfigs.github('owner/repository', 'github-token');
// Or with custom configuration
const config = {
integrations: {
github: {
repo: 'owner/repository',
token: 'github-token',
labels: ['bug', 'user-report'],
assignees: ['developer-username'],
milestone: 'v1.0'
}
}
};
```
#### Linear
> ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
const config = defaultConfigs.linear('linear-api-key', 'team-id');
// Or with custom configuration
const config = {
integrations: {
linear: {
apiKey: 'linear-api-key',
teamId: 'team-id',
projectId: 'project-id',
priority: 2, // High priority
labels: ['bug', 'user-feedback']
}
}
};
```
#### Slack
```tsx
const config = defaultConfigs.slack('https://hooks.slack.com/your/webhook');
// Or with custom configuration
const config = {
integrations: {
slack: {
webhook: 'https://hooks.slack.com/your/webhook',
channel: '#bugs',
username: 'Bug Reporter',
iconEmoji: ':bug:'
}
}
};
```
#### Custom Webhook
> ⚠️ **SECURITY WARNING**: The examples below show API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
const config = defaultConfigs.webhook('https://your-api.com/bug-reports');
// Or with authentication
const config = {
integrations: {
webhook: {
url: 'https://your-api.com/bug-reports',
method: 'POST',
headers: {
'Authorization': 'Bearer your-token',
'X-App-Version': '1.0.0'
},
auth: {
type: 'bearer',
token: 'your-auth-token'
}
}
}
};
```
### Custom Trigger
Replace the default floating button with your own trigger:
```tsx
function CustomTrigger({ onClick }) {
return (
🐛 Report Issue
);
}
```
### Privacy Controls
Protect sensitive information:
```tsx
const config = {
privacy: {
excludeSelectors: [
'[data-private]',
'.password-field',
'.credit-card-input'
],
redactPatterns: [
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, // emails
/\b\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\b/g // credit cards
],
anonymizeUrls: true,
allowScreenshots: true,
allowConsoleLogs: false // Disable console logs for privacy
}
};
```
### Keyboard Shortcuts
```tsx
const config = {
keyboard: {
openShortcut: ['ctrl', 'shift', 'b'],
closeShortcut: ['escape'],
submitShortcut: ['ctrl', 'enter']
}
};
```
### Custom Fields
Add custom form fields:
```tsx
const config = {
ui: {
fields: [
{
type: 'text',
key: 'title',
label: 'Issue Title',
required: true
},
{
type: 'select',
key: 'severity',
label: 'Severity',
options: [
{ value: 'low', label: 'Low' },
{ value: 'medium', label: 'Medium' },
{ value: 'high', label: 'High' },
{ value: 'critical', label: 'Critical' }
],
required: true
},
{
type: 'textarea',
key: 'description',
label: 'Description',
placeholder: 'Describe the issue...',
required: true
},
{
type: 'email',
key: 'userEmail',
label: 'Email (optional)',
validation: {
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
}
}
]
}
};
```
## 🎨 Styling and Theming
### Built-in Themes
```tsx
const config = {
ui: {
theme: 'light', // 'light', 'dark', or 'auto'
primaryColor: '#3b82f6'
}
};
```
### Custom CSS
Override default styles using CSS variables:
```css
:root {
--br-color-primary: #your-primary-color;
--br-color-secondary: #your-secondary-color;
--br-border-radius: 8px;
}
/* Custom styling */
.br-popup-container {
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.br-floating-button {
background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
}
```
### Custom Styles Object
```tsx
const config = {
ui: {
customStyles: {
'--br-color-primary': '#9333ea',
'--br-color-secondary': '#7c3aed',
'--br-border-radius': '12px'
}
}
};
```
## 📱 Framework Examples
### Next.js App Router
> ⚠️ **SECURITY WARNING**: The example below uses `NEXT_PUBLIC_*` environment variables which expose values to the client-side code. **This is insecure for production**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
'use client';
import { BugReporter, defaultConfigs } from '@zudsniper/bugs';
import '@zudsniper/bugs/styles';
export default function Layout({ children }) {
const config = defaultConfigs.github('owner/repo', process.env.NEXT_PUBLIC_GITHUB_TOKEN);
return (
{children}
);
}
```
### Next.js Pages Router
> ⚠️ **SECURITY WARNING**: The example below uses `NEXT_PUBLIC_*` environment variables which expose values to the client-side code. **This is insecure for production**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
// pages/_app.tsx
import { BugReporter, defaultConfigs } from '@zudsniper/bugs';
import '@zudsniper/bugs/styles';
export default function MyApp({ Component, pageProps }) {
const config = defaultConfigs.linear(
process.env.NEXT_PUBLIC_LINEAR_API_KEY,
process.env.NEXT_PUBLIC_LINEAR_TEAM_ID
);
return (
<>
>
);
}
```
### Vite + React
```tsx
// main.tsx
import { BugReporter, defaultConfigs } from '@zudsniper/bugs';
import '@zudsniper/bugs/styles';
const config = defaultConfigs.webhook('https://your-api.com/bug-reports');
ReactDOM.render(
,
document.getElementById('root')
);
```
### Vanilla JavaScript (CDN)
```html
Your app content
const { BugReporter, defaultConfigs } = window.ZudsniperBugs;
const config = defaultConfigs.slack('https://hooks.slack.com/your/webhook');
const container = document.createElement('div');
document.body.appendChild(container);
ReactDOM.render(
React.createElement(BugReporter, { config }),
container
);
```
## 🔧 Advanced Usage
### Multiple Integrations
Send reports to multiple services simultaneously:
> ⚠️ **SECURITY WARNING**: The example below shows API keys/tokens directly in code for demonstration purposes only. **Never expose sensitive credentials in frontend code**. For production applications, use the secure [proxy mode configuration](#🛡️-security-best-practices) instead.
```tsx
const config = {
integrations: {
github: {
repo: 'owner/repo',
token: 'github-token'
},
slack: {
webhook: 'https://hooks.slack.com/webhook'
},
webhook: {
url: 'https://your-analytics.com/bug-reports'
}
}
};
```
### Event Handlers
```tsx
{
console.log('Bug report submitted:', response);
// Analytics tracking
gtag('event', 'bug_report_submitted', {
issue_id: response.issueId
});
}}
onSubmitError={(error) => {
console.error('Submission failed:', error);
// Error tracking
Sentry.captureException(error);
}}
onOpen={() => {
console.log('Bug reporter opened');
}}
onClose={() => {
console.log('Bug reporter closed');
}}
/>
```
### Data Transformation
Modify report data before submission:
```tsx
const config = {
advanced: {
transformData: (data) => {
return {
...data,
// Add custom metadata
environment: process.env.NODE_ENV,
version: process.env.REACT_APP_VERSION,
userId: getCurrentUserId(),
// Remove sensitive information
consoleLogs: data.consoleLogs.filter(log =>
!log.message.includes('password')
)
};
}
}
};
```
### File Upload Configuration
```tsx
const config = {
validation: {
maxFileSize: 10 * 1024 * 1024, // 10MB
maxFiles: 5,
allowedFileTypes: [
'image/', // All image types
'text/plain',
'application/pdf',
'.log', // By extension
'.json'
]
}
};
```
## 🛡️ Security Best Practices
⚠️ **CRITICAL SECURITY WARNING**: Never expose API keys, tokens, or sensitive credentials in your frontend code. Always use server-side proxy endpoints for secure integrations.
### Recommended: Proxy Mode (Secure)
For production applications, use proxy mode where API keys stay on your server:
```tsx
// Secure configuration - API keys stay on server
const config = {
integrations: {
github: {
mode: 'proxy',
endpoint: '/api/bug-report/github'
},
linear: {
mode: 'proxy',
endpoint: '/api/bug-report/linear'
}
}
};
```
### Direct Mode (Development Only)
⚠️ Only use direct mode for development/testing with non-production tokens:
```tsx
// NOT recommended for production - tokens exposed to client
const config = {
integrations: {
github: {
mode: 'direct', // or omit mode (defaults to direct)
repo: 'owner/repo',
token: 'github_token' // ⚠️ Exposed to client!
}
}
};
```
### Backend API Routes
Create server-side API routes that handle the actual integration calls. Examples for Next.js:
#### GitHub Issues API Route
```typescript
// app/api/bug-report/github/route.ts
import { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
try {
const bugData = await request.json();
// Your GitHub token stays secure on the server
const response = await fetch(`https://api.github.com/repos/${process.env.GITHUB_REPO}/issues`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: bugData.title || 'Bug Report',
body: formatBugReport(bugData),
labels: ['bug', 'user-report']
})
});
const issue = await response.json();
return Response.json({
success: true,
issueId: issue.number.toString(),
issueUrl: issue.html_url
});
} catch (error) {
return Response.json({ success: false, error: 'Failed to create issue' }, { status: 500 });
}
}
function formatBugReport(data: any): string {
// Format your bug report data as needed
return `## Description\n${data.description}\n\n## Environment\n- URL: ${data.url}\n- User Agent: ${data.userAgent}`;
}
```
#### Linear API Route
```typescript
// app/api/bug-report/linear/route.ts
import { NextRequest } from 'next/server';
export async function POST(request: NextRequest) {
try {
const bugData = await request.json();
const mutation = `
mutation IssueCreate($input: IssueCreateInput!) {
issueCreate(input: $input) {
success
issue { id identifier title url }
}
}
`;
const response = await fetch('https://api.linear.app/graphql', {
method: 'POST',
headers: {
'Authorization': process.env.LINEAR_API_KEY!, // Secure on server
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: mutation,
variables: {
input: {
title: bugData.title || 'Bug Report',
description: formatLinearReport(bugData),
teamId: process.env.LINEAR_TEAM_ID!,
priority: 3
}
}
})
});
const result = await response.json();
const issue = result.data?.issueCreate?.issue;
return Response.json({
success: true,
issueId: issue.identifier,
issueUrl: issue.url
});
} catch (error) {
return Response.json({ success: false, error: 'Failed to create Linear issue' }, { status: 500 });
}
}
```
### Environment Variables (Server-Side)
```bash
# .env.local (server-side only)
GITHUB_TOKEN=github_pat_...
GITHUB_REPO=owner/repo
LINEAR_API_KEY=lin_api_...
LINEAR_TEAM_ID=team_id
```
### Data Sanitization
The bug reporter automatically:
- Redacts sensitive URL parameters
- Excludes elements marked with `data-private`
- Sanitizes console log arguments
- Filters network request headers
- Removes sensitive patterns from logs
### Additional Security Measures
- Always validate and sanitize data on your backend
- Implement rate limiting on your API routes
- Use HTTPS for all endpoints
- Validate API tokens server-side
- Log security events for monitoring
- Consider implementing CSRF protection
## 🎯 Performance
### Bundle Size
- Core library: ~45KB gzipped
- With all integrations: ~65KB gzipped
- Tree-shakable: Only includes used integrations
### Optimization Tips
```tsx
// Lazy load for better performance
const BugReporter = lazy(() => import('@zudsniper/bugs'));
function App() {
return (
);
}
```
## 🐛 Troubleshooting
### Common Issues
#### Screenshots not capturing
```tsx
// Ensure html2canvas peer dependency is installed
npm install html2canvas
// Or disable screenshots
const config = {
capture: {
captureScreenshot: false
}
};
```
#### Network requests not captured
```tsx
// Make sure capture is started before requests
const config = {
capture: {
maxNetworkRequests: 50 // Increase limit
}
};
```
#### Integration not working
```tsx
// Validate configuration
import { validationManager } from '@zudsniper/bugs';
const validation = validationManager.validateConfig(config);
if (!validation.isValid) {
console.error('Config errors:', validation.errors);
}
```
### Debug Mode
```tsx
const config = {
advanced: {
customLogger: (level, message, data) => {
console.log(`[BugReporter:${level}] ${message}`, data);
}
}
};
```
## 🤝 Contributing
We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
### Development Setup
```bash
# Clone the repository
git clone https://github.com/your-username/bug-reporter-popup.git
# Install dependencies
cd bug-reporter-popup
npm install
# Start development
npm run dev
# Run tests
npm test
# Build for production
npm run build
```
## 📄 License
MIT License - see [LICENSE](LICENSE) file for details.
## 🙏 Acknowledgments
- [html2canvas](https://html2canvas.hertzen.com/) for screenshot functionality
- [Framer Motion](https://www.framer.com/motion/) for smooth animations
- [Lucide React](https://lucide.dev/) for beautiful icons
## 📊 Stats




---
Made with ❤️ for better user feedback