JavaScript API
window.Nimbia has the functions and events below. The coming loadNimbia() returns the same object.
#How the API is named
- Anything
getState()reads back is a setting, andupdate()changes it. Anything that happens once, such as starting a guide or hanging up, is a verb that returns a promise.pauseGuide()is a verb, because whether a guide is paused belongs to the running guide and ends with it. update()changes the keys you name and leaves the rest alone. The type isNimbiaUpdateOptions; the type forboot()isNimbiaBootOptions.- Names are positive:
visible, nothidden;microphoneEnabled, notmuted. - There are no toggles.
update({ microphoneEnabled: false })leaves the microphone off whatever it was before, so two calls can't undo each other. identify()says who the visitor is and starts a new session for them.update()says how the widget behaves and leaves the session alone.- A call made before the script has loaded is queued and runs once it has. An action called before the session has started waits for it.
- The prompt a first-time visitor sees, "Ready for a 2-minute walkthrough?", is the CTA modal.
dismissCtaModal()closes it andgetState().ctaModalVisiblesays whether it shows. on()returns a function that removes the handler.
Nimbia.update({ visible: !onLoginPage, inputMode: "chat" }); // settings
await Nimbia.startGuide("guide-id"); // an action; fine before the widget is ready
const stop = Nimbia.on("guideEnded", onGuideEnded);
stop();#Wait for the widget
The widget is ready once Nimbia has started the visitor's session, a moment after boot() with a user or after identify(). Actions wait for it themselves. To wait in your own code:
await Nimbia.ready; // a promise
Nimbia.on("ready", () => {}); // an event; runs at once if the widget is already ready
Nimbia.getState().ready; // a booleangetState() exists only once the script has loaded. Before that, use Nimbia.ready or the events.
#Settings
update(options) changes the settings you name and leaves the rest alone. getState() returns their current values.
| Setting | Values | What it does |
|---|---|---|
visible |
true, false |
Shows or hides the whole widget. A running call keeps going while it's hidden. |
minimized |
true, false |
Minimizes the onboarding checklist. |
chatOpen |
true, false |
Opens the chat panel during a call. A running guide pauses while it's open. |
inputMode |
"voice", "chat" |
Whether the visitor talks to Nimbia or types. |
microphoneEnabled |
true, false |
The visitor's microphone during a call. |
speakerEnabled |
true, false |
Nimbia's voice during a call. |
basePath |
a path such as "/demo", or "" |
The path your app runs under. Guides match pages without it. |
The widget keeps a setting it can't apply yet and applies it as soon as it can. speakerEnabled: false with no call running turns Nimbia's voice off once the next call starts, and getState() shows the kept value until then. inputMode: "chat" before a call makes the next call, or the next guide, start in chat. Settings made before the script has loaded or before the session has started apply once it has.
chatOpen, inputMode, microphoneEnabled and speakerEnabled belong to a call and reset when it ends. visible and minimized stay, also across identify().
Guides find their page by its path, such as /dashboard. When your app runs under a prefix, set basePath to it: with basePath: "/demo", the page /demo/dashboard matches a guide's /dashboard. Paths outside the prefix stay as they are, so you can set it once in boot(). The widget reads it each time it sends the page to Nimbia, so set it before the first page under the prefix. basePath stays across identify().
update() logs a warning and skips a key it doesn't know or a value of the wrong type.
// Keep the widget off the login form
Nimbia.update({ visible: location.pathname !== "/login" });#Actions
Each action returns a promise. It resolves once the action has started and rejects with a NimbiaError if it can't. An action called before the widget is ready waits for it.
| Action | Resolves when |
|---|---|
startGuide(guideId, options?) |
The guide has started |
stopGuide() |
The guide has ended (at once if none is running) |
pauseGuide() |
The guide is paused. An open chat panel already pauses it, so this resolves at once then |
resumeGuide() |
The guide runs again |
startCall() |
Nimbia is listening, in voice or chat as inputMode says |
endCall() |
The call has ended (at once if there is none) |
sendText(text) |
The message is sent, as if the visitor typed it |
continueCall() |
The answer to Nimbia's "Still here?" question is sent |
dismissCtaModal() |
The CTA modal is closed and the checklist minimized, as its Skip button does |
boot(options) |
The visitor's session has started; at once without user |
identify(user) |
The new visitor's session has started |
shutdown(reason?) |
The widget is gone from the page |
#Start a guide
startGuide(guideId) starts a guide the way the Start button in the widget's checklist does. A visitor who hasn't been asked about the microphone yet is asked first whether they want to talk or type. With inputMode: "chat" the guide starts in chat without the question.
When your page asks that question itself, pass the answer as startGuide(guideId, { inputMode }) and the widget doesn't ask. With "voice" the browser asks for the microphone at once, and if the visitor refuses, the guide goes on in chat. With "chat" the widget doesn't use the microphone. Nimbia speaks in both modes.
Call it from the click that confirms the choice, before any await in your handler. Safari plays Nimbia's voice only when the page started it while handling a click, and after the first await the page no longer counts as handling the click.
startButton.addEventListener("click", () => {
Nimbia.startGuide("your-guide-id", { inputMode: voiceChosen ? "voice" : "chat" });
});try {
await Nimbia.startGuide("your-guide-id");
} catch (error) {
if (error.code === "timeout") showHelpLink();
}If you call startGuide() several times before the widget is ready, only the latest call runs, and the earlier ones reject with superseded. You find a guide's ID in the Nimbia dashboard.
startMilestone(guideId) is a deprecated alias. It skips the microphone question, as it always has.
#Errors
code |
Meaning |
|---|---|
init_failed |
The widget couldn't start a session for the visitor. It shuts itself down, so you can call boot() again |
call_failed |
A call couldn't start, or it dropped |
timeout |
The action didn't start in time (2 minutes for a guide, 1 minute for a call, 15 seconds for the rest) |
superseded |
A newer startGuide() call replaced this one before the widget was ready |
no_call |
The action needs a running call |
no_guide |
The action needs a running guide |
not_configured |
boot() had no platformId, or identify() ran before boot() named the platform |
shut_down |
shutdown() ran before the session started |
Check error.code or error.name === "NimbiaError". instanceof NimbiaError fails when the page and the widget script each have their own copy of the class.
#Events
on(event, handler) adds a handler and returns a function that removes it. once() does the same for a single run, and off(event, handler) removes a handler too.
| Event | Sent when | Payload |
|---|---|---|
ready |
The session has started | none |
change |
Anything in getState() changed |
{ state, changed }, where changed lists the keys |
guideStarted |
A guide has started | { guideId } |
guideEnded |
A guide has ended | { guideId, reason }, with reason "completed", "stopped" or "error" |
callStarted |
A call has connected and Nimbia is listening | none |
callEnded |
A call has ended | none |
error |
Starting the session or a call failed | a NimbiaError |
const stop = Nimbia.on("guideEnded", ({ guideId, reason }) => {
if (reason === "completed") analytics.track("guide_completed", { guideId });
});
// Later:
stop();#State
getState() returns the settings above plus:
| Field | Values |
|---|---|
ready |
true once the session has started |
ctaModalVisible |
true while the CTA modal shows: the prompt a first-time visitor sees, "Ready for a 2-minute walkthrough?" |
call |
"idle", "connecting" or "connected". It is "connected" once Nimbia can hear the visitor, not when the line opens |
guide |
null, or { id, step, paused }, where step is what the current step is doing ("loading", "audio_playing", "executing_dom_action", "done", "handover" or null) and paused is true while the guide is paused, by pauseGuide() or by an open chat panel |
user |
null, or { id, email, name } |
Nimbia.on("change", ({ state, changed }) => {
if (changed.includes("call")) {
document.body.classList.toggle("in-call", state.call === "connected");
}
});#TypeScript
Coming soon: the types ship with the
@nimbia/jspackage, which isn't published yet. Until then, use the script snippet; the tables on this page list every function, setting and event.
Once it's published, @nimbia/js exports the types: NimbiaUpdateOptions, NimbiaState, NimbiaEvents and its payloads, NimbiaIdentity, NimbiaError and NimbiaErrorCode, and the Nimbia interface. With the snippet, install the package for its types and add this once, which types window.Nimbia:
import type {} from "@nimbia/js/global";