UNPKG

quala-widget

Version:

Smart feedback widget for SaaS trial optimization

449 lines (353 loc) โ€ข 12.3 kB
# ๐Ÿš€ Quala Widget v1.2.0 Turn "it's broken" into actionable debugging intelligence with contextual feedback widgets. ## โœจ What's New in v1.2.0 - **๐ŸŽฏ Conditional Micro Widgets**: Micro widgets only load when enabled for your project - **๐Ÿง  Contextual Intelligence**: Questions and feedback options adapt to trigger type - **๐Ÿ›ก๏ธ Advanced Anti-Spam**: Intelligent widget frequency management - **๐Ÿ“ฑ Enhanced Offline Support**: Queue feedback when offline, sync when online - **๐Ÿ”ง Technical Context Capture**: Automatic collection of errors, device info, and user actions - **โšก Performance Optimized**: Minimal overhead when features aren't enabled - **๐ŸŽจ Trigger-Specific Styling**: Different emoji sets per trigger type ## ๐Ÿ“ฆ Installation ### NPM ```bash npm install quala-widget ``` ### CDN ```html <script src="https://unpkg.com/quala-widget@1.2.0/dist/quala.umd.js"></script> ``` ## ๐Ÿš€ Quick Start ### 1. Initialize the SDK ```javascript import { qualaSdk } from 'quala-widget'; // Initialize with your API key await qualaSdk.initialize('your-api-key', { debug: true, // Enable for development apiBaseUrl: 'https://www.getquala.xyz/api/widget' // Optional custom URL }); ``` ### 2. Identify Users ```javascript // Identify the user to enable feedback await qualaSdk.identifyUser({ userId: 'user-123', email: 'user@company.com', trialStartDate: '2025-01-01' // Optional }); ``` ### 3. Ready! ๐ŸŽ‰ That's it! The SDK will automatically: - โœ… Show regular feedback widgets if configured - โœ… Enable micro widgets if configured for your project - โœ… Set up intelligent triggers based on user behavior - โœ… Capture technical context when issues occur ## ๐ŸŽฃ React Hooks For React applications, use the provided hooks for cleaner integration: ### useQualaInit Hook Initialize Quala in your app component with automatic cleanup: ```tsx import { useQualaInit } from 'quala-widget'; function App() { useQualaInit({ apiKey: 'your-api-key', options: { debug: true, apiBaseUrl: 'https://www.getquala.xyz/api/widget' // Optional } }); return <div>Your App</div>; } ``` ### useQuala Hook Access Quala functionality in any component: ```tsx import { useQuala } from 'quala-widget'; function UserProfile({ userId, email }) { const { identifyUser, trackEvent, triggerSmartFeedback } = useQuala(); useEffect(() => { // Identify user when component mounts identifyUser({ userId, email, trialStartDate: '2025-01-01' }); }, [userId, email]); const handleFeatureUsed = () => { trackEvent('feature_used', { feature: 'user-profile', section: 'settings' }); }; const handleFeedbackRequest = async () => { await triggerSmartFeedback(); }; return ( <div> <button onClick={handleFeatureUsed}>Use Feature</button> <button onClick={handleFeedbackRequest}>Give Feedback</button> </div> ); } ``` ### TypeScript Support Full TypeScript support with proper typing: ```tsx import { useQuala, type QualaUser } from 'quala-widget'; const user: QualaUser = { userId: 'user-123', email: 'user@company.com', trialStartDate: '2025-01-01' }; const { identifyUser } = useQuala(); identifyUser(user); // โœ… Fully typed ``` ### Hook Benefits - **Automatic Cleanup**: `useQualaInit` handles SDK destruction on unmount - **React-Friendly**: No need to manage SDK lifecycle manually - **TypeScript Ready**: Full type safety out of the box - **Lightweight**: Hooks only wrap the core SDK, no extra overhead ## ๐ŸŽฏ Micro Widgets (Conditional Feature) Micro widgets are **conditionally loaded** based on your project configuration. They only activate when: 1. Your project has micro widgets enabled in the dashboard 2. Valid trigger configuration exists 3. Anti-spam conditions are met ### Smart Triggers When enabled, micro widgets respond to 5 intelligent triggers: | Trigger | When It Shows | Default Question | Emoji Set | |---------|---------------|------------------|-----------| | **๐Ÿ•’ Time** | After user spends time on page | "How has your experience been so far?" | Detailed (๐Ÿ˜๐Ÿ˜Š๐Ÿ˜๐Ÿ˜•๐Ÿ˜ค) | | **๐Ÿšช Exit Intent** | When user moves to leave | "Before you go, how can we improve?" | Exit-focused (๐Ÿ‘๐Ÿคท๐Ÿ˜•) | | **โšก Console Error** | When JavaScript errors occur | "We noticed some technical issues. How can we help?" | Technical (โœ…๐Ÿค”๐Ÿž) | | **๐Ÿ“ Form Failure** | When form submissions fail | "Having trouble with the form?" | Technical (โœ…๐Ÿค”๐Ÿž) | | **๐Ÿ”ง API Failure** | When API calls fail | "Something went wrong. What can we fix?" | Technical (โœ…๐Ÿค”๐Ÿž) | ### Contextual Intelligence Each trigger type gets **contextual questions and appropriate feedback options**: ```javascript // Example: Console error detected // Question: "We noticed some technical issues. How can we help?" // Options: โœ… Working fine ๐Ÿค” Something's off ๐Ÿž It's broken // Example: Exit intent detected // Question: "Before you go, how can we improve?" // Options: ๐Ÿ‘ All good ๐Ÿคท Just browsing ๐Ÿ˜• Something's wrong ``` ## ๐Ÿ“Š Technical Context Capture When micro widgets are enabled, the SDK automatically captures: ```javascript { device: { userAgent: "Chrome/91.0...", viewport: "1920x1080", timezone: "America/New_York" }, performance: { loadTime: 1250, memoryUsage: "45MB", connectionType: "4g" }, errors: [ { message: "Cannot read property 'x' of undefined", stack: "...", timestamp: "2025-01-15T10:30:00Z" } ], networkFailures: [ { url: "/api/users", status: 500, timestamp: "2025-01-15T10:29:55Z" } ], userActions: [ { type: "click", element: "button#submit", timestamp: "..." }, { type: "form_submit", form: "login-form", timestamp: "..." } ] } ``` ## ๐Ÿ›ก๏ธ Anti-Spam System Intelligent frequency management prevents widget fatigue: - **Global Cooldown**: Minimum 45 seconds between any widgets - **Trigger Priorities**: Critical errors override time-based triggers - **Session Limits**: Maximum 3 widgets per session - **Individual Cooldowns**: Each trigger type has its own cooldown - **Smart Override**: High-priority triggers can override cooldowns ```javascript // Check anti-spam status (debug mode only) const status = qualaSdk.getAntiSpamStatus(); console.log(status); // { // enabled: true, // globalCooldownRemaining: 15000, // sessionWidgetCount: 1, // lastWidgetType: 'time', // canShow: true // } ``` ## ๐ŸŽฎ Runtime Configuration ### Configure Micro Widgets ```javascript qualaSdk.configureMicroWidget({ position: 'bottom-left', question: 'Custom question for all triggers', emojiSet: 'simple', // 'default' | 'simple' | 'detailed' autoHide: true, hideDelay: 8000 }); ``` ### Check Availability ```javascript // Check if regular feedback trigger is available const available = await qualaSdk.checkTriggerAvailable(); // Refresh trigger status const refreshed = await qualaSdk.refreshTriggerStatus(); ``` ## ๐Ÿ“ฑ Regular Feedback Widgets Traditional feedback forms still work as before: ```javascript // These will show automatically when triggers are configured // Or manually trigger: await qualaSdk.triggerSmartFeedback(); ``` ## ๐Ÿ”ง Advanced Configuration ### Event Listeners ```javascript // Listen to SDK events qualaSdk.on('micro_widget_shown', ({ triggerType, config }) => { console.log(`Micro widget shown for ${triggerType}`); }); qualaSdk.on('micro_feedback_submitted', ({ feedback, triggerType, technicalContext }) => { console.log('Feedback submitted:', feedback); }); qualaSdk.on('user_identified', ({ user, session }) => { console.log('User identified:', user.userId); }); qualaSdk.on('config_updated', ({ config, reason }) => { console.log('Config updated:', reason); }); // Remove listeners qualaSdk.off('micro_widget_shown'); ``` ### Debug Mode ```javascript await qualaSdk.initialize('your-api-key', { debug: true }); // Debug-only methods qualaSdk.forceAllowNextWidget(); // Bypass anti-spam qualaSdk.resetAntiSpamState(); // Reset anti-spam counters await qualaSdk.forceConfigRefresh(); // Force config update ``` ### Get Session Info ```javascript const info = qualaSdk.getSessionInfo(); console.log(info); // { // sessionToken: "abc123...", // questionGroupId: "uuid...", // isInitialized: true, // microWidgetEnabled: true, // antiSpam: { ... } // Debug mode only // } ``` ### Get Technical Context ```javascript // Only available when micro widgets are enabled const context = qualaSdk.getTechnicalContext(); if (context) { console.log('Current technical state:', context); } ``` ## ๐Ÿ“Š Analytics & Tracking The SDK automatically tracks key events: ```javascript // Manual event tracking qualaSdk.trackEvent('feature_used', { feature: 'advanced-search', userId: 'user-123' }); qualaSdk.trackEvent('milestone_reached', { milestone: 'onboarding_complete', timeToComplete: 120000 }); ``` **Automatic Events:** - `user_identified` - When user is identified - `micro_widget_shown` - When micro widget appears - `micro_feedback_submitted` - When micro feedback is submitted - `feedback_widget_triggered` - When regular widget triggers - `anti_spam_blocked` - When anti-spam prevents display - `config_updated` - When configuration changes ## ๐ŸŒ Offline Support The SDK gracefully handles offline scenarios: - **Offline Queue**: Feedback is queued when offline - **Auto-Sync**: Syncs when connection returns - **Persistence**: Uses localStorage as backup - **Retry Logic**: Automatic retry with exponential backoff ```javascript // Feedback submitted offline will be automatically synced // when the user comes back online ``` ## ๐ŸŽฏ Conditional Loading Key features are **conditionally loaded** based on configuration: | Feature | Loads When | |---------|------------| | **Micro Widgets** | Project has micro widgets enabled | | **Technical Context** | Micro widgets are enabled | | **Anti-Spam Manager** | Micro widgets are enabled | | **Trigger Listeners** | Micro widgets enabled + triggers configured | | **Config Refresh** | Micro widgets are enabled | This ensures **minimal overhead** when features aren't needed. ## ๐Ÿšซ Error Handling ```javascript try { await qualaSdk.initialize('invalid-key'); } catch (error) { console.error('SDK initialization failed:', error); } // Listen for errors qualaSdk.on('sdk_error', ({ error, phase }) => { console.error(`SDK error in ${phase}:`, error); }); qualaSdk.on('widget_load_error', ({ error }) => { console.error('Widget failed to load:', error); }); ``` ## ๐Ÿ” Security & Privacy - **Domain Filtering**: Sensitive domains (auth, payment) are excluded from context - **Data Minimization**: Only necessary technical data is collected - **Local Storage**: Minimal use of localStorage for offline support - **Session-Based**: All data tied to user sessions ## ๐Ÿ—‚๏ธ Project Configuration Configure your project's feedback strategy through the Quala dashboard: - **Trigger Selection**: Choose which behavioral triggers to enable - **Contextual Questions**: Customize questions per trigger type - **Emoji Sets**: Select appropriate feedback styles for each context - **Technical Context**: Enable detailed error and performance capture - **Anti-Spam Settings**: Configure frequency and priority rules ## ๐Ÿงช Testing ```javascript // Test in development await qualaSdk.initialize('your-api-key', { debug: true, apiBaseUrl: 'http://localhost:3001/api/widget' }); // Check what features are enabled const info = qualaSdk.getSessionInfo(); console.log('Micro widgets enabled:', info.microWidgetEnabled); // Debug mode provides additional testing methods qualaSdk.forceAllowNextWidget(); // Bypass anti-spam qualaSdk.resetAntiSpamState(); // Reset anti-spam counters ``` ## ๐Ÿ“š TypeScript Support Full TypeScript definitions included: ```typescript import { qualaSdk, QualaUser, MicroWidgetConfig } from 'quala-widget'; const user: QualaUser = { userId: 'user-123', email: 'user@company.com' }; await qualaSdk.identifyUser(user); ``` **Ready to turn vague complaints into actionable insights?** ๐Ÿš€ Get started at [getquala.xyz](https://getquala.xyz)