npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kamyarme/ticketing-widget

v1.2.2

Published

React widget for bug reporting and feedback with Linear integration

Downloads

220

Readme

@kamyarme/ticketing-widget

npm version npm downloads license

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.

DemoInstallationDocumentationExamples


✨ 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

📦 Installation

npm install @kamyarme/ticketing-widget
# or
yarn add @kamyarme/ticketing-widget
# or
pnpm add @kamyarme/ticketing-widget

Requirements:

  • 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 start

Required 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=3000

Option 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-data

Body:

{
  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

  1. Set up the backend server
  2. Access the admin panel (typically at https://your-api.com/admin)
  3. 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?

  1. Make sure you've added the component to your app
  2. Check browser console for errors
  3. Verify your apiUrl and licenseKey are correct
  4. Ensure your backend server is running

License validation failed?

  1. Verify the license key is correct
  2. Check that your backend server is accessible
  3. Make sure the license hasn't expired
  4. Check backend logs for validation errors

Files not uploading?

  1. Check file size (max 10MB per file)
  2. Verify backend has proper file upload configuration
  3. Check backend storage permissions
  4. Review network tab in browser DevTools

Console logs not capturing?

Console capture is automatic and requires no configuration. If logs aren't appearing:

  1. Make sure errors actually occurred
  2. Check browser console for the widget's own errors
  3. 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:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. 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:


🙏 Acknowledgments

  • Built with React
  • Powered by Axios
  • Integrated with Linear
  • UI inspired by modern design principles

Made with ❤️ by Kamyar Pouretesam

⭐ Star on GitHub📦 View on npm🐛 Report Bug