UNPKG

@triagly/sdk

Version:

JavaScript SDK for Triagly - Turn user feedback into GitHub issues instantly

452 lines (341 loc) 11.6 kB
# @triagly/sdk > JavaScript SDK for Triagly - Turn user feedback into GitHub issues instantly. Lightweight (<10KB gzipped) browser widget that captures user feedback with screenshots and automatically creates GitHub issues. ## Features - 🎨 **Beautiful UI Widget** - Clean, customizable feedback form - 📸 **Screenshot Capture** - Automatic page screenshots (with html2canvas) - 🐛 **Console Log Capture** - Automatically captures browser console errors and warnings for debugging - 🤖 **Bot Protection** - Cloudflare Turnstile integration to prevent spam - 🔒 **Secure Authentication** - Uses publishable keys with optional hardened mode - 📊 **Metadata Collection** - Browser, URL, viewport info automatically captured - 🔐 **Privacy & Security** - Auto-sanitizes sensitive data (tokens, passwords, emails) - ⚡ **Lightweight** - Minimal bundle size, no heavy dependencies - 🎯 **TypeScript** - Full type definitions included ## Installation ### NPM ```bash npm install @triagly/sdk # or pnpm add @triagly/sdk # or yarn add @triagly/sdk ``` ### CDN ```html <!-- Include Cloudflare Turnstile for bot protection --> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <!-- Include html2canvas for screenshot support (optional) --> <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> <!-- Include Triagly SDK --> <script src="https://unpkg.com/@triagly/sdk/dist/index.min.js"></script> ``` ## Quick Start ### Method 1: Simple Mode (Recommended for most users) ```typescript import Triagly from '@triagly/sdk'; const triagly = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', }); ``` ### Method 2: Hardened Mode (For sensitive applications) ```typescript import Triagly from '@triagly/sdk'; const triagly = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', getToken: async () => { // Call your backend to get a hardened token const res = await fetch('/api/triagly-token', { method: 'POST', headers: { Authorization: `Bearer ${userSessionToken}` } }); const { token } = await res.json(); return token; } }); ``` ### Method 3: Auto-initialization (CDN) ```html <script> window.TriaglyConfig = { publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', }; </script> <script src="https://unpkg.com/@triagly/sdk/dist/index.min.js"></script> ``` ### Method 4: React Example ```tsx import { useEffect, useRef } from 'react'; import Triagly from '@triagly/sdk'; function App() { const triaglyRef = useRef<Triagly | null>(null); useEffect(() => { triaglyRef.current = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', onSuccess: (feedbackId) => { console.log('Feedback submitted:', feedbackId); }, onError: (error) => { console.error('Feedback error:', error); }, onOpen: () => { console.log('Widget opened'); }, onClose: () => { console.log('Widget closed'); }, }); return () => { triaglyRef.current?.destroy(); }; }, []); return <div>Your App</div>; } ``` ## Configuration ```typescript interface TriaglyConfig { // Required publishableKey: string; // Your Triagly publishable key // Optional - Authentication getToken?: () => Promise<string>; // Callback for hardened mode turnstileSiteKey?: string; // Cloudflare Turnstile site key (required for bot protection) // Optional - API Configuration apiUrl?: string; // Custom API URL (defaults to production) // Optional - UI Customization theme?: 'light' | 'dark' | 'auto'; position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'; buttonShape?: 'rounded' | 'circular' | 'square' | 'pill'; // Default: "rounded" buttonText?: string; // Default: "🐛 Feedback" placeholderText?: string; // Default: "Describe what happened..." successMessage?: string; errorMessage?: string; // Optional - Callbacks onSuccess?: (feedbackId: string) => void; // Called after successful submission onError?: (error: Error) => void; // Called on submission error onOpen?: () => void; // Called when widget opens onClose?: () => void; // Called when widget closes // Optional - Console Log Capture captureConsole?: boolean; // Enable console log capture (default: true) consoleLogLimit?: number; // Max logs to keep (default: 50) consoleLogLevels?: ('error' | 'warn' | 'log')[]; // Which levels to capture (default: ['error', 'warn']) // Optional - Custom Metadata metadata?: Record<string, any>; // Additional metadata to include } ``` ## API ### Constructor ```typescript const triagly = new Triagly(config: TriaglyConfig); ``` ### Methods #### `open()` Programmatically open the feedback widget. ```typescript triagly.open(); ``` #### `close()` Programmatically close the feedback widget. ```typescript triagly.close(); ``` #### `submit(data)` Submit feedback programmatically without UI. ```typescript await triagly.submit({ title: 'Bug: Login button not working', description: 'When I click the login button, nothing happens.', reporterEmail: 'user@example.com', tags: ['bug', 'login'], }); ``` #### `destroy()` Remove the widget and clean up event listeners. ```typescript triagly.destroy(); ``` ## Examples ### Custom Button Trigger ```html <button id="custom-feedback-btn">Report Issue</button> <script> const triagly = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', }); document.getElementById('custom-feedback-btn').onclick = () => { triagly.open(); }; </script> ``` ### With Custom Metadata ```typescript const triagly = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', metadata: { appVersion: '1.2.3', environment: 'production', userId: 'user-123', }, }); ``` ### Programmatic Submission ```typescript const triagly = new Triagly({ publishableKey: 'pub_live_abc123', turnstileSiteKey: 'your-turnstile-site-key', }); // Submit without opening widget try { await triagly.submit({ title: 'Feature Request', description: 'It would be great to have dark mode.', reporterEmail: 'user@example.com', tags: ['feature-request'], }); console.log('Feedback sent!'); } catch (error) { console.error('Failed:', error); } ``` ### Using Pre-built Themes ```html <!-- Dark theme --> <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/dark.css"> <!-- Minimal theme --> <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/minimal.css"> <!-- Gradient theme --> <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/gradient.css"> <!-- Ocean theme --> <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/ocean.css"> ``` ### Custom Styling with CSS Variables ```css :root { /* Customize colors easily */ --triagly-button-bg: #ff0066; --triagly-button-bg-hover: #cc0052; --triagly-modal-bg: #ffffff; --triagly-modal-radius: 20px; --triagly-btn-primary-bg: #ff0066; } ``` See [Styling Guide](./docs/guides/STYLING.md) for all available variables and more examples. ## Screenshot Support To enable screenshot capture, include html2canvas: ```html <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> ``` Or install via NPM and import in your bundle: ```bash npm install html2canvas ``` ```typescript import html2canvas from 'html2canvas'; (window as any).html2canvas = html2canvas; ``` ## Console Log Capture The SDK automatically captures browser console messages (errors and warnings by default) to help developers debug issues. ### How It Works - Intercepts `console.error`, `console.warn`, and optionally `console.log` - Stores the last 50 messages in a circular buffer - Includes stack traces for errors - Automatically sanitizes sensitive data (tokens, passwords, emails) - Sends logs with feedback submissions ### Example Captured Logs When a user reports "Login doesn't work", the SDK automatically includes: ``` [14:30:15] ❌ ERROR: TypeError: Cannot read property 'submit' of undefined at LoginForm.handleSubmit (login.js:42:15) [14:30:10] ⚠️ WARN: Deprecated API used: oldAuthMethod() [14:30:08] ❌ ERROR: Network request failed: POST /api/auth/login ``` ### Privacy & Sanitization The SDK automatically sanitizes: - API keys and tokens (e.g., `token=***`) - Passwords (e.g., `password=***`) - Email addresses (e.g., `***@***.com`) - JWT tokens (e.g., `jwt.***`) - Credit card numbers - GitHub tokens ### Disable Console Capture ```typescript const triagly = new Triagly({ projectId: 'your-project-id', apiUrl: 'https://your-api.com', captureConsole: false, // Disable console capture }); ``` ### Customize Console Capture ```typescript const triagly = new Triagly({ projectId: 'your-project-id', apiUrl: 'https://your-api.com', captureConsole: true, consoleLogLimit: 100, // Keep last 100 logs consoleLogLevels: ['error'], // Only capture errors }); ``` ## Rate Limiting The SDK automatically rate-limits submissions to 3 per 5 minutes per user (stored in localStorage). ## Migration Guide ### Upgrading from v0.0.x to v0.1.0 This release introduces **breaking changes** for improved security and bot protection. #### What Changed 1. **`projectId` → `publishableKey`** - Old: `projectId: 'uuid-here'` - New: `publishableKey: 'pub_live_abc123'` 2. **`apiUrl` is now optional** - The SDK now defaults to the production API - Only set this if using a custom deployment 3. **Turnstile bot protection** - Add `turnstileSiteKey` to your config - Include the Turnstile script in your HTML #### Migration Steps **Before:** ```typescript const triagly = new Triagly({ projectId: 'your-project-id', apiUrl: 'https://your-project.supabase.co/functions/v1', }); ``` **After:** ```typescript const triagly = new Triagly({ publishableKey: 'pub_live_abc123', // Get from dashboard turnstileSiteKey: 'your-turnstile-site-key', // Get from Cloudflare }); ``` **Don't forget to add Turnstile:** ```html <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> ``` #### Backward Compatibility The SDK maintains backward compatibility with `projectId` for now, but will show a deprecation warning. Update to `publishableKey` as soon as possible. ## Browser Support - Chrome/Edge (latest 2 versions) - Firefox (latest 2 versions) - Safari (latest 2 versions) ## Development ```bash # Install dependencies pnpm install # Build pnpm build # Watch mode pnpm dev ``` ## Documentation - [Accessibility Guide](./docs/guides/ACCESSIBILITY.md) - WCAG 2.1 AA compliance & keyboard navigation - [Callbacks Guide](./docs/guides/CALLBACKS.md) - Complete callback documentation - [Console Capture Guide](./docs/guides/CONSOLE_CAPTURE.md) - Automatic console log capture - [Styling Guide](./docs/guides/STYLING.md) - Customize button and modal styles - [Local Testing Guide](./docs/guides/TEST_LOCALLY.md) - Test the package locally - [Contributing Guide](./docs/contributing/CONTRIBUTING.md) - Contribution guidelines - [Release Guide](./docs/contributing/RELEASE_GUIDE.md) - How to create releases ## License MIT