Widget Events

Listen in the host page
// Catch all
window.addEventListener('duki:event', (e) => {
  console.log('[DUKI]', e.detail.name, e.detail);
});

// Specific
window.addEventListener('duki:chat:init', (e) => {
  const { chatId } = e.detail;
});

Check the "Event catalog" to see events names

Payload
{
  name,          // normalized event name, e.g. "chat:init"
  ts,            // ISO timestamp
  projectId,     // widget project id
  language,      // e.g., "en"
  side,          // "right" | "left"
  ...custom      // event-specific fields (chatId, message, error, ...)
}
Event catalog
EventWhenDetail
Meta
duki:eventEvery event (catch-all)name, ts, projectId, customFields, + payload
Panel & lifecycle
duki:chat:openChat openssource, widget_mode
duki:chat:closeChat closes
duki:chat:fullscreenEnter fullscreen
duki:chat:smallscreenExit fullscreen
duki:chat:closeRequestedUser clicked Close in chat menuchatId
duki:chat:toggleExpandExpand / collapse from chat menuexpanded, chatId
Session & messages
duki:chat:initSession readychatId
duki:chat:startSession startedchatId
duki:chat:newSessionNew session created (after end chat)chatId
duki:chat:endedChat endedchatId
duki:chat:historyHistory receivedmessages[]
duki:chat:historyendHistory renderedmessages[]
duki:chat:typingTyping on
duki:chat:typingendTyping off
duki:chat:thinkingThinking on
duki:chat:thinkingendThinking off
duki:chat:messageUser sent a messagemessage
duki:chat:newMessageBot message received (not history)chatId
duki:chat:errorErrorerror
End chat
duki:chat:endChatRequestedUser requested end chatchatId
duki:chat:endChatPopupOpenedEnd chat rating popup openedchatId
duki:chat:endChatPopupClosedEnd chat popup closedchatId, reason
duki:chat:endChatRatingSelectedThumbs up / down selectedchatId, rating
duki:chat:endChatFeedbackSentFeedback submittedchatId, rating, hasComment
duki:chat:endChatDisconnectedWebSocket disconnectedchatId
duki:chat:endChatStartNewRequestedStart new chat clickedchatId
Lead form
duki:chat:leadFormOpenedLead form openedchatId
duki:chat:leadFormClosedLead form closedchatId
duki:chat:leadFormSubmittedLead form submittedchatId, lead
Tooltip
duki:tooltip:showChat icon tooltip shownvariant, source, textLength
duki:tooltip:closeUser dismissed tooltipvariant, reason, dismissedSaved
Page analytics (every 15s + on exit)
duki:analytics:page_viewPage loaded with widgeturl, visitorId
duki:analytics:time_on_pageEvery 15 seconds on pagetimeOnPageSec, maxScrollPercent, scrollBucket
duki:analytics:page_closeUser leaves page / tab hiddentimeOnPageSec, maxScrollPercent
duki:analytics:chat_engagementFirst chat open on pagetimeOnPageSec, engagementPageUrl
Custom fields
duki:customFields:updatedCustom fields updated (e.g. disclaimer)customFields
duki:updateCustomFieldsSame update, forwarded from iframecustomFields
Search mode
duki:searchMode:expandSearch panel expanded
duki:searchMode:closeSearch panel closed
GTM / GA4
<script>
window.dataLayer = window.dataLayer || [];
window.addEventListener('duki:event', (e) => {
  const ev = e.detail;
  window.dataLayer.push({
    event: 'duki_' + ev.name.replace(/:/g, '_'),
    duki: ev
  });
});
</script>

This is an exmple how you can use the events.

AI Chat Custom Fields

Add contextual data to enrich conversations. Define window.dukiCustomFields before loading the chat widget. These fields are automatically sent on duki:chat:start.

<script>
window.dukiCustomFields = {
  // Business Context
  country: "",
  userMarket: "",

  // Page Context
  currentPageUrl: window.location.href,
  currentPageTitle: document.title,
  previousPageUrl: document.referrer,

  // User Context
  visitorName: "",
  visitorEmail: "",
  companyName: "",
  userRole: "",
  industry: "",

  // Behavioral Context
  pageCategory: "",
  userIntent: "",
  customerType: "",

  // Technical Context
  userAgent: navigator.userAgent,
  language: navigator.language,
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,

  // Session Context
  sessionId: "",
  visitCount: "",
  lastVisit: "",
  
  // tooltip text  and auto open
   tooltipText: "Your custom tooltip text here",
    autoOpen: true  // or false to disable auto-open


};
</script>

You can dynamically add values with:

<script>
window.dukiSetCustomField = function(key, value) {
  if (!window.dukiCustomFields.dynamicFields)
    window.dukiCustomFields.dynamicFields = {};
  window.dukiCustomFields.dynamicFields[key] = value;
};

// Example usage
window.dukiSetCustomField("planSelected", "Pro");
window.dukiSetCustomField("cartValue", "199.90");
</script>

This helps personalize AI replies, analytics, and lead enrichment.