Runtime API
After the widget mounts, it exposes window.Knoku for programmatic control.
With the CDN script, mounting is asynchronous because the widget first fetches project config. With npm, await initKnokuWidget() resolves after mount.
Methods
window.Knoku.open()
window.Knoku.close()
window.Knoku.toggle()
window.Knoku.ask('How do I get started?')
window.Knoku.identify({ id: 'user_123', email: 'user@example.com' })
window.Knoku.destroy()| Method | Behavior |
|---|---|
open() | Opens the panel |
close() | Closes the panel |
toggle() | Toggles the panel |
ask(question) | Opens the panel and submits a question |
identify(user) | Associates future chat requests with a known user |
destroy() | Removes the widget host, listeners, injected styles, and runtime |
ask
ask(question) opens the panel and submits the question.
If consent is required and the visitor has not accepted yet, the widget opens the consent screen first. The question is held and submitted after acceptance. If the visitor rejects, the held question is discarded.
identify
Call identify() after your app knows the current user:
window.Knoku.identify({
id: 'user_123',
email: 'user@example.com',
metadata: {
plan: 'business',
company: 'Acme',
},
})Pass null to clear the in-memory identity:
window.Knoku.identify(null)Identity is sent on future chat requests. Refreshing the page resets it, so call identify() on each load after auth state resolves.
Inbound events
You can control the widget by dispatching events on window:
window.dispatchEvent(new CustomEvent('knoku:open'))
window.dispatchEvent(new CustomEvent('knoku:close'))
window.dispatchEvent(new CustomEvent('knoku:toggle'))
window.dispatchEvent(new CustomEvent('knoku:ask', {
detail: { question: 'How do I install the widget?' },
}))For buttons, prefer data-open-selector when possible.
Outbound events
Listen on window for widget events:
window.addEventListener('knoku:message', (event) => {
console.log(event.detail.question)
})
window.addEventListener('knoku:response', (event) => {
console.log(event.detail.answer)
console.log(event.detail.sources)
})| Event | When it fires | Detail |
|---|---|---|
knoku:message | A user question is submitted before the network request starts | { question } |
knoku:response | The assistant answer completes successfully | { answer, sources } |
knoku:deflector-resolved | Deflector visitor clicks This answered my question | Empty |
knoku:deflector-continue | Deflector visitor clicks Continue to support | Empty |
There is no knoku:ready event. Use the readiness helper below or the npm promise.
There is no knoku:error event. Errors render inside the assistant message. If you need failure analytics, compare knoku:message to knoku:response within your own timeout window.
SourceRef shape
knoku:response includes sources from the answer:
type SourceRef = {
doc_id: string
path: string
url_path?: string
title: string
lines: string
}Wait for CDN readiness
function whenKnokuReady(fn, timeoutMs = 10000) {
if (window.Knoku) return fn(window.Knoku)
const started = Date.now()
const timer = setInterval(() => {
if (window.Knoku) {
clearInterval(timer)
fn(window.Knoku)
return
}
if (Date.now() - started > timeoutMs) {
clearInterval(timer)
console.warn('Knoku widget did not mount within timeout')
}
}, 50)
}
whenKnokuReady((Knoku) => {
Knoku.open()
})npm mount
import { initKnokuWidget } from '@knoku/widget'
await initKnokuWidget({
projectId: 'YOUR_PROJECT_ID',
})
window.Knoku?.open()