@singular-health/chatbase
v1.0.4
Published
Typed wrapper for the Chatbase embed widget — bootstrap, widget control, events, i18n, and client-side custom actions.
Maintainers
Keywords
Readme
@singular-health/chatbase
Typed TypeScript wrapper for the Chatbase embed widget.
Bootstrap, widget control, event listeners, i18n, and client-side custom actions — all in one small package.
Features
| Capability | Description |
| ------------------ | ------------------------------------------------------------------------------ |
| Bootstrap | Dynamically loads the Chatbase embed script with call-queue buffering |
| Widget control | openChat(), closeChat(), resetChat() |
| Events | Strongly-typed on() / off() with automatic cleanup via destroy() |
| i18n | Detect browser language, configurable translation map, runtime language switch |
| Custom actions | Register client-side tool handlers with built-in error wrapping |
| Identity | Placeholder user config for future JWT / hash identity verification |
| Browser safety | SSR guards, no duplicate injection, DOM-ready handling |
Install
npm install @singular-health/chatbase
# or
yarn add @singular-health/chatbaseQuick start (npm / TypeScript)
import { initChatbase, openChat, on } from "@singular-health/chatbase";
await initChatbase({
botId: "YOUR_BOT_ID",
debug: true,
translations: {
en: ["Hi!", "How can I help you today?"],
es: ["¡Hola!", "¿Cómo puedo ayudarte hoy?"],
},
});
// Listen for user messages
const unsub = on("user-message", (evt) => {
console.log("User said:", evt.content);
});
// Open the widget programmatically
openChat();Quick start (browser <script> tag)
<script src="https://your-cdn.example.com/singular-chatbase/dist/index.browser.js"></script>
<script>
SingularChatbase.initChatbase({
botId: "YOUR_BOT_ID",
debug: true,
});
</script>The browser bundle exposes the global SingularChatbase with all public API functions.
API Reference
initChatbase(config): Promise<void>
Initialise the widget. Safe to call multiple times (returns the same promise).
Config options
| Key | Type | Default | Description |
| ----------------- | ---------------------------- | ------------------- | ------------------------------------ |
| botId | string | required | Your Chatbase bot / agent ID |
| domain | string | "www.chatbase.co" | Chatbase domain |
| language | string | auto-detected | BCP-47 language code |
| autoLoad | boolean | true | Inject embed script immediately |
| debug | boolean | false | Print diagnostic console messages |
| initialMessages | string[] | — | Static initial messages |
| translations | TranslationMap | built-in en/es | Language-keyed greeting messages |
| eventHandlers | Record<EventName, Handler> | — | Event listeners registered on init |
| customActions | CustomActionMap | — | Client-side tools registered on init |
| user | ChatbaseUserIdentity | — | Identity/auth placeholder |
| scriptUrl | string | Chatbase default | Override embed script URL |
Widget control
openChat(); // Open the chat widget
closeChat(); // Close the chat widget
resetChat(); // Reset the chat session
isInitialized(); // Returns true when widget is ready
destroy(); // Remove all listeners and clear stateLanguage
setLanguage("es"); // Switch language and reset chat
setInitialMessages(["Hello!"]); // Manually override messagessetLanguage resolves messages from the translations map and calls resetChat() so the new greeting appears immediately.
Events
import { on, off } from "@singular-health/chatbase";
// Subscribe — returns an unsubscribe function
const unsub = on("user-message", (event) => {
console.log(event.content);
});
// Unsubscribe
unsub();
// or
off("user-message", handler);Known event names: "user-message", "agent-message", "action".
Any string is accepted for forward-compatibility.
Client-side custom actions
import { registerClientActions } from "@singular-health/chatbase";
registerClientActions({
get_weather: async (args, user) => {
const res = await fetch(`/api/weather?loc=${args.location}`);
const data = await res.json();
return { status: "success", data };
},
});Action names must match the names configured in the Chatbase dashboard.
All handlers are wrapped with error fallback — uncaught exceptions return { status: "error", error: "<message>" } automatically.
Demo page
A simple test page is included at demo/index.html.
# 1. Build the package
npm run build
# 2. Serve the project root
npx serve .
# 3. Open http://localhost:3000/demo/ in a browserEnter your Bot ID, click Initialize, and use the controls to test widget behaviour.
Event logs and custom action invocations are printed to the on-screen log.
Development
npm install # install deps
npm run build # production build (ESM + CJS + browser IIFE)
npm run dev # rebuild on change
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run format # prettierOutput files
| File | Use |
| ----------------------- | -------------------------------------- |
| dist/index.js | ESM module |
| dist/index.cjs | CommonJS module |
| dist/index.d.ts | TypeScript declarations |
| dist/index.browser.js | Minified IIFE for <script> embedding |
Embedding in another Singular Health project
As an npm dependency
// vite / webpack / any bundler
import { initChatbase } from "@singular-health/chatbase";
initChatbase({ botId: "YOUR_BOT_ID" });As a script on a startup page
<script src="/path/to/dist/index.browser.js"></script>
<script>
SingularChatbase.initChatbase({ botId: "YOUR_BOT_ID" });
</script>WordPress with automatic language detection
WordPress translation plugins (WPML, Polylang, TranslatePress, etc.) change the
<html lang="…"> attribute when the user switches language. The snippet below
initialises the chatbot and watches for those changes so the widget language
stays in sync automatically.
Paste this into your theme's footer (e.g. via a "Custom HTML" widget,
wp_footer hook, or a code-snippets plugin):
<script src="https://your-cdn.example.com/singular-chatbase/dist/index.browser.js"></script>
<script>
(function () {
var botId = "YOUR_BOT_ID";
// Read the initial language from the <html lang> attribute
var lang = document.documentElement.lang.split("-")[0] || "en";
SingularChatbase.initChatbase({
botId: botId,
language: lang,
debug: false,
// Add any custom translations your site supports
translations: {
en: ["Hi!", "How can I help you today?"],
es: ["¡Hola!", "¿Cómo puedo ayudarte hoy?"],
},
});
// Watch for language changes on <html lang="…">
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (m) {
if (m.type === "attributes" && m.attributeName === "lang") {
var newLang = document.documentElement.lang.split("-")[0] || "en";
if (newLang !== lang) {
lang = newLang;
SingularChatbase.setLanguage(lang);
}
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["lang"],
});
})();
</script>How it works:
- Reads the current
<html lang>value at page load and passes it toinitChatbase. - A
MutationObserverwatches thelangattribute on<html>. - When a translation plugin changes it, the observer calls
setLanguage()which updates the greeting messages, resets the chat, and switches the widget overlay.
Assumptions
| Assumption | Rationale |
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| window.chatbase("open") / "close" / "reset" are the correct widget-control calls | Inferred from Chatbase docs referencing "Widget Control" and the proxy-call pattern |
| removeEventListener mirrors addEventListener | Standard pattern; not explicitly documented |
| agent-message and action are valid event names | Inferred from docs mentioning AI response and action events |
| The embed script reads bot ID from script.id | Matches the original sample code pattern |
License
UNLICENSED — internal Singular Health use only.
