SDK & User Tracking¶
Once the ChannelX widget is on your site, the JavaScript SDK lets you do far more than show a chat bubble. You can identify logged-in users, attach custom data to their conversations, control the widget's appearance and behavior programmatically, and validate identities so nobody can impersonate your customers.
Getting started with the SDK¶
When the widget loads, it exposes a window.$chatwoot object. Because the script loads asynchronously, wait for the chatwoot:ready event before calling any SDK method:
window.addEventListener("chatwoot:ready", function () {
// window.$chatwoot is now available
});
You can also listen for messages and errors:
window.addEventListener("chatwoot:on-message", function (e) {
console.log("chatwoot:on-message", e.detail);
});
window.addEventListener("chatwoot:error", function () {
// handle widget errors here
});
Widget settings¶
Configure the widget's defaults with a window.chatwootSettings object before the SDK runs:
window.chatwootSettings = {
hideMessageBubble: false,
showUnreadMessagesDialog: false, // disable the unread message dialog
position: "left", // "left" or "right"
locale: "en", // widget language
useBrowserLanguage: false, // use the visitor's browser language
type: "standard", // "standard" or "expanded_bubble"
darkMode: "auto", // "light" or "auto"
// baseDomain: "yourdomain.com" // track users across subdomains
};
A few notes:
- Browser language — set
useBrowserLanguage: trueto match the visitor's browser locale. When on, it overrideslocale; if the browser language isn't supported, the widget falls back tolocale, then to the agent dashboard's language. - Expanded bubble — with
type: "expanded_bubble", setlauncherTitleto customize the bubble text:
window.chatwootSettings = {
type: "expanded_bubble",
launcherTitle: "Chat with us",
};
- Popout window — set
showPopoutButton: trueto let users open the chat in its own window. - Custom header and status messages:
window.chatwootSettings = {
welcomeTitle: "Need help?",
welcomeDescription: "We're here to support you.",
availableMessage: "We're online and ready to chat!",
unavailableMessage: "We're currently offline.",
};
- Feature toggles — selectively enable UI features:
window.chatwootSettings = {
enableFileUpload: true, // file attachment button
enableEmojiPicker: true, // emoji picker in the input
enableEndConversation: true, // let users end the conversation
};
Controlling the widget programmatically¶
window.$chatwoot.toggle(); // toggle the widget
window.$chatwoot.toggle("open"); // open it
window.$chatwoot.toggle("close"); // close it
window.$chatwoot.popoutChatWindow(); // open the popout window
window.$chatwoot.toggleBubbleVisibility("show"); // show the bubble
window.$chatwoot.toggleBubbleVisibility("hide"); // hide the bubble
window.$chatwoot.setLocale("en"); // set language at runtime
Sending user information¶
If you know who the visitor is — because they're signed in to your app — pass that to ChannelX with setUser. The first argument is a unique identifier (a user ID from your database or any stable unique value); the second is an object of profile details:
window.$chatwoot.setUser("<unique-identifier>", {
email: "user@example.com",
name: "Jane Doe",
avatar_url: "https://example.com/avatar.png",
phone_number: "+15551234567",
});
Always reset the session when the user signs out of your app:
window.$chatwoot.reset();
Custom attributes and labels¶
Attach extra structured data to the contact or conversation. Values are typed (string, number, or date) and surface in the conversation's side panel:
window.$chatwoot.setCustomAttributes({
accountId: 1,
pricingPlan: "paid",
});
window.$chatwoot.deleteCustomAttribute("pricingPlan");
You can also set or remove a conversation label. Labels only apply once a conversation has started:
window.$chatwoot.setLabel("support-ticket");
window.$chatwoot.removeLabel("support-ticket");
Identity validation (HMAC)¶
Passing an identifier is enough to recognize a returning user, but on its own it could be spoofed by anyone who knows the value. To prevent impersonation and keep conversations private, ChannelX supports identity validation using an HMAC (a SHA-256 hash-based message authentication code) generated from the user's identifier.
You compute the hash on your server, using a secret token, and pass the result to the widget as identifier_hash. Because the secret never reaches the browser, a malicious user can't forge a valid hash for someone else.
Keep the HMAC token secret
The widget HMAC token is a credential. Generate the hash only on your server, never in client-side JavaScript, and never expose the token in your front-end code or version control. Anyone with the token can impersonate any of your users.
Find your token¶
Open Inboxes → Settings → Configuration → Identity Validation and copy the token shown there. Each website widget has its own token.
Generate the hash¶
Compute an HMAC-SHA256 of the identifier using the token as the key. Examples:
Node.js
const crypto = require("crypto");
const key = "<widget-hmac-token>";
const message = "<identifier>";
const hash = crypto.createHmac("sha256", key).update(message).digest("hex");
Ruby
require "openssl"
key = "<widget-hmac-token>"
message = "<identifier>"
OpenSSL::HMAC.hexdigest("sha256", key, message)
Python
import hashlib, hmac
secret = bytes("<widget-hmac-token>", "utf-8")
message = bytes("<identifier>", "utf-8")
hash = hmac.new(secret, message, hashlib.sha256).hexdigest()
PHP
<?php
$key = "<widget-hmac-token>";
$message = "<identifier>";
$identifier_hash = hash_hmac("sha256", $message, $key);
Go
secret := []byte("<widget-hmac-token>")
message := []byte("<identifier>")
h := hmac.New(sha256.New, secret)
h.Write(message)
hex.EncodeToString(h.Sum(nil))
Pass the hash to the widget¶
Include identifier_hash in your setUser call, alongside any other profile details:
window.$chatwoot.setUser("<unique-identifier>", {
name: "Jane Doe",
email: "user@example.com",
avatar_url: "https://example.com/avatar.png",
phone_number: "+15551234567",
identifier_hash: "<hash-generated-on-your-server>",
description: "",
country_code: "",
city: "",
company_name: "",
social_profiles: {
twitter: "",
linkedin: "",
facebook: "",
github: "",
},
});
With identity validation enabled, chat history persists reliably across sessions for the verified user.
Common questions¶
Do I need identity validation? If you pass real user identifiers, yes — it's strongly recommended. Without it, the identifier alone could be guessed or reused to access another customer's conversation.
Where must the HMAC be generated? On your server only. Generating it in the browser would expose the secret token.
What happens when a user logs out?
Call window.$chatwoot.reset() to clear the session so the next visitor starts fresh.