Appearance
JavaScript API
widget.js puts one global on the page, window.WirefaceChat. The npm package gives you the same API with TypeScript types: bootWirefaceChat() resolves with a chat instance, which has every method below.
js
// after widget.js has loaded
const chat = await WirefaceChat.boot({ bot: 'pk_your_bot_id' });
chat.on('message', m => console.log(m.role, m.text));
chat.open();The global also has every instance method. Called on the global, a method acts on the first chat on the page (and waits for it, if no chat has started yet), and WirefaceChat.bot is that chat's bot id. Use WirefaceChat.get('pk_...') to reach another bot's chat.
Calling it before it loads
widget.js loads async, so your code may run first. Put this stub before your own calls: it queues them, and widget.js replays them when it arrives.
html
<script>
window.WirefaceChat = window.WirefaceChat || function () {
var args = [].slice.call(arguments);
return new Promise(function (resolve, reject) {
(window.WirefaceChat.q = window.WirefaceChat.q || []).push([args[0], args.slice(1), resolve, reject]);
});
};
WirefaceChat('on', 'lead', function (lead) { console.log('lead', lead.fields); });
</script>
<script src="https://chat.example.com/widget.js" data-bot="pk_your_bot_id" async></script>Or wait for the wirefacechat:loaded event on window. widget.js may already have loaded by the time your code runs, so check first:
js
function ready() { /* WirefaceChat is here */ }
if (window.WirefaceChat && WirefaceChat.version) ready();
else window.addEventListener('wirefacechat:loaded', ready);A queued boot call replaces the script tag's data-bot: widget.js only boots from the tag when no boot was queued.
The global
WirefaceChat(command, ...args)
ts
(command: string, ...args: unknown[]): Promise<unknown>The queue form: WirefaceChat('open'), WirefaceChat('boot', { bot: 'pk_...' }), WirefaceChat('on', 'message', fn). Calls made through the stub before widget.js loads are replayed in order (all boot calls first). Returns a Promise of the method's result.
WirefaceChat.boot()
ts
boot(o: BootOptions): Promise<WirefaceChatInstance>Starts a chat for a bot and resolves with its instance. Booting a bot that is already on the page returns the existing chat (an inline chat of the same bot is separate).
WirefaceChat.get()
ts
get(bot?: string): WirefaceChatInstance | undefinedThe chat for a bot id, or the first chat on the page.
WirefaceChat.instances()
ts
instances(): WirefaceChatInstance[]All chats on the page.
WirefaceChat.version
ts
readonly version: stringThe widget version, e.g. 0.1.0.
Boot options
Pass these to WirefaceChat.boot(), to bootWirefaceChat() (with host), as props of the React component, or in window.wirefaceChatSettings before widget.js loads. "bot" in the Default column means the bot's own setting from the admin panel applies (see Configuration).
| Option | Type | Default | What it does |
|---|---|---|---|
bot | string | required | The bot's public id (pk_...). The admin panel shows it with the embed code. |
host | string | where widget.js came from | Your Wireface Chat server, e.g. https://chat.example.com. Only needed when widget.js is not loaded from that server; the npm package always passes it. |
layout | 'panel' | 'drawer' | 'floating' | 'inline' | bot | panel, drawer, floating or inline. See Layouts and launchers. |
target | string | HTMLElement | Inline layout only: the element, or a CSS selector for it, to draw the chat into. If it isn't found, the chat falls back to the panel layout with a launcher and warns in the console. | |
launcher | LauncherOptions | bot | Launcher settings (below), merged over the bot's appearance.launcher. |
theme | 'light' | 'dark' | 'auto' | bot | light, dark, or auto to follow the visitor's system setting. |
accentColor | string | bot | The accent colour as #rrggbb. The launcher ignores any other format. |
locale | string | <html lang>, then the browser | The visitor's language, e.g. fr or pt-BR. It sets the chat's lang and text direction (right to left for Arabic, Hebrew, Persian, Urdu and a few others), and is sent to the server; with identity.languagePolicy: match_visitor the agent replies in it. It doesn't translate the chat's own buttons and labels: use strings for that. |
strings | Record<string, string> | bot | Your own wording for the chat's interface text, by key. Merged over the bot's texts.strings. See Interface strings. |
open | boolean | false | Open the chat as soon as it's ready. Without it, a chat that was open when the visitor left the last page opens again (not on phones). |
user | VisitorIdentity | Who the visitor is, when they are signed in to your site. See Identity verification. Ignored when the bot's security.identity.mode is off. | |
context | Record<string, Json> | Facts the agent may use, e.g. { plan: "pro", cartTotal: 42 }. They reach the agent as a note when a conversation starts, and again when the chat picks up an earlier conversation with different facts (up to 4,000 characters of JSON). They are marked as untrusted information, so the agent treats them as data, never as instructions. Change them later with setContext(). | |
tools | Record<string, ClientTool> | Tools the agent can run in your page, by name. The same as calling registerTool() for each. See Client tools. | |
zIndex | number | bot (2147483000) | The z-index of the launcher and the chat window. |
storage | 'local' | 'session' | 'none' | local | Where the visitor token and conversation are remembered on your site: local (localStorage), session (sessionStorage, gone when the tab closes) or none (nothing is stored; every page load is a new visitor). |
spa | 'auto' | 'manual' | auto | auto follows history.pushState, history.replaceState, popstate, hashchange and Turbo's turbo:load, and tells the chat about each new page. manual: this chat ignores them, and you call page() yourself. |
preload | 'intent' | 'idle' | 'none' | intent | When to load the chat window before it is opened: intent (when the pointer hovers, focuses or touches the launcher), idle (once the browser is idle after the page loads) or none (only when it opens). |
exclusive | boolean | true | Close other bots' chats on the page when this one opens. |
debug | boolean | false | Log every event the chat emits with console.debug. |
preview | string | A signed preview token from the admin panel. The chat then shows the bot's unpublished draft. Tokens last 6 hours. |
Launcher
| Option | Type | Default | What it does |
|---|---|---|---|
type | 'bubble' | 'tab' | 'none' | bubble | bubble: a round button in a corner. tab: a labelled tab docked on an edge. none: no launcher; open the chat from your own button. |
position | 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | bottom-right | Bubble (and none): the corner, bottom-right, bottom-left, top-right or top-left. The window opens next to it. |
edge | 'right' | 'left' | 'bottom' | right | Tab: the edge it sits on, right, left or bottom. |
align | 'start' | 'center' | 'end' | end | Tab: where along the edge, start, center or end. On the right or left edge end is the bottom; on the bottom edge it is the right. |
label | string | Chat with us | Tab: its text. An empty label shows "Chat with" and the agent's name. |
icon | 'face' | 'chat' | 'avatar' | face | face: the agent's face picture, which breathes gently on the bubble (still for visitors who ask for reduced motion). avatar: the same picture, still. chat: a chat icon. |
offset | { x?: number; y?: number } | { x: 20, y: 20 } | Distance from the edges of the window, in pixels. |
size | number | 60 | The bubble's diameter in pixels (the admin allows 40 to 96). |
hideOnMobile | boolean | false | Hide the launcher on phones, for example when your mobile site has its own chat button. |
Visitor identity
The user option and identify().
| Option | Type | Default | What it does |
|---|---|---|---|
id | string | required | Your user id for this person (up to 200 characters). |
hash | string | HMAC-SHA256(identity secret, id) as lowercase hex, computed on your server. Required when the bot's identity mode is required. | |
name | string | The visitor's name. The agent and your team see it (marked unverified without a valid hash). | |
email | string | The visitor's email (same as name). | |
attributes | Record<string, string | number | boolean | null> | Other facts to keep with the visitor: strings (up to 1,000 characters), numbers, booleans or null. |
Client tool
The tools option and registerTool().
| Option | Type | Default | What it does |
|---|---|---|---|
description | string | required | What the tool does, for the agent (up to 2,000 characters). Say when to use it. |
parameters | JsonSchema | required | A JSON Schema for the arguments. The server checks the arguments against it before your handler runs. |
confirm | boolean | string | Ask the visitor first. true shows a question such as "Ava wants to: add to cart. Is that OK?" with the arguments; a string is your own question (up to 300 characters). If they say no, or don't answer within 2 minutes, the handler doesn't run and the agent is told. | |
timeoutMs | number | 15000 | How long the handler may take. The bot's tools.client.timeoutMs and tools.toolTimeoutMs (both 15000 by default) also apply: the shortest wins. |
handler | (args: A, ctx: ToolContext) => R | Promise<R> | required | Runs the tool. Return JSON (or a Promise of it); results over 16 KB are cut short. Throwing reports the error message to the agent. |
The handler's second argument:
| Field | Type | |
|---|---|---|
callId | string | The id of this call. |
conversationId | string | null | The conversation it belongs to. |
signal | AbortSignal | Aborted if the call times out, or when the server gives up on it (the visitor stopped the reply, or its own timeout passed). Pass it to fetch() so abandoned requests stop. |
Instance methods
bot
ts
readonly bot: stringThe bot's public id.
ready
ts
readonly ready: Promise<void>Resolves once the launcher is drawn. The chat window loads and connects later (when it is first opened, or earlier with preload). It never rejects: if the bot can't be loaded it resolves and an error event fires.
open()
ts
open(): Promise<void>Opens the chat window, loading it if needed. Closes other bots' chats unless exclusive: false. Does nothing with the inline layout, which is always open.
close()
ts
close(): Promise<void>Closes the chat window. The conversation carries on and can be reopened.
toggle()
ts
toggle(): Promise<void>Opens the chat if it is closed, closes it if it is open.
isOpen()
ts
isOpen(): booleanWhether the chat window is open.
show()
ts
show(): voidShows the launcher again after hide().
hide()
ts
hide(): voidHides the launcher (and the greeting bubble). An open chat window stays open.
update()
ts
update(o: Partial<Omit<BootOptions, 'bot' | 'host' | 'target'>>): Promise<void>Changes options after boot: layout, launcher, theme, accentColor, locale, strings and zIndex redraw the launcher and window; user calls identify(); context calls setContext(); storage moves what is remembered to the new place (none forgets it).
sendMessage()
ts
sendMessage(text: string, o?: { open?: boolean }): Promise<void>Sends a message as if the visitor typed it. Opens the chat first unless { open: false }.
prefill()
ts
prefill(text: string): Promise<void>Puts text in the message box without sending it, e.g. from a "Ask about this product" button.
startVoice()
ts
startVoice(o?: { mode?: 'conversation' | 'ptt'; camera?: boolean }): Promise<void>Opens the chat and starts a voice conversation: mode: 'conversation' (the default, hands-free) or 'ptt' (push-to-talk) when the bot allows it. The browser asks for the microphone. With camera: true the chat also offers the camera (the visitor sees the consent prompt first). If the chat window is still loading, the request waits until it's ready. See Voice for the autoplay rules.
stopVoice()
ts
stopVoice(): Promise<void>Ends the voice conversation. The chat carries on in text.
identify()
ts
identify(user: VisitorIdentity): Promise<void>Tells the chat who the visitor is after boot, e.g. after they sign in. See Identity verification. If the bot requires identity, pass user to boot() instead: the connection is refused without it.
setContext()
ts
setContext(context: Record<string, Json>, o?: { merge?: boolean }): Promise<void>Shares facts with the agent. Each call reaches the agent as a note in the conversation. By default the object is merged into earlier context; { merge: false } replaces the copy the chat keeps (what it sends again when it reconnects).
page()
ts
page(info?: { url?: string; title?: string }): voidTells the chat the page changed. Only needed with spa: 'manual'. The agent gets a note with the new URL and title, and the greeting rules are checked again. Does nothing until the chat window has loaded.
registerTool()
ts
registerTool<A = any, R extends Json = Json>(name: string, tool: ClientTool<A, R>): () => voidGives the agent a tool that runs in your page. Returns a function that removes it. Names are letters, digits and _ (up to 64, not starting with a digit). See Client tools.
newConversation()
ts
newConversation(): Promise<void>Starts a new conversation. The current one is closed, unless it held no more than the welcome and one message.
setLocale()
ts
setLocale(locale: string): Promise<void>Same as update({ locale }): changes the chat's lang and text direction (right to left for Arabic, Hebrew, Persian, Urdu and a few others) and tells the server. With identity.languagePolicy: match_visitor the agent is told to answer in the new language from then on.
setTheme()
ts
setTheme(theme: ThemeMode): Promise<void>Same as update({ theme }).
consent()
ts
consent(granted: boolean): voidFor cookie-consent banners. consent(false) deletes what the chat stored on your site and stores nothing more (the visitor becomes anonymous on the next page load). consent(true) turns storage back on (local, or the storage you booted with).
getState()
ts
getState(): { open: boolean; conversationId: string | null; visitorId: string | null; unread: number }A snapshot: whether the chat is open, the conversation and visitor ids (null until the window has connected), and the unread count.
on()
ts
on<K extends EventName>(event: K, fn: (data: WirefaceChatEvents[K]) => void): () => voidListens to an event. Returns a function that stops listening. See Events.
once()
ts
once<K extends EventName>(event: K, fn: (data: WirefaceChatEvents[K]) => void): () => voidListens to the next occurrence of an event only.
off()
ts
off<K extends EventName>(event: K, fn: (data: WirefaceChatEvents[K]) => void): voidStops listening (pass the same function you gave to on()).
shutdown()
ts
shutdown(o?: { forget?: boolean }): Promise<void>Removes the chat from the page and closes its connection. { forget: true } also deletes what it remembered on your site (the visitor token and conversation): use it when someone signs out, so the next person on that browser starts fresh.
Script tag attributes
widget.js reads these from its own <script> tag. They set the boot options of the same name. window.wirefaceChatSettings (an object of boot options, set before widget.js loads) wins over them.
| Attribute | Sets |
|---|---|
data-host | host: the chat server, when it differs from where the script came from. |
data-bot | bot: the bot to start. Without it (and without window.wirefaceChatSettings.bot) nothing starts until you call boot(). |
data-layout | layout |
data-theme | theme |
data-locale | locale |
data-target | target (a CSS selector) |
data-open | open: data-open="true" |
data-preview | preview |
data-debug | debug: data-debug="true" |
data-storage | storage |
data-launcher | launcher.type |
data-position | launcher.position |
data-edge | launcher.edge |
data-align | launcher.align |
data-label | launcher.label |
data-autoboot | data-autoboot="false" loads the API without starting a chat (the npm package does this, then calls boot()). |
Open buttons
Any element with a data-wireface-open attribute opens the chat when clicked. Its value can name a bot; empty opens the first chat on the page.
html
<button data-wireface-open>Chat with us</button>
<a href="#" data-wireface-open="pk_your_bot_id">Ask sales</a>