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.
<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
| Attribute | Values | Default |
|---|---|---|
| data-agent-key | Public agent key from the Deploy tab | required |
| data-position | bottom-right, bottom-left | bottom-right |
| data-launcher | bubble, tab, none | bubble |
| data-open-on-load | true, false | false |
| data-greeting-delay | milliseconds before the proactive bubble appears | 0 (disabled) |
| data-locale | BCP-47 tag such as en-US or es-MX | browser 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.
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
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"));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.
