Event System
LuaPop communicates with your website through the browser’spostMessage API. Listen for events to track interactions, trigger actions, or integrate with analytics.
Widget Events
Listening to Events
Copy
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
Fired when the chat widget is opened by the user.Data:
{}Copy
case 'widget_opened':
console.log('Chat widget opened');
// Track in analytics, show help hints, etc.
break;
Fired when the chat widget is closed.Data:
{}Copy
case 'widget_closed':
console.log('Chat widget closed');
// Track session duration, save state, etc.
break;
Fired when the user sends a message.Data:
{ content: string, timestamp: string }Copy
case 'message_sent':
console.log('User sent:', data.content);
// Track user messages, sentiment analysis, etc.
break;
Fired when the AI sends a response.Data:
{ content: string, timestamp: string }Copy
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:Copy
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);
}
});
Navigation Handler
Handle navigation events from the chat:Copy
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
Copy
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
Copy
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
Copy
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
Copy
// 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);
}

