Skip to main content
The Molin AI widget notifies your website at key moments in its lifecycle. You can use these hooks to trigger custom logic such as initializing integrations, adjusting page layout, or tracking analytics. The simplest and most reliable approach is to define callback functions directly in window.molinSettings. Because this object is defined before the widget script loads, the onReady hook is guaranteed to fire.
<script>
  window.molinSettings = {
    onReady: (e) => {
      console.log('Widget ready:', e.widgetId);
      window.Molin.openChat();
    },
    onChatOpen: (e) => {
      console.log('Chat opened:', e.widgetId);
    },
    onChatClose: (e) => {
      console.log('Chat closed:', e.widgetId);
    },
    onMessageSent: (e) => {
      console.log('Message sent:', e.widgetId);
    },
    onLinkClick: (e) => {
      console.log('Link clicked:', e.widgetId, e.url);
    },
  };
</script>

Available hooks

HookArgumentDescription
onReady{ widgetId: string }Called once when the widget has loaded and rendered
onChatOpen{ widgetId: string }Called whenever the chat window opens
onChatClose{ widgetId: string }Called whenever the chat window closes
onMessageSent{ widgetId: string }Called when the user sends a message
onLinkClick{ widgetId: string, url: string }Called when the user clicks a link in the chat
Settings hooks can be combined with other molinSettings properties like hidden or userData in the same object.

Window events (alternative)

The widget also dispatches standard CustomEvent events on the window object. Use this approach if you need multiple independent listeners for the same event, or if you prefer the DOM event API.

Available events

molin:ready

Fired once when the widget has fully loaded its configuration and rendered for the first time.
window.addEventListener('molin:ready', (e) => {
  console.log('Molin widget is ready:', e.detail.widgetId);

  // safe to call widget methods now
  window.Molin.openChat({ message: 'Welcome!' });
});
PropertyTypeDescription
e.detail.widgetIdstringThe unique ID of the widget that fired
If your script loads after the widget, the molin:ready event may have already fired. In that case, check if window.Molin already exists as a fallback:
if (window.Molin) {
  // widget is already ready
  onMolinReady();
} else {
  window.addEventListener('molin:ready', onMolinReady);
}
This race condition does not exist with the settings hooks approach above, which is why it is recommended.

molin:chat-open

Fired whenever the chat window is opened, whether by the user clicking the bubble, a popup click, the floating input, a programmatic call to openChat(), or a restored session on mobile.
window.addEventListener('molin:chat-open', (e) => {
  console.log('Chat opened for widget:', e.detail.widgetId);
});
PropertyTypeDescription
e.detail.widgetIdstringThe unique ID of the widget that fired

molin:chat-close

Fired whenever the chat window is closed, whether by the user clicking the close button, toggling the bubble, or a programmatic call to closeChat().
window.addEventListener('molin:chat-close', (e) => {
  console.log('Chat closed for widget:', e.detail.widgetId);
});
PropertyTypeDescription
e.detail.widgetIdstringThe unique ID of the widget that fired

molin:message-sent

Fired when the user sends a message in the chat.
window.addEventListener('molin:message-sent', (e) => {
  console.log('Message sent in widget:', e.detail.widgetId);
});
PropertyTypeDescription
e.detail.widgetIdstringThe unique ID of the widget that fired
Fired when the user clicks a link inside the chat conversation.
window.addEventListener('molin:link-click', (e) => {
  console.log('Link clicked:', e.detail.url);
});
PropertyTypeDescription
e.detail.widgetIdstringThe unique ID of the widget that fired
e.detail.urlstringThe URL of the clicked link

Full example

<script>
  function onMolinReady(e) {
    console.log('Widget ready:', e.detail.widgetId);
  }

  if (window.Molin) {
    onMolinReady({ detail: { widgetId: 'already-loaded' } });
  } else {
    window.addEventListener('molin:ready', onMolinReady);
  }

  window.addEventListener('molin:chat-open', () => {
    document.body.classList.add('molin-chat-open');
  });

  window.addEventListener('molin:chat-close', () => {
    document.body.classList.remove('molin-chat-open');
  });
</script>