window.postMessage; the only callback option is onNavigate, covered in the configuration reference.
Before you begin
- The widget installed per the quickstart.
- For the Tag Manager step, a GTM container on the page.
1
Listen for widget events
Every event is posted to the page’s own The payload is
window with type: "LUA_POP_EVENT". Register the listener before or after init(); the order doesn’t matter.{ type: "LUA_POP_EVENT", eventType, timestamp, data? }: timestamp is Date.now() at emit time and data exists only on message_received. No event carries an end user identifier or the session ID.2
Handle each event type
Four
eventType values exist.widget_opened and widget_closed never fire in embedded mode, where the chat is always visible. message_received doesn’t fire for a reply whose stream fails part-way, nor for replies delivered as rich UI components instead of text.3
Forward events to Google Tag Manager
GTM triggers fire on
dataLayer pushes, so forward each event from a Custom HTML tag, then create a Custom Event trigger for lua_message_sent or any of the other names.4
Optional: resize an iframe that hosts the widget
When the widget runs inside an iframe, it also posts a metadata-only copy of each event to
window.parent, plus a LUA_POP_RESIZE message once when it mounts and whenever the floating window opens or closes. Handle that message in the parent page.width and height are "350px" and "500px" while the window is open and "auto" when it is closed. The parent copy of message_received omits data, because the parent may be on another origin.5
Verify
Open the widget and send a message. The console from the first step prints
widget_opened, then message_sent, then message_received with the reply text.Options you may need
Google Analytics 4
Callgtag directly instead of going through dataLayer.
If it isn’t working
No widget_opened or widget_closed events
No widget_opened or widget_closed events
The widget is in embedded mode, where the chat never opens or closes. Use
message_sent as the engagement signal.Events arrive without data in the parent page
Events arrive without data in the parent page
You are listening in the page that hosts the iframe. Only the copy posted to the widget’s own window carries
data.Events can be forged
Events can be forged
Any script on the page can post the same messages. Use them for analytics and UX, never for access control.
Next steps
Widget configuration
onNavigate and every other option.Send proactive messages
Messages the agent starts also fire
message_received.
