Quick start
Configuration
Every option can be set as adata-* attribute on the script tag, or as the
equivalent camelCase key passed to init(). These are the ones most sites set:
Full configuration reference
All 160-odd options — launcher, modal chrome, open triggers, consent,
hand-off, surveys, analytics identity, theme tokens, and the kapa.ai
attribute spellings the widget also answers to.
View modes
- modal (default)
- search
A centered overlay triggered by the floating launcher. Closes on backdrop click or Esc.
Making the panel bigger
The panel header has a ⤢ button, so a reader with a long answer in front of them can give it more room. ⤡ puts it back.
Their choice is saved in the browser, per knowledge base: expand it on one page
and it is already expanded on the next. On phones there is no button, because
the panel already fills the screen.
Two attributes change it, both optional.
data-modal-expanded-size sets how big
“expanded” is, and data-modal-expand-button-hidden removes the button:
Beside your search bar
The arrangement most docs sites want: an Ask AI button in the header, next to the search box, where a reader who has just failed to find something is looking. There are two ways round it, and which one you need depends on one thing — can you edit your header’s markup? No (a hosted docs theme — Mintlify, GitBook, ReadMe). Name an element that is already there, and the widget puts its own button beside it:
The button becomes a labelled toolbar control — 36px, no drop shadow, no
animations — and keeps its own shadow root, so your header’s CSS cannot restyle
it by accident. Anchors are re-checked for the life of the page, so a header your
framework re-renders on every navigation gets its button back.
Finding the selector: right-click your search box → Inspect → read the
id="…" off the highlighted tag (#that-id), or one of its classes
(.that-class). Check it in the console with document.querySelectorAll("…")
before you ship it.
Your own “Ask AI” button
Yes, you can edit the header. Then keep the button in your own markup and point the widget at it — it inherits your styling and sits exactly where your layout puts it.
Triggers are bound by delegation on
document, so a button your framework
re-renders on every route change keeps working without re-initialising the widget.
data-open-query-from is what stops the reader typing the question twice: they
typed it into the search box, then pressed the button next to it. Without it the
panel opens with an empty composer.
The same thing from code, if you would rather wire the click yourself:
Programmatic API
For SPAs, initialize and control the widget from code. Everything hangs offwindow.BeforeQueryWidget:
Methods
Events
Every widget interaction is reported to a callback, which is how a docs team gets “how many opened it, what did they ask, did the answer land” into the analytics tool they already use:
Handlers run inside a
try/catch. A broken analytics snippet logs and is
stepped over; it cannot take the chat down with it. Subscriptions outlive any
one instance, so unmount() then render() keeps reporting, and registering
before the bundle has finished loading is safe.
Migrating from another widget — there is a callable form of the same bus:The event names and payload shapes match kapa.ai’s, so an existing analytics
wiring can be pointed here without being rewritten. The same goes for the
embed itself: where an attribute has two spellings, the second is the one a
kapa script tag already carries.
Keyboard shortcut & dark mode
- Cmd+K (Mac) / Ctrl+K (Windows/Linux) opens the widget by default. Change with
data-hotkey="/"or disable withdata-hotkey="none". Esc always closes. - The widget renders light unless told otherwise. Set
data-color-scheme="auto"to follow the visitor’s OS preference, or"dark"to force it. Better still on a site with its own theme switch: pointdata-color-scheme-selectorat the class that switch toggles (html.dark), which wins over both and is re-checked as the page changes, so the widget follows the toggle mid-session.
Features at a glance
- Instant search results as you type (debounced 250 ms)
- Optional Search tab — matching pages, no answer generated
- Streaming RAG chat with numbered source citations
- Follow-up questions continue the same thread
- Thumbs up / down feedback, plus optional satisfaction and exit prompts
- 11 UI languages
- Full theming with separate light and dark palettes, and a selector that follows your site’s own toggle
- Consent screen and footer privacy links for GDPR-style flows
- “Talk to a human” escalation on configurable triggers
- “Connect to AI tools” menu offering the MCP server
- reCAPTCHA v3 support (configured server-side via the widget-config API)
- Mobile full-screen sheet layout
- White-label branding: custom name, logo, accent color, and hideable footer (enterprise)