quala-widget
Version:
Smart feedback widget for SaaS trial optimization
449 lines (353 loc) โข 12.3 kB
Markdown
# ๐ 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)