Docs

cxthread Website Widget

Add a support widget with one script tag, then tune live chat, business-hour fallback, and theme styling from your app.

Quick start

Start in Admin → Inboxes → choose inbox → Widget setup.

  • 1) Generate or rotate a dedicated widget token.
  • 2) Pick live chat behavior and business hours.
  • 3) Copy the embed snippet into your website template.
  • 4) Place the script before </body>.
  • 5) Open your site and confirm the launcher appears.
If you already expose authenticated customer data on your site, wire user prefill now. It improves ticket identity quality immediately.

Minimal embed

This is the smallest valid installation.

<script
  src="https://YOUR_CXTHREAD_DOMAIN/cxthread-widget.js"
  data-widget-token="cxwt_REDACTED"
></script>

The widget runs in a hosted iframe to avoid CSS and JavaScript collisions with your site code.

Mode behavior

data-mode="auto"

Uses workspace availability + business hours to decide between live chat and form fallback.

data-mode="form"

Always uses async ticket form behavior, even when agents are online.

Config precedence

  • 1) Runtime API calls (for example window.cxt.setTheme()) take immediate precedence.
  • 2) Script attributes (data-*) override matching config keys.
  • 3) window.cxtConfig is the base config.

Keep static defaults in window.cxtConfig, then use runtime APIs when page state changes.

Script attributes

Required

  • data-widget-token: widget token for the inbox.

Optional

  • data-title: header title override.
  • data-primary: primary hex color.
  • data-mode: auto or form.
  • data-position: left or right.
  • data-open: set to true to start open.
  • data-theme: JSON or URI-encoded JSON.
  • data-theme-mode: auto, dark, or light.
  • data-user-email, data-user-name, data-user-id: user prefill.

data-api-key is accepted as a legacy alias, but new installs should use data-widget-token.

Theme and styling

Theme values can be set from script attributes, config object, or runtime API.

Branding

  • themeMode: auto/system, forced dark, or forced light.
  • primary: launcher + primary action color (hex only, #RRGGBB).
  • textOnPrimary: text on primary surfaces.
  • launcherLabel: closed launcher text.
  • launcherCloseLabel: open launcher text.

Shape and placement

  • borderRadius: launcher radius (8–32).
  • frameBorderRadius: frame radius (8–32).
  • width: 280–720 px.
  • height: 360–960 px.
  • offsetX/offsetY: 0–72 px.
  • position: left or right.
  • zIndex: 1–2147483647.

Example theme payload:

window.cxtConfig = {
  theme: {
    themeMode: "auto",
    primary: "#4a3dd6",
    textOnPrimary: "#ffffff",
    launcherLabel: "Need help?",
    launcherCloseLabel: "Close",
    borderRadius: 18,
    frameBorderRadius: 16,
    width: 380,
    height: 640,
    offsetX: 16,
    offsetY: 16,
    position: "right",
    zIndex: 2147483000
  }
};

Runtime API

Use runtime methods when your app needs to open, close, or retheme the widget dynamically.

window.cxt.open();
window.cxt.close();
window.cxt.toggle();
window.cxt.isOpen();
window.cxt.getState();
window.cxt.setThemeMode("dark"); // "auto" | "dark" | "light"
window.cxt.setTheme({ primary: "#5b4bff" });
window.cxt.setPosition("left");
window.cxt.setUser({ email: "user@example.com", name: "User", id: "u_123" });
window.cxt.identify({ email: "user@example.com", name: "User", id: "u_123" }); // alias
window.cxt.clearUser();
const unsubscribe = window.cxt.onStateChange((state) => console.log(state));

State changes also emit cxthread:widget:state on window.

window.addEventListener("cxthread:widget:state", (event) => {
  console.log(event.detail);
});

Late identity pattern

Use this when user identity is resolved after page load.

// Safe pre-load queue (before widget script is loaded):
window.cxt = window.cxt || {};
window.cxt.q = window.cxt.q || [];
window.cxt.q.push([
  "identify",
  { email: "signed-in@customer.com", name: "Signed In Customer", id: "customer_123" }
]);

// Or after widget is loaded:
window.cxt?.identify?.({ email: "signed-in@customer.com", id: "customer_123" });

identify, setIdentity, and setUser all map to the same behavior.

User identity and session

If you know the signed-in user, pass identity so tickets map back to real customers.

window.cxtConfig = {
  user: {
    email: currentUser.email,
    name: currentUser.fullName,
    id: currentUser.id
  }
};
  • Session state is stored in a signed cookie for resume across page loads.
  • Identity updates via setUser() apply on the next interaction/open cycle.
  • First live-chat message requires email unless you prefill one from your app.

Live chat behavior

  • Live chat is available when the widget is enabled, mode is auto, and workspace availability allows it.
  • If “Require identity before first message” is enabled in Admin, visitors are prompted for name then email in-chat before the first message is routed.
  • When live chat is not available, the widget uses async ticket-form flow.
  • Live stream reconnects automatically after transient failures.
  • Messages stay attached to one ticket thread by ticket token + widget session ID.

Slack integration

  • Widget inbound messages post to the ticket Slack thread.
  • Admin ticket live-chat sends are mirrored to both widget and Slack.
  • cxthread Slack actions are mirrored to widget for widget-linked tickets.
  • Internal notes are never sent to widget visitors.

Troubleshooting

Widget does not render

Verify the script is loaded and data-widget-token is present.

Invalid token errors

Regenerate the widget token in Admin and update your site embed.

Theme not applying

Confirm color values are six-digit hex and data-theme is valid JSON.

Current limitations

  • No typing indicators yet.
  • No launcher unread badge yet.
  • File upload in widget chat is not implemented yet.
  • Generic manual Slack thread replies are not auto-mirrored unless sent through cxthread actions.

Security notes

Widget tokens are browser-visible by design. Rotate tokens if they are leaked or abused.

For stricter control, call the server-side API from your backend instead of direct browser widget calls.