Skip to content

Control the widget with JavaScript

Open the chat, ask a question for the visitor, read its state and react to events from your own code.

Last updated

Use the JavaScript API when buttons with attributes aren't enough: open the chat from your own logic, ask a question for the visitor, or react to what happens in the widget.

Where the API lives#

How you installedCall it on
Quick install script tagHelpAI, the global the script adds
<web-ai-chat> elementThe element itself
NPM packageThe widget init() returns
React kituseHelpAI(), see Add the widget to a React or Next.js app

The calls are the same on each, with one difference: on the script tag, await HelpAI.ready() gives you the widget; on the element and the init() handle, await chat.ready (no brackets) waits for it. The HelpAI global doesn't control a <web-ai-chat> element. None of this reaches a deployment set to Embed in an iframe, where the chat runs on the hosted page.

The examples use await, so run them in an async function or a <script type="module">.

Wait until the widget is ready#

The Quick install snippet loads with defer, so HelpAI exists once the page has been read. Run your code after that, and await HelpAI.ready() before you use the widget: it resolves once the widget has finished connecting. If it couldn't connect, the error event fires first.

js
document.addEventListener('DOMContentLoaded', async () => {
  const chat = await HelpAI.ready();
  console.log(chat.state);
  // { open: false, ready: true, unread: 0, … }
});

Code that runs before the widget's script#

Inline code above the widget's script tag runs before HelpAI exists, so a call throws HelpAI is not defined. Add this line first. It holds your calls until the widget loads:

html
<script>
  window.HelpAI = window.HelpAI || function () { (HelpAI.q = HelpAI.q || []).push(arguments); };

  HelpAI('ready', (chat) => {
    chat.on('open', () => console.log('Chat opened'));
  });
</script>

ready, login, track and hook work from the start: they wait for the widget. Calls that act on the chat, such as open, ask and reset, do nothing until it has loaded, so make them from a click.

On the element#

If your code can run before the element's script, wait for the element first:

js
await customElements.whenDefined('web-ai-chat');
const chat = document.querySelector('web-ai-chat');
await chat.ready;
chat.open({ to: 'help' });

Open, close and ask#

CallWhat it does
HelpAI.open()Opens the chat
HelpAI.open({ to: 'help' })Opens a tab: home, chats, help or news
HelpAI.open({ to: 'help', id: '<article id>' })Opens one Help article. Use to: 'news' for a News post
HelpAI.close()Closes the chat
HelpAI.expand()Switches the chat between its normal and larger size
HelpAI.ask('Can I change my plan?')Opens the chat with the question in the message box, for the visitor to send or edit
HelpAI.ask('Can I change my plan?', { send: true })Opens the chat and sends the question for the visitor
chat.openForm('<form id>')Shows a form whose When is Manual (open via code)

openForm isn't a HelpAI shortcut: call it on the widget, (await HelpAI.ready()).openForm(id).

ask() waits until the chat can take the question, for example after a form that must be filled in first, so you can call it as soon as the visitor clicks.

  • A newer ask() replaces one that's still waiting.
  • Empty text is ignored.
  • If a send is turned down, the text stays in the message box for the visitor to send.
  • Send only from something the visitor did, such as a click, never when the page loads.
js
const button = document.querySelector('#plan-help');
button.addEventListener('click', () => {
  HelpAI.ask('Which plan fits a team of 10?');
});

Change options while it runs#

HelpAI.update() changes options on the running widget, such as its theme, without reloading it:

js
HelpAI.update({ theme: 'dark' });

On <web-ai-chat>, change its attributes instead.

Read the widget's state#

chat.state says where the widget is right now:

FieldMeaning
openThe chat is showing. Always true for an inline chat or a full page
readyThe widget has connected, so calls act at once
unreadConversations with replies the visitor hasn't read
conversationIdThe visitor's current conversation

Listen for events#

chat.on(event, callback) calls you back each time, and returns a function that stops listening.

js
const chat = await HelpAI.ready();
chat.on('open', () => analytics.track('Chat opened'));
chat.on('message', ({ role, text }) => {
  console.log(role, text);
});
const stopWatching = chat.on('state', (state) => {
  console.log(state);
});
EventFires when
open, closeThe chat opens or closes
messageThe visitor sends a message, or a reply from the AI agent or your team finishes. role is user, assistant or operator
stateAnything in chat.state changes
unreadThe number of conversations with unread replies changes
expand, fullscreenThe chat changes size: true when it's now larger or full screen
formSubmitThe visitor submits or skips a form: { formId, values, skipped }
messageFeedbackThe visitor rates a reply: { messageId, value }, where value is up, down or null
localeChangeThe visitor picks another language
errorThe widget can't load or send

A callback that throws an error can't break the widget. With the NPM package, init() also takes onOpen, onClose, onMessage and onError. To forward events to Google Analytics or another tracker, see Send chat activity to your analytics.

Start over when someone signs out#

The widget remembers each visitor in their browser. On a shared computer, call reset() when someone signs out of your site. It forgets their conversation, preferences, and the user details and sign-in your page passed, then reconnects as a new visitor. Your on() listeners keep working.

js
const signOut = document.querySelector('#sign-out');
signOut.addEventListener('click', () => HelpAI.reset());

On <web-ai-chat> it's chat.reset(). For signed-in users, see Verify signed-in users.

Every option, call and event is in the API reference (opens another site).

Was this helpful?

Still need help?

Ask the community