Package Exports
- @kamyarme/ticketing-widget
- @kamyarme/ticketing-widget/dist/index.esm.js
- @kamyarme/ticketing-widget/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@kamyarme/ticketing-widget) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@kamyarme/ticketing-widget
A beautiful, production-ready bug reporting and feedback widget for React applications
Capture bugs, feature requests, and user feedback with automatic console log capture and Linear integration.
✨ Features
- 🎯 Zero Configuration - Works out of the box with minimal setup
- 📝 Smart Console Capture - Automatically captures console logs, warnings, and errors (last 100 messages)
- 🔐 Secure & Licensed - License-based activation with backend validation
- 📸 File Attachments - Upload screenshots, images, and documents (up to 10MB)
- 🔗 Linear Integration - Automatically creates issues in your Linear workspace
- 💾 MongoDB Storage - All tickets stored securely in your database
- 🌐 Rich Context - Captures URL, user token, browser info, screen size, and timestamp
- 🎨 Fully Customizable - Light/dark themes, custom positioning, and custom styles
- 🌍 Internationalization - Built-in support for English and Persian (Farsi)
- ⚡ Lightweight - Small bundle size with tree-shaking support
- 📱 Responsive - Works perfectly on desktop, tablet, and mobile
- ♿ Accessible - Keyboard navigation and screen reader support
- 🔲 Host-modal compatible - Ticket modal works on top of your app’s own modals (portaled, focus-trapped, high z-index); see MODAL_PORTAL.md
📦 Installation
npm install @kamyarme/ticketing-widget
# or
yarn add @kamyarme/ticketing-widget
# or
pnpm add @kamyarme/ticketing-widgetRequirements:
- React 17.0.0 or higher
- React DOM 17.0.0 or higher
🚀 Quick Start
1. Add the Widget to Your App
import React from 'react';
import { TicketingWidget } from '@kamyarme/ticketing-widget';
function App() {
return (
<div>
<h1>Your Application</h1>
<TicketingWidget
apiUrl="https://your-api.example.com"
licenseKey="your-license-key-here"
/>
</div>
);
}
export default App;2. Set Up the Backend
You'll need a backend server to handle tickets. See Backend Setup section below.
🎯 Demo
📹 Coming soon: Live demo and screenshots
📚 API Reference
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
apiUrl |
string |
✅ Yes | - | URL of your ticketing API server |
licenseKey |
string |
✅ Yes | - | Your license key (get one from backend) |
getUserToken |
() => string | null |
⬜ No | undefined |
Function to retrieve user's auth token for user identification |
position |
'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' |
⬜ No | 'bottom-right' |
Position of the floating widget button |
theme |
'light' | 'dark' |
⬜ No | 'light' |
Color theme for the widget |
customStyles |
React.CSSProperties |
⬜ No | {} |
Custom CSS styles for the floating button |
Type Definitions
interface TicketingWidgetProps {
apiUrl: string;
licenseKey: string;
getUserToken?: () => string | null;
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
theme?: 'light' | 'dark';
customStyles?: React.CSSProperties;
}💡 Examples
Basic Usage
import { TicketingWidget } from '@kamyarme/ticketing-widget';
function App() {
return (
<>
<YourApp />
<TicketingWidget
apiUrl="https://api.example.com"
licenseKey="lic_1234567890abcdef"
/>
</>
);
}With User Authentication
Track which users report issues by providing their auth token:
import { TicketingWidget } from '@kamyarme/ticketing-widget';
function App() {
return (
<TicketingWidget
apiUrl="https://api.example.com"
licenseKey="lic_1234567890abcdef"
getUserToken={() => {
// Return the user's authentication token
return localStorage.getItem('authToken');
// or from your auth context/state
// return user?.token;
}}
/>
);
}Custom Positioning
Place the widget button wherever you want:
<TicketingWidget
apiUrl="https://api.example.com"
licenseKey="lic_1234567890abcdef"
position="top-left" // Options: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
/>Dark Theme
Perfect for dark-mode applications:
<TicketingWidget
apiUrl="https://api.example.com"
licenseKey="lic_1234567890abcdef"
theme="dark"
/>Custom Button Styles
Customize the floating button to match your brand:
<TicketingWidget
apiUrl="https://api.example.com"
licenseKey="lic_1234567890abcdef"
customStyles={{
backgroundColor: '#ff6b6b',
width: '70px',
height: '70px',
borderRadius: '35px',
boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
}}
/>Complete Example with Next.js
// app/layout.tsx or pages/_app.tsx
import { TicketingWidget } from '@kamyarme/ticketing-widget';
import { useAuth } from '@/hooks/useAuth';
export default function RootLayout({ children }) {
const { user } = useAuth();
return (
<html>
<body>
{children}
<TicketingWidget
apiUrl={process.env.NEXT_PUBLIC_API_URL}
licenseKey={process.env.NEXT_PUBLIC_TICKETING_LICENSE}
getUserToken={() => user?.accessToken || null}
theme="dark"
position="bottom-right"
/>
</body>
</html>
);
}📊 What Gets Captured?
When a user submits a ticket, the widget automatically captures comprehensive debugging information:
| Data | Description |
|---|---|
| 📝 Console Logs | Last 100 console messages (log, warn, error, info) with timestamps |
| 🌐 Current URL | The exact page where the issue occurred |
| 👤 User Token | User authentication token (if getUserToken is provided) |
| 💻 User Agent | Browser, OS, and device information |
| 📱 Screen Size | Current viewport dimensions (width × height) |
| ⏰ Timestamp | Exact date and time of submission |
| ⚠️ Error Stack Traces | Full stack traces for JavaScript errors |
| 📄 Description | User-provided title and detailed description |
| 🖼️ Files | User-uploaded screenshots and attachments |
All data is sent securely to your backend and stored in MongoDB.
🔧 Backend Setup
This widget requires a backend server to process tickets. Here's how to set it up:
Option 1: Using the Official Backend Package
We provide a ready-to-use backend built with Hono.js and MongoDB:
# Clone or download the backend
git clone https://github.com/yourusername/ticketing.git
cd ticketing/packages/api
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Edit .env with your configuration
# Run the server
npm startRequired Environment Variables:
# MongoDB
MONGODB_URI=mongodb://localhost:27017/ticketing
# JWT Secret
JWT_SECRET=your-super-secret-key
# Linear Integration (optional)
LINEAR_API_KEY=lin_api_xxxxxxxxxxxxx
# Server
PORT=3000Option 2: Custom Backend
The widget makes a POST request to /api/tickets endpoint. Here's the expected request format:
Endpoint: POST /api/tickets
Headers:
Content-Type: multipart/form-dataBody:
{
licenseKey: string; // License key for validation
subject: string; // Ticket title
description: string; // Detailed description
url: string; // Current page URL
userToken?: string; // Optional user auth token
userAgent: string; // Browser info
screenSize: {
width: number;
height: number;
};
consoleLogs: Array<{
level: 'log' | 'warn' | 'error' | 'info';
message: string;
timestamp: string;
}>;
files?: File[]; // Optional file attachments
}Response: 200 OK
{
"success": true,
"ticketId": "ticket-id-here",
"linearIssueId": "optional-linear-issue-id"
}🔑 Getting a License Key
License keys are required to use this widget and are validated on your backend.
For Development
Generate a test license key from your backend admin panel or using the CLI tool.
For Production
- Set up the backend server
- Access the admin panel (typically at
https://your-api.com/admin) - Create a new license:
- Enter project name
- Set expiration date (optional)
- Configure Linear integration (optional)
- Generate license key
The license key format: lic_ followed by 20 random characters
Example: lic_a1b2c3d4e5f6g7h8i9j0
🎨 Styling & Customization
Using Tailwind CSS
The widget works great with Tailwind CSS:
<div className="relative">
<TicketingWidget
apiUrl={apiUrl}
licenseKey={licenseKey}
customStyles={{
backgroundColor: 'rgb(59 130 246)', // Tailwind blue-500
}}
/>
</div>CSS Variables
You can also customize using CSS variables (not yet implemented, but coming soon):
:root {
--ticketing-widget-primary: #3b82f6;
--ticketing-widget-radius: 12px;
}🌍 Internationalization
The widget automatically detects the user's language and displays text accordingly.
Supported Languages:
- 🇬🇧 English (default)
- 🇮🇷 Persian (Farsi)
The widget detects browser language automatically. You can contribute more languages by submitting a PR!
🐛 Troubleshooting
Widget not showing up?
- Make sure you've added the component to your app
- Check browser console for errors
- Verify your
apiUrlandlicenseKeyare correct - Ensure your backend server is running
License validation failed?
- Verify the license key is correct
- Check that your backend server is accessible
- Make sure the license hasn't expired
- Check backend logs for validation errors
Files not uploading?
- Check file size (max 10MB per file)
- Verify backend has proper file upload configuration
- Check backend storage permissions
- Review network tab in browser DevTools
Console logs not capturing?
Console capture is automatic and requires no configuration. If logs aren't appearing:
- Make sure errors actually occurred
- Check browser console for the widget's own errors
- Verify the widget loaded before the logs you want to capture
📖 Advanced Topics
TypeScript Support
This package includes full TypeScript definitions:
import { TicketingWidget, TicketingWidgetProps } from '@kamyarme/ticketing-widget';
const config: TicketingWidgetProps = {
apiUrl: 'https://api.example.com',
licenseKey: 'lic_xxx',
theme: 'dark',
position: 'bottom-left',
};
<TicketingWidget {...config} />SSR (Server-Side Rendering)
The widget is designed to work with SSR frameworks like Next.js:
'use client'; // Next.js 13+ app directory
import { TicketingWidget } from '@kamyarme/ticketing-widget';
export default function TicketingWrapper() {
return <TicketingWidget {...props} />;
}Performance Optimization
The widget is lazy-loaded and won't impact your initial page load:
- Bundle size: ~50KB gzipped
- No external dependencies (except React & Axios)
- Console capture has minimal performance impact
- Tree-shakable ES modules
🤝 Contributing
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Development Setup:
git clone https://github.com/yourusername/ticketing.git
cd ticketing/packages/react-widget
npm install
npm run dev📄 License
Copyright © 2025 Kamyar Pouretesam
This software is provided under a commercial license. See LICENSE file for details.
Key Points:
- ✅ Free to use with a valid license key
- ✅ Can be used in commercial projects
- ❌ Cannot redistribute or resell this package
- ❌ Cannot remove license validation
💬 Support
Need help? We're here for you:
- 📧 Email: services@kamyar.me
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📚 Docs: Full Documentation
🙏 Acknowledgments
Made with ❤️ by Kamyar Pouretesam