window.Kelu exists only once the widget script has loaded, and the script loads async. Code that runs earlier, such as analytics setup in your <head>, finds nothing to call. A preinitialization stub fixes this. It defines window.Kelu as a function that queues every call. When the widget loads, it replaces the stub and runs the queue.

Setup

Put this on every page that has the widget, as early as possible, ideally in <head> before the widget’s own tag:
<head>
  <script>
    (function () {
      let k = window.Kelu;
      if (!k) {
        let i = function () {
          i.c(arguments);
        };
        i.q = [];
        i.c = function (args) {
          i.q.push(args);
        };
        window.Kelu = i;
      }
    })();
  </script>
</head>
It is kapa.ai’s window.Kapa stub with the name changed. The widget reads only window.Kelu.

Usage

Call functions by name, with the argument after it:
// Instead of window.Kelu.open({ query: "how to get started" })
window.Kelu("open", { query: "how to get started" });

window.Kelu("onModalOpen", ({ mode }) => console.log("opened on", mode));
window.Kelu("setSourceGroupIDs", ["group-id-1"]);
This form works before and after the script loads. The method form, window.Kelu.open(), works only after.

When queued calls run

Queued callRuns
Event subscriptions, such as Kelu("onModalOpen", fn)As soon as the script loads, so no event is missed
Functions: open, close, render, unmount, setSourceGroupIDs, getSourceGroupIDsIn the order you queued them, once the widget is configured: by the script tag’s attributes, or by your first KeluWidget.init() call
  • A queued open waits until the widget is on the page.
  • A queued getSourceGroupIDs has nowhere to return its value. Call it after the script loads.
  • Any other name logs a warning. window.KeluWidget is not queued; it exists only after the script loads.
With data-render-on-load="false", a queued open on its own does nothing, because nothing is on the page yet. Queue render with open in its onRender instead:
window.Kelu("render", { onRender: () => window.Kelu("open") });
See Widget lifecycle.