Documentation

Install the widget

One tag, no build step, no framework integration. Paste it into your page template — ideally just before the closing </body> — and the bubble appears on every page that renders it.

Embed snippet

<script src="https://livechat-api.seu33.brandmill.nl/widget.js" data-website-id="11111111-1111-4111-8111-111111111111" async></script>

Configuration

  • data-website-id — required. The public id of the website you are installing on. Find it in the dashboard under Settings → Websites; it is a UUID, safe to expose in page source, and it is what ties an incoming visitor to your workspace. The id above is the seeded demo website.
  • async — keep it. The loader is ~2 KB and must never block your first paint. It injects a positioned iframe, so the widget gets its own CSS scope: your stylesheet cannot leak into the chat, and the chat cannot leak into your layout. The iframe resizes itself between bubble and panel as the visitor opens and closes it.
  • Appearance and behaviour live in the dashboard, not in the tag. Colour, position, title, subtitle, welcome message, reply-time text, whether the widget hides when your team is offline, and whether to ask for an email up front are all part of the website's widget config, delivered to the browser in the boot payload. Change them at the dashboard and every page picks the change up on next load — no redeploy of your site.

What happens after the tag loads

The concepts below are specified in full in docs/CONTRACT.md, the single source of truth for every endpoint and event in LiveChat. This page is the short version.

Boot. The widget posts the website id, the current page URL and the referrer to the boot endpoint, and gets back a visitor token, your widget config, whether your team is currently online, any open conversation with its last fifty messages, and the proactive triggers configured for the site. The token is kept in localStorage, which is what makes a conversation survive a page navigation instead of restarting on every click.

Realtime. From then on the widget holds a websocket on the visitor namespace, authenticated with that same token. Messages carry a client-generated UUID so a retry can never duplicate a message, and the server's ids and timestamps are the ordering truth. Typing events — including the MagicType preview — and presence are ephemeral and never stored.

Passive until contacted. Loading the tag does not create a conversation, and neither does a trigger firing. A conversation exists the moment a visitor actually sends something — which is also the moment your agents get their badge and their sound.