Skip to main content

Event System

LuaPop communicates with your website through the browser’s postMessage API. Listen for events to track interactions, trigger actions, or integrate with analytics.

Widget Events

Listening to Events

window.addEventListener('message', function(event) {
  if (event.data && event.data.type === 'LUA_POP_EVENT') {
    const { eventType, data } = event.data;
    
    console.log('Event:', eventType);
    console.log('Data:', data);
  }
});

Available Events

widget_opened
event
Fired when the chat widget is opened by the user.Data: {}
case 'widget_opened':
  console.log('Chat widget opened');
  // Track in analytics, show help hints, etc.
  break;
widget_closed
event
Fired when the chat widget is closed.Data: {}
case 'widget_closed':
  console.log('Chat widget closed');
  // Track session duration, save state, etc.
  break;
message_sent
event
Fired when the user sends a message.Data: { content: string, timestamp: string }
case 'message_sent':
  console.log('User sent:', data.content);
  // Track user messages, sentiment analysis, etc.
  break;
message_received
event
Fired when the AI sends a response.Data: { content: string, timestamp: string }
case 'message_received':
  console.log('AI responded:', data.content);
  // Track AI responses, measure quality, etc.
  break;

Resize Events

For embedded mode, listen to resize events:
window.addEventListener('message', function(event) {
  if (event.data && event.data.type === 'LUA_POP_RESIZE') {
    const { width, height } = event.data;
    console.log('Widget resized:', width, height);
    
    // Adjust surrounding layout if needed
    adjustLayout(width, height);
  }
});
Handle navigation events from the chat:
window.LuaPop.init({
  agentId: "your-agent-id",
  
  onNavigate: (pathname, options) => {
    console.log('Navigate to:', pathname);
    console.log('Query params:', options.query);
    
    // Example 1: Standard navigation
    window.location.href = pathname;
    
    // Example 2: With query params
    const url = pathname + '?' + new URLSearchParams(options.query);
    window.location.href = url;
    
    // Example 3: React Router
    navigate(pathname, { state: options.query });
    
    // Example 4: Vue Router
    router.push({ path: pathname, query: options.query });
  }
});

Complete Event Handler

class LuaPopEventHandler {
  constructor() {
    this.setupEventListeners();
  }

  setupEventListeners() {
    window.addEventListener('message', (event) => {
      if (!event.data) return;
      
      switch (event.data.type) {
        case 'LUA_POP_EVENT':
          this.handleWidgetEvent(event.data);
          break;
        case 'LUA_POP_RESIZE':
          this.handleResize(event.data);
          break;
        case 'LUA_POP_ERROR':
          this.handleError(event.data);
          break;
      }
    });
  }

  handleWidgetEvent({ eventType, data }) {
    switch (eventType) {
      case 'widget_opened':
        this.onWidgetOpened();
        break;
      case 'widget_closed':
        this.onWidgetClosed();
        break;
      case 'message_sent':
        this.onMessageSent(data);
        break;
      case 'message_received':
        this.onMessageReceived(data);
        break;
    }
  }

  onWidgetOpened() {
    console.log('✅ Widget opened');
    
    // Track in analytics
    gtag('event', 'chat_opened', {
      event_category: 'engagement'
    });
    
    // Update UI
    document.body.classList.add('chat-active');
  }

  onWidgetClosed() {
    console.log('❌ Widget closed');
    
    // Track session duration
    gtag('event', 'chat_closed', {
      event_category: 'engagement'
    });
    
    // Update UI
    document.body.classList.remove('chat-active');
  }

  onMessageSent(data) {
    console.log('📤 User sent:', data.content);
    
    // Track user engagement
    this.trackMessage('user', data.content);
  }

  onMessageReceived(data) {
    console.log('📥 AI responded:', data.content);
    
    // Track AI responses
    this.trackMessage('ai', data.content);
  }

  handleResize({ width, height }) {
    console.log(`📐 Widget resized: ${width}x${height}`);
  }

  handleError({ error }) {
    console.error('❌ LuaPop Error:', error);
    
    // Show fallback UI or error message
    this.showErrorFallback(error);
  }

  trackMessage(sender, content) {
    // Send to analytics service
    fetch('/api/analytics/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        sender,
        content,
        timestamp: new Date().toISOString()
      })
    });
  }

  showErrorFallback(error) {
    // Show user-friendly error message
    alert('Chat is temporarily unavailable. Please try again later.');
  }
}

// Initialize event handler
new LuaPopEventHandler();

Use Cases

Track Chat Engagement

let chatSessions = 0;
let messagesExchanged = 0;

window.addEventListener('message', function(event) {
  if (event.data && event.data.type === 'LUA_POP_EVENT') {
    switch (event.data.eventType) {
      case 'widget_opened':
        chatSessions++;
        console.log('Total chat sessions:', chatSessions);
        break;
        
      case 'message_sent':
      case 'message_received':
        messagesExchanged++;
        console.log('Total messages:', messagesExchanged);
        break;
    }
  }
});

Show Help Hints

window.addEventListener('message', function(event) {
  if (event.data && event.data.type === 'LUA_POP_EVENT') {
    if (event.data.eventType === 'widget_opened') {
      // Show contextual help based on current page
      const page = window.location.pathname;
      
      if (page.includes('/pricing')) {
        // Could trigger AI to suggest pricing questions
        console.log('User opened chat on pricing page');
      }
    }
  }
});

Auto-Open for New Users

// Check if user is new
const isNewUser = !localStorage.getItem('has_used_chat');

window.LuaPop.init({
  agentId: "onboarding-agent",
  buttonText: isNewUser ? "🚀 Get Started" : "💬 Chat"
});

// Auto-open for new users after 5 seconds
if (isNewUser) {
  setTimeout(() => {
    // Trigger chat open
    document.querySelector('.lua-pop-button')?.click();
    localStorage.setItem('has_used_chat', 'true');
  }, 5000);
}

Next Steps

EOFSTYLE