Widget Events & Callbacks
React to widget events in your application. Track analytics, integrate with other systems, or customize behavior.
Event Handlers
onOpen() => voidCalled when the chat window is opened.
onClose() => voidCalled when the chat window is closed.
onMessage(message: ChatMessage) => voidCalled when a new message is sent or received.
onError(error: Error) => voidCalled when an error occurs (connection issues, API errors).
Basic Usage
RagChatsWidget.init({
botId: 500">class="text-green-500">'YOUR_BOT_ID',
apiKey: 500">class="text-green-500">'YOUR_API_KEY',
onOpen: () => {
console.log(500">class="text-green-500">'Chat window opened');
},
onClose: () => {
console.log(500">class="text-green-500">'Chat window closed');
},
onMessage: (message) => {
console.log(500">class="text-green-500">'New message:', message);
},
onError: (error) => {
console.error(500">class="text-green-500">'Widget error:', error);
}
});ChatMessage Type
The onMessage callback receives a ChatMessage object:
ChatMessage
idstringUnique message identifier
role"user" | "assistant" | "system"Who sent the message
contentstringMessage text content
timestampDateWhen the message was sent
isStreamingbooleanTrue while assistant response is streaming
metadataobjectAdditional message data
sourcesSource[]Source citations (assistant messages only)
latencynumberResponse time in milliseconds
Analytics Integration
Use events to track widget usage in your analytics platform:
RagChatsWidget.init({
botId: 500">class="text-green-500">'YOUR_BOT_ID',
apiKey: 500">class="text-green-500">'YOUR_API_KEY',
onOpen: () => {
500">class=500">class="text-green-500">"text-muted-foreground">// Google Analytics 4
gtag(500">class="text-green-500">'event', 500">class="text-green-500">'chat_opened', {
event_category: 500">class="text-green-500">'engagement',
});
500">class=500">class="text-green-500">"text-muted-foreground">// Segment
analytics.track(500">class="text-green-500">'Chat Opened');
500">class=500">class="text-green-500">"text-muted-foreground">// Mixpanel
mixpanel.track(500">class="text-green-500">'Chat Opened');
},
onMessage: (message) => {
500">if (message.role === 500">class="text-green-500">'user') {
gtag(500">class="text-green-500">'event', 500">class="text-green-500">'chat_message_sent', {
event_category: 500">class="text-green-500">'engagement',
message_length: message.content.length,
});
}
},
onError: (error) => {
500">class=500">class="text-green-500">"text-muted-foreground">// Track errors
gtag(500">class="text-green-500">'event', 500">class="text-green-500">'chat_error', {
event_category: 500">class="text-green-500">'error',
error_message: error.message,
});
}
});Custom Integrations
Send to CRM
onMessage: (message) => {
500">if (message.role === 500">class="text-green-500">'user') {
500">class=500">class="text-green-500">"text-muted-foreground">// Log conversation to CRM
fetch(500">class="text-green-500">'/api/crm/log-chat', {
method: 500">class="text-green-500">'POST',
body: JSON.stringify({
message: message.content,
timestamp: message.timestamp,
})
});
}
}Show Notification
onMessage: (message) => {
500">if (message.role === 500">class="text-green-500">'assistant' && !RagChatsWidget.isOpen()) {
500">class=500">class="text-green-500">"text-muted-foreground">// Show browser notification 500">for 500">new messages
500">if (Notification.permission === 500">class="text-green-500">'granted') {
500">new Notification(500">class="text-green-500">'New message 500">from Support', {
body: message.content.substring(0, 100) + 500">class="text-green-500">'...',
});
}
}
}Trigger Support Escalation
onMessage: (message) => {
500">class=500">class="text-green-500">"text-muted-foreground">// Detect frustrated users
500">const frustrationPhrases = [500">class="text-green-500">'speak to human', 500">class="text-green-500">'real person', 500">class="text-green-500">'not helpful'];
500">const needsHuman = frustrationPhrases.some(phrase =>
message.content.toLowerCase().includes(phrase)
);
500">if (needsHuman) {
500">class=500">class="text-green-500">"text-muted-foreground">// Trigger live chat or support ticket
openLiveChatWidget();
500">class=500">class="text-green-500">"text-muted-foreground">// or
createSupportTicket(message);
}
}Error Handling
Common errors you might receive:
Error Types
ConnectionErrorErrorWebSocket connection failed. Check network or API status.
AuthenticationErrorErrorInvalid API key or bot ID.
RateLimitErrorErrorToo many requests. Implement backoff.
ServerErrorErrorAPI server error. Retry or contact support.
onError: (error) => {
500">if (error.name === 500">class="text-green-500">'ConnectionError') {
500">class=500">class="text-green-500">"text-muted-foreground">// Show connection status to user
showToast(500">class="text-green-500">'Connection lost. Retrying...');
} 500">else 500">if (error.name === 500">class="text-green-500">'RateLimitError') {
500">class=500">class="text-green-500">"text-muted-foreground">// Implement rate limiting
showToast(500">class="text-green-500">'Please wait a moment before sending another message.');
} 500">else {
500">class=500">class="text-green-500">"text-muted-foreground">// Generic error handling
console.error(500">class="text-green-500">'Chat error:', error);
showToast(500">class="text-green-500">'Something went wrong. Please try again.');
}
}Graceful Degradation
The widget automatically retries failed connections and shows user-friendly error messages. The onError handler is for additional logging or custom UI.
Programmatic Control
Control the widget from your application code:
500">class=500">class="text-green-500">"text-muted-foreground">// Open the chat window
RagChatsWidget.open();
500">class=500">class="text-green-500">"text-muted-foreground">// Close the chat window
RagChatsWidget.close();
500">class=500">class="text-green-500">"text-muted-foreground">// Toggle open/closed
RagChatsWidget.toggle();
500">class=500">class="text-green-500">"text-muted-foreground">// Check 500">if open
500">if (RagChatsWidget.isOpen()) {
console.log(500">class="text-green-500">'Chat is visible');
}
500">class=500">class="text-green-500">"text-muted-foreground">// Destroy the widget (remove 500">from DOM)
RagChatsWidget.destroy();Open from Custom Button
<button onclick=500">class="text-green-500">"RagChatsWidget.open()">
Need Help? Chat with us
</button>Open Based on User Behavior
500">class=500">class="text-green-500">"text-muted-foreground">// Open chat after user spends 30 seconds on page
setTimeout(() => {
500">if (!RagChatsWidget.isOpen()) {
RagChatsWidget.open();
}
}, 30000);
500">class=500">class="text-green-500">"text-muted-foreground">// Open chat when user scrolls to bottom
window.addEventListener(500">class="text-green-500">'scroll', () => {
500">const scrolledToBottom =
window.innerHeight + window.scrollY >= document.body.offsetHeight - 100;
500">if (scrolledToBottom && !RagChatsWidget.isOpen()) {
RagChatsWidget.open();
}
});
