Chat

Web Widget

A single script tag puts a Katexs agent on any page. The widget loads asynchronously, weighs under 40 KB gzipped, and inherits nothing from your stylesheet unless you tell it to.


Install the snippet

Copy the snippet from Creator โ†’ Deploy โ†’ Web Widget and paste it before the closing body tag. The public key is safe to expose; it is scoped to the single agent and rate-limited per visitor.

html
<script
  src="https://cdn.katexs.com/widget/v1.js"
  data-agent-key="pk_live_9f4c2ab0e7"
  data-position="bottom-right"
  async
></script>

For single-page apps, load the script once at the app shell level and let the widget survive route changes. Mounting it inside a route component remounts the conversation on every navigation.

Configure at load time

AttributeValuesDefault
data-agent-keyPublic agent key from the Deploy tabrequired
data-positionbottom-right, bottom-leftbottom-right
data-launcherbubble, tab, nonebubble
data-open-on-loadtrue, falsefalse
data-greeting-delaymilliseconds before the proactive bubble appears0 (disabled)
data-localeBCP-47 tag such as en-US or es-MXbrowser locale

Customise appearance

Theming is set in Creator so marketing can change it without a deploy, and overridden at runtime when you need per-page control. Colours accept any CSS colour value; the widget derives hover, border, and focus states automatically.

js
window.Katexs = window.Katexs || [];
window.Katexs.push(["theme", {
  surface: "#0b0b0f",
  onSurface: "#f5f7fa",
  bubble: "#ffffff",
  radius: 14,
  fontFamily: "inherit",
  launcherIcon: "https://cdn.example.com/mark.svg",
  headerTitle: "Ask us anything",
  headerSubtitle: "Replies in seconds"
}]);
  • fontFamily: inherit โ€” Pulls your site's font into the widget. Any other value loads nothing extra โ€” supply a font already on the page.
  • Shadow DOM by default โ€” Your global CSS cannot leak in and the widget cannot leak out. Set data-shadow="false" only if you deliberately want to style it from outside.
  • Dark and light โ€” One theme object; the widget computes readable contrast. Pass a second object under theme.dark to swap on prefers-color-scheme.

Control the widget from your code

js
Katexs.open();
Katexs.close();
Katexs.send("I need help with order 40128");
Katexs.identify({ id: "usr_812", email: "dana@example.com", plan: "pro" });
Katexs.on("message", (m) => analytics.track("chat_message", { role: m.role }));
Katexs.on("handoff", () => analytics.track("chat_handoff"));
Calling identify() before the visitor opens the widget lets the agent greet them by name and skip verification questions. See Variable Substitution for how those fields reach the prompt.

Domain allowlisting

Each public key is bound to a list of origins in Creator โ†’ Deploy. Requests from an origin that is not on the list are rejected before the model is invoked, so a copied snippet cannot run up your usage on someone else's site. Add localhost explicitly for development.

Accessibility

  • Keyboard complete โ€” The launcher is a real button, the panel traps focus while open, and Escape closes it.
  • Screen readers โ€” New messages are announced through a polite live region; the transcript is a labelled log.
  • Motion โ€” All entrance animations respect prefers-reduced-motion.