Widget Events & Callbacks

React to widget events in your application. Track analytics, integrate with other systems, or customize behavior.

Event Handlers

onOpen() => void

Called when the chat window is opened.

onClose() => void

Called when the chat window is closed.

onMessage(message: ChatMessage) => void

Called when a new message is sent or received.

onError(error: Error) => void

Called 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

idstring

Unique message identifier

role"user" | "assistant" | "system"

Who sent the message

contentstring

Message text content

timestampDate

When the message was sent

isStreamingboolean

True while assistant response is streaming

metadataobject

Additional message data

sourcesSource[]

Source citations (assistant messages only)

latencynumber

Response 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

ConnectionErrorError

WebSocket connection failed. Check network or API status.

AuthenticationErrorError

Invalid API key or bot ID.

RateLimitErrorError

Too many requests. Implement backoff.

ServerErrorError

API 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();
  }
});