Put chat on your site

Add the chat widget to your site

One script tag puts your website chat inbox on every page. Quick start, step-by-step guides for HTML, Google Tag Manager, WordPress, Shopify and React or Next.js, and how to check that it works.

Last updated

Everything on this page is also in the product, with your inbox's real key filled in: Settings → Inboxes → your website chat inbox → Install. From there you can copy the snippet, email the instructions to a developer, and open a demo store with your chat already installed.

Quick start

  1. Create a website chat inbox

    Settings → Inboxes → add an inbox → Website chat. The last step of the wizard shows the snippet. Each inbox has its own public key: it only addresses the inbox and is safe to publish.

  2. Paste the snippet before </body> on every page

    Every page
    <!-- Kommio chat: paste before </body> on every page -->
    <script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" async></script>

    The chat button appears in the bottom corner. Colours, greeting and texts you set in Kommio apply without any further attributes.

  3. Check that it works

    Open a page of your site that has the snippet, then look at the Installation check on the inbox's Install tab (see below).

Platform guides

Step by step for the most common ways to build a site. Replace INBOX_PUBLIC_KEY with your inbox's key, or copy the ready-made code from the Install tab.

HTML

  1. Open the template or layout that every page shares.
  2. Paste the snippet just before the closing </body> tag.
  3. Publish, open your site and look for the chat button.
layout.html
<script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" async></script>
  </body>
</html>

Google Tag Manager

  1. In your container, go to Tags → New → Tag configuration → Custom HTML.
  2. Paste the code below.
  3. Under Triggering choose All Pages (or Initialization – All Pages).
  4. Save, then Submit and Publish the container.
Custom HTML tag
<script>
  (function () {
    var s = document.createElement('script');
    s.src = 'https://app.kommio.io/widget/widget.js';
    s.async = true;
    s.onload = function () { window.Kommio.init({ key: 'INBOX_PUBLIC_KEY' }); };
    document.body.appendChild(s);
  })();
</script>

A tag manager inserts the script without the data-key attribute, so the chat is started with Kommio.init(), which takes the same options.

WordPress

  1. Easiest: install a header and footer plugin (for example WPCode), open its Footer box and paste the snippet.
  2. Or, with a child theme, add the PHP below to functions.php.
  3. Clear any caching plugin, then open your site.
<script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" async></script>

Shopify

  1. In Shopify admin go to Online Store → Themes.
  2. On your live theme choose ⋯ → Edit code, then open layout/theme.liquid.
  3. Paste the snippet just before </body> and save.
layout/theme.liquid
<script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" async></script>
  </body>

React and Next.js

  1. Next.js: add the Script tag to the root layout, once.
  2. Other React apps: call the hook once in your root component.
  3. Do not load it per page: one load follows every route change.
app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script src="https://app.kommio.io/widget/widget.js" data-key="INBOX_PUBLIC_KEY" strategy="afterInteractive" />
      </body>
    </html>
  );
}

Single-page apps: the widget follows pushState, replaceState and popstate by itself, so the agent sees each page. After your own sign-in call Kommio.identify(identity), and after sign-out Kommio.logout() (see Identify signed-in visitors). For TypeScript, a declaration for window.Kommio is on the JavaScript API page.

Check that it works

When the widget loads, it tells Kommio which site it is on. The inbox's Install tab shows Installed · Last seen on <site>, <when>, recorded at most once a minute, or Not detected yet: open a page that has the snippet, then choose Check again. The site is what the page reports, so treat it as an aid, not proof.

Before your site is ready, open the demo store from the Install tab: a fictional shop with your chat installed and a "Try the widget" panel that signs in a test customer, passes a cart, triggers a JavaScript error, changes position and language, switches the chat's colours (the inbox's setting, auto, light or dark) and the store's own colours (to watch auto follow the page), drives the API and shows the widget's events.

The demo store's address takes the same options as parameters: /widget/demo/?key=KEY&position=left&color=%23AA0000&locale=es&theme=dark, and &store=dark shows the store itself in dark colours.

Choose which websites may show the chat

By default any website may show your chat. Add your sites under the Install tab's Allowed websites (scheme and host only, such as https://www.example.com; include every variant you use, with and without www). The chat runs in a frame served by Kommio, and with a list Kommio tells the browser, through Content-Security-Policy: frame-ancestors, to show that frame only inside those sites, so a copied snippet shows nothing elsewhere. Kommio's own pages, such as the demo store, are always allowed.

Visitors' files

Visitors attach files with the chat's button, by pasting or by drag-and-drop. Each inbox sets what they may attach (Settings → Inboxes → the inbox → Visitors' files):

  • Accepted files: images, PDF, text and office documents; images and PDF; images only; or none, which removes the attach button.
  • Largest file: 1–25 MB, 10 by default.
  • Files per message: 1–10, 5 by default.

Each visitor can upload up to 20 files an hour. The widget learns the inbox's limits from its config (GET /api/widget/{key}/config), and Kommio checks them again on the upload and on the message, so a changed page cannot get around them.

Widget config (files)
{
  "files": {
    "extensions": [".png", ".jpg", ".jpeg", ".gif", ".webp", ".pdf"],
    "max_size_mb": 10,
    "max_per_message": 5
  }
}

Content Security Policy on your site

If your site sends a Content Security Policy, allow the loader and the chat frame:

CSP additions
script-src https://app.kommio.io;
frame-src  https://app.kommio.io;

If your workspace has a logo mark set in Branding, the launcher shows it as an image, so add its address to img-src as well (https://app.kommio.io for an uploaded mark). The loader injects no stylesheets, fonts or third-party scripts: it draws the button and the frame with inline element styles and talks to the frame through postMessage.

Languages

The chat ships in 16 languages: en, pt-BR, es, fr, de, it, nl, pl, tr, id, ja, ko, zh-CN, hi, fil and ur. Urdu (ur) is right to left: the panel mirrors, while the launcher keeps the corner set on the inbox. A browser that asks for Tagalog (tl) gets Filipino. It uses data-locale when you set a supported one, otherwise the visitor's browser languages, otherwise English.

What your visitors get

  • A button in the bottom corner with an unread count while the chat is closed, and the chat in a panel above it.
  • A pre-chat form when the inbox asks for a name or an email; signed-in visitors skip it.
  • Their conversation across page loads: the loader keeps the chat session in your site's local storage (kommio.token.<key>), so browsers that partition third-party storage do not lose the thread.
  • Attention without noise when an agent writes while the chat is closed: the button bounces once per burst, a preview bubble shows the agent's name and the start of the message for 8 seconds, the tab title counts while the tab is hidden, and a soft two-note chime plays (only after the visitor has interacted with the page, at most once every 3 seconds). Reduced-motion settings drop the movement. Visitors can mute the sound in the chat header, and you can turn it off per inbox.
  • When nobody is online, a question about where to reply, a follow-up email with the answers they missed, and a transcript on request (away email and follow-ups).

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].