Put chat on your site

Widget JavaScript API

Drive the chat from your page with window.Kommio: open and close it, sign visitors in and out, pass page context, listen to events, or replace the button with your own.

Last updated

Before you call it

window.Kommio exists once the loader script has run. The script is async and there is no call queue, so call the API from the tag's onload, from code that runs later (a click handler, your sign-in callback), or guard it with window.Kommio &&.

<script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" async
  onload="Kommio.on('unread', function (e) { console.log('unread', e.count); })"></script>

Calls

CallWhat it does
Kommio.init(options)Starts the chat; only needed when the tag has no data-key. Takes key, position, color, locale, launcher, launcherShape, launcherIcon, launcherSize, theme, proactive, baseUrl and identity (options). Ignored while the chat is already running.
Kommio.open()Opens the chat panel.
Kommio.close()Closes it.
Kommio.toggle()Opens it when closed, closes it when open.
Kommio.isOpen()true or false.
Kommio.identify(identity)Signs the visitor in with an identity your server signed; an anonymous chat in this browser joins them. Identify signed-in visitors.
Kommio.logout()
or Kommio.identify(null)
Forgets this browser's chat session; the chat starts again as an anonymous visitor.
Kommio.setContext(object | null)Page context for the agent, such as a cart. Replaced on each call; null clears it. Details.
Kommio.on(event, fn)Listens to an event; returns a function that stops listening.
Kommio.off(event, fn)Stops a listener added with on.
Kommio.destroy()Removes the button and the chat, and drops every listener. init() can start it again.

Open and close

Kommio.open();
Kommio.close();
Kommio.toggle();
Kommio.isOpen(); // true or false

Open the chat from a help link, close it after a task, or ask whether it is open before showing something in the same corner.

Events

EventDataWhen
ready{ identified: boolean }A chat session started; again after identify() or logout(). identified says whether a signed identity is in use.
open{}The panel opened (by the visitor, your page or an agent-started chat).
close{}The panel closed.
unread{ count: number }The number of agent messages the visitor has not seen changed; 0 when they open the chat.
message{ direction: 'inbound' | 'outbound', conversation_id: number }A message was added to the visitor's conversation: inbound from the visitor, outbound from your team. Never the text.
conversation{ id: number }The visitor's conversation is known: their first message, an agent-started chat or a resumed one. For a signed-in visitor this is also the moment their contact exists.
proactive{ id }A proactive message rule showed its opener; id names the rule.
const off = Kommio.on('unread', ({ count }) => {
  document.title = count ? `(${count}) My shop` : 'My shop';
});
Kommio.on('conversation', ({ id }) => console.log('conversation', id));
Kommio.on('message', ({ direction }) => console.log(direction)); // 'inbound' | 'outbound', never the text
Kommio.on('open', () => {});
Kommio.on('close', () => {});
Kommio.on('ready', ({ identified }) => {});
off(); // stop listening

Use conversation and message for analytics (for example, a "chat started" goal), unread for your own badge, and ready to know when a sign-in took effect.

Your own chat button

Hide the round button with data-launcher="hidden" and open the chat from any element of your page, with an unread badge:

Custom launcher
<button type="button" id="help">Chat with us <span id="help-count" hidden></span></button>
<script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" data-launcher="hidden" async
  onload="Kommio.on('unread', function (e) { var b = document.getElementById('help-count'); b.hidden = !e.count; b.textContent = e.count; })"></script>
<script>
  document.getElementById('help').addEventListener('click', function () { window.Kommio && Kommio.toggle(); });
</script>

Without the round button the chat panel opens in the same bottom corner (see data-position). Give your button an accessible name, as above.

Page context

Tell the agent what the visitor is looking at, such as a cart or the plan on screen. Agents see it in the conversation's Visitor card, marked provided by the page, not verified.

// After "Add to cart"
Kommio.setContext({ cart_total: 49.9, cart_items: 2, currency: 'EUR', items: '2× Harbor Mug' });
Kommio.setContext(null); // clears it
  • A flat object of at most 30 keys; names up to 40 characters; values are strings (cut at 200 characters), numbers or booleans. Anything else, such as nested objects or arrays, is dropped key by key.
  • Each call replaces the previous context; it is stored per conversation.
  • Like the rest of the visitor context, it reaches Kommio only once the visitor has written in the chat.
  • It is unsigned, so anyone can change it from the browser. For facts agents should trust, such as the plan a customer pays for, use signed attributes.

Sign-in and sign-out

When someone signs in on your site, pass their signed identity; an anonymous chat in that browser joins them. Signing in stores the identity with the visitor's chat session and adds nothing to Contacts: the contact is created, or matched to the one carrying the same id, when they write, when an agent starts a chat with them or when they leave an email in the offline form. On sign-out, forget the session so the next person at the same computer does not see it.

// After your sign-in (identity signed by your server)
Kommio.identify(identity);
// After sign-out: the chat forgets this browser's session
Kommio.logout();

How to build identity on your server: Identify signed-in visitors.

Start it yourself

Instead of data-attributes, call init with the same options, for example from a tag manager or a framework.

// Instead of data-attributes (no data-key on the tag):
Kommio.init({ key: 'INBOX_PUBLIC_KEY', position: 'left', color: '#1F4D3A', locale: 'es', launcher: 'hidden', theme: 'auto', identity });
Kommio.destroy(); // removes the launcher and the chat

TypeScript

The loader ships no type package. This declaration matches it; put it in a .d.ts file of your project.

kommio.d.ts
type KommioIdentity = {
  id: string;
  name?: string;
  email?: string;
  hmac: string;
  email_hmac?: string;
  attributes?: Record<string, string | number | boolean>;
  attributes_hmac?: string;
};

type KommioOptions = {
  key: string;
  baseUrl?: string;
  identity?: KommioIdentity;
  position?: 'right' | 'left';
  color?: string;               // #RRGGBB
  locale?: string;              // e.g. pt-BR
  launcher?: 'default' | 'hidden';
  launcherShape?: 'circle' | 'square' | 'pill' | 'tab';
  launcherIcon?: 'chat' | 'chats' | 'headset' | 'question' | 'smile' | 'wave' | 'mark';
  launcherSize?: 'small' | 'medium' | 'large';
  theme?: 'auto' | 'light' | 'dark'; // default: the inbox's setting
  proactive?: 'off';                 // no proactive messages on this page
};

type KommioEvents = {
  ready: { identified: boolean };
  open: Record<string, never>;
  close: Record<string, never>;
  unread: { count: number };
  message: { direction: 'inbound' | 'outbound'; conversation_id: number };
  conversation: { id: number };
  proactive: { id: string };
};

interface Window {
  Kommio?: {
    init(options: KommioOptions): void;
    open(): void;
    close(): void;
    toggle(): void;
    isOpen(): boolean;
    identify(identity: KommioIdentity | null): void;
    logout(): void;
    setContext(context: Record<string, string | number | boolean> | null): void;
    on<K extends keyof KommioEvents>(event: K, fn: (data: KommioEvents[K]) => void): () => void;
    off<K extends keyof KommioEvents>(event: K, fn: (data: KommioEvents[K]) => void): void;
    destroy(): void;
  };
}

Every claim on these pages is covered by a test in the repository, and the API reference is generated from the same contract every server serves at /api/openapi. Corrections to [email protected].