Widget installation
This page is for the web developer installing the chat widget. It's a single script tag — no build steps, no packages, works with any framework or CMS.
Before you start
- Whitelist the site's domains. In the admin area, open the client and go to Settings → Install on your site → Allowed domains. One domain per line;
*.example.comcovers all subdomains;localhost(with or without a port) is accepted for local testing. On any other domain the widget stays silently absent — no error, no widget. - Find the snippet. The exact snippet — with the correct host and site ID already filled in — is shown in the same section, with a Copy snippet button. The site ID (starts with
pk_) is also displayed in the client header, top right.
Option A: floating popup (most common)
Paste before </body> on every page where the chat should appear:
<script async src="https://<your-platform-host>/widget/loader.js" data-site-id="pk_..."></script>
A launcher button appears in the configured corner; clicking it opens the chat panel. The script is async and tiny — it does not block page rendering.
Option B: inline block
Renders the chat as a block inside the page (e.g. on a dedicated support page) instead of a floating popup:
<div id="compent-chat-inline"></div>
<script async src="https://<your-platform-host>/widget/loader.js" data-site-id="pk_..." data-mode="inline"></script>
- Place the
<div>where the chat should appear. - To use your own container instead, drop the div and add
data-target="#your-selector"to the script tag. - Height, max width, alignment and border are configured in the admin under Settings → Widget appearance → Inline embed layout.
Content-Security-Policy
If the site sends a strict CSP, allow the platform host in both directives:
script-src https://<your-platform-host>;
connect-src https://<your-platform-host>;
Testing locally
- Add
localhost(orlocalhost:8080etc.) to Allowed domains. - Serve your page and load it — the widget appears exactly as in production.
- Alternatively, skip local setup entirely and use the Playground tab, which runs the real widget against the real chat API inside the admin.
JavaScript API
The loader defines a global CompentChat function. Calls made before the widget finishes loading are queued and replayed, so you can call it immediately after the script tag.
| Call | What it does |
|---|---|
CompentChat("open") / ("close") / ("toggle") | Opens/closes the popup panel (ignored in inline mode, which is always visible). |
CompentChat("clear") | Clears this browser's current conversation and starts the next message in a new conversation. Useful from SPA route handlers or your own "new chat" button. |
CompentChat("identify", { userId, name, email, ...vars }) | Tells the widget who the visitor is. Values are usable as {{tokens}} in the title/welcome texts (see Languages); userId also gives the visitor a per-user rate-limit bucket. |
CompentChat("identify", { userToken: <string or function> }) | Passes a verified identity token signed by your backend — see Identity and access. A function is called automatically whenever a fresh token is needed. |
CompentChat("language", "da") | Switches the widget language ("en" or "da"). |
CompentChat("on", event, handler) | Subscribes to widget events (below). |
Events for CompentChat("on", ...):
message:beforeSend— fired before a visitor message is sent; returnfalsefrom the handler to cancel it.message:beforeRenderandmessage:rendered— fired around each message appearing in the chat.identity:expired— fired once when a static identity token expires, so you can fetch a fresh one and callidentifyagain.
Handler errors never break the widget or the page — every callback is wrapped.
Controlling appearance at runtime
The page can also adjust how the widget looks and behaves — useful for matching a site-wide dark/light toggle live, or giving one page a different placement or size:
CompentChat("theme", { primaryColor: "#0ea5e9", backgroundColor: "#0b1220", textColor: "#e2e8f0", radius: 14, fontFamily: "Inter, sans-serif" });
CompentChat("position", "bottom-left"); // popup corner: "bottom-left" or "bottom-right"
CompentChat("size", { width: 420, height: 560 }); // popup panel size in px (kept within the viewport)
CompentChat("inline", { height: 640, maxWidth: 900 }); // inline block size in px (height 320–1600; maxWidth 0 = fill)
CompentChat("showSources", false); // hide the source chips under answers on this page
CompentChat("config", { theme: {...}, position: "...", size: {...}, inline: {...}, showSources: true }); // set several at once
Rules of thumb:
- Page-scoped only. Nothing is saved — a reload returns to the settings configured in the admin. Use the admin's Widget appearance for the permanent look.
- Any subset works — pass only the theme keys you want to change. Colors must be 6-digit hex (
#0ea5e9); the corner radius is kept within 0–32. - Invalid values are silently ignored — a typo can never break the widget or your page. Calls made before the widget loads are queued and replayed, like every other command.
sizeapplies to the floating popup;inlineapplies to the inline block embed.
Example — follow the site's dark-mode switch:
function applyChatTheme(dark) {
CompentChat("theme", dark
? { backgroundColor: "#0b1220", textColor: "#e2e8f0" }
: { backgroundColor: "#ffffff", textColor: "#111827" });
}
Example — greet logged-in users by name:
<script>
window.CompentChat = window.CompentChat || function(){(CompentChat._q=CompentChat._q||[]).push(arguments)};
CompentChat("identify", { userId: "u-123", name: "Anna" });
</script>
Good to know
- The widget renders inside a shadow DOM — your site's CSS can't accidentally break it, and its styles never leak out.
- Visitors' conversation, language choice and (if enabled) dragged position/size are remembered per browser via local storage. In Settings -> Widget appearance, Clear chat on page reload keeps the conversation only for the current page life; SPAs can also call
CompentChat("clear")whenever their routing should start fresh. - Installing the snippet on a not-yet-whitelisted staging domain is safe: the widget simply doesn't render there.
Next: make it match your brand under Widget appearance, or wire up verified logins under Identity and access.