render() and unmount() control whether the widget is on the page. You need them most in single-page apps, where the widget lives outside your component tree and otherwise stays on every route once loaded.

Overview

  • render() puts the widget on the page. On window.Kelu it takes an onRender callback that runs once the widget is there. Open the panel from that callback.
  • unmount() removes it and keeps its configuration, so the next render() brings it back. Event subscriptions survive both.
The widget is in one of three states:
StateWhat the reader sees
UnmountedNothing
Mounted and closedThe launcher, or your own open button
Mounted and openThe panel
Add data-render-on-load="false" to the script tag to start unmounted: the script loads its configuration and shows nothing until render() is called.
The conversation is kept for the browser tab by default (data-persist="session"), so a reader finds it again when the widget renders on the next route. Set data-persist="none" to start empty each time.

Preinitialize first

Your code usually calls render() before the async script has loaded. Preinitialize window.Kelu so those calls are queued, not lost.

Examples

These call a loadScriptIfNotExists() helper, shown in the appendix, that adds the widget’s tag with rendering turned off.

Vanilla JavaScript

loadScriptIfNotExists();

// Show the widget, then open it
window.Kelu("render", {
  onRender: () => window.Kelu("open"),
});

React

Return unmount as the effect’s cleanup, and the widget leaves with the component.
useEffect(() => {
  loadScriptIfNotExists();
  window.Kelu("render", {
    onRender: () => window.Kelu("open"),
  });
  return () => window.Kelu("unmount");
}, []);
Both need the preinitialization stub on the page, because the effect can run before the script has loaded.

Appendix: setup function

function loadScriptIfNotExists() {
  const scriptSrc = "https://widget.kelu.dev/kelu-widget.js";

  // Already on the page: nothing to do
  if (document.querySelector(`script[src="${scriptSrc}"]`)) return;

  const script = document.createElement("script");
  script.async = true;
  script.src = scriptSrc;

  const attributes = {
    "data-knowledge-base-id": "YOUR_KNOWLEDGE_BASE_ID",
    "data-client-key": "kl_pk_...",
    "data-product-name": "Acme Docs",
    "data-brand-color": "#0070f3",
    "data-render-on-load": "false",
  };
  Object.entries(attributes).forEach(([key, value]) => {
    script.setAttribute(key, value);
  });

  document.head.appendChild(script);
}
Without data-render-on-load="false", the widget appears as soon as the script loads, on whatever route that happens to be.

Without window.Kelu

For code that runs after the script has loaded:
window.Keluwindow.KeluWidget
Kelu("render", { onRender })KeluWidget.render(), with no callback
Kelu("unmount")KeluWidget.unmount()
noneKeluWidget.destroy(): remove the widget and forget its configuration. Only init() can bring it back