The widget is built from named parts, called components. You can style each one with data-* attributes on the script tag. For colours, fonts and dark mode across the whole widget, use Theming instead. The names are kapa.ai’s, so a styled kapa embed keeps its look. kapa’s legacy style names (data-button-bg-color, data-modal-header-bg-color, …) work too. See Legacy and kapa.ai names.

Component style configuration

An attribute is a component name, an optional state, and a CSS property:
data-{component}-{property}          data-modal-header-background-color
data-{component}-{state}-{property}  data-launcher-button-hover-background-color
data-{component}-{property}-dark     data-modal-header-background-color-dark
  • A component style wins over the colour palette and the brand colour.
  • It applies in light and dark mode. The -dark version overrides it in dark mode only.
  • An attribute that does not name a known component and a supported property is ignored. So is an unsafe value (one containing ;, {, }, <, > or url().

Supported CSS properties

A bare number in a size means pixels.
PropertySets
background-color, color, opacityColours
border, border-bottom, border-color, border-radiusBorders and corners
font-family, font-size, font-weightText
height, width, min-height, min-width, max-height, max-widthSize
padding, padding-top, padding-bottom, padding-left, padding-rightPadding
padding-x, padding-yLeft and right, or top and bottom padding
margin-top, margin-bottom, margin-left, margin-right, margin-x, margin-yMargin
top, left, right, bottom, z-indexPosition
flex-direction, justify-contentFlex layout
box-shadow, text-shadowShadows
icon-sizeWidth and height of the icon inside the component

Pseudo-state variants

Put a state between the component and the property to style that state only.
StateAppliesExample
hoverWhile the pointer is over itdata-launcher-button-hover-background-color
focusWhile it, or a field inside it, has focusdata-query-input-focus-border-color
placeholderTo an input’s placeholder textdata-query-input-placeholder-color
activeWhile it is being presseddata-submit-button-active-background-color
enabledTo the chosen 👍 or 👎data-answer-feedback-button-enabled-background-color

Available components

A style on a base component applies to the components built on it. A style on the child wins.
ComponentBaseWhat it is
launcher-buttonThe button that opens the panel, in the corner or in your header
launcher-button-labelThe text on the launcher
modal, modal-contentThe panel (both names reach it)
modal-innerPlaces the panel. flex-direction and justify-content lay out the full-screen layer; top, right, bottom, left pin the panel to the window; other properties size the panel
modal-overlayThe dimmed backdrop. background-color sets its colour; opacity thins that colour without fading the panel
modal-headerThe header row
modal-logoThe logo in the header
modal-titleThe title in the header
modal-close-buttonThe ✕ in the header
modal-bodyThe conversation area and the search results
modal-footerThe footer
disclaimer, chat-disclaimerThe notice above the question box (both names reach it)
consent-screenThe consent screen
query-inputBoth input fields. Text properties land on the field inside
ask-ai-inputquery-inputThe question box
search-inputquery-inputThe Search tab’s field
submit-buttonThe send button
example-questionsThe group of starter questions
example-question-buttonOne starter question
conversation-item-questionThe reader’s question
conversation-item-answerThe answer text
conversation-buttonCopy, 👍, 👎 and new conversation
answer-feedback-buttonconversation-button👍 and 👎
answer-copy-buttonconversation-buttonCopy answer
thread-clear-buttonconversation-buttonNew conversation, in the header
handoff-buttonThe Create ticket button
answer-cta-buttonThe call-to-action button under answers
answer-sources-buttonThe Sources label above an answer’s sources
source-linkOne source
source-link-primary-headingA source’s title
source-link-secondary-headingA source’s number
search-resultOne search result
search-result-badgeA result’s section path
search-result-primary-textA result’s title
search-result-secondary-textA result’s snippet
search-ask-ai-ctaThe “Ask AI: …” row in search
switchThe Ask AI / Search tabs
switch-labelOne tab
mcp-buttonThe Use MCP header button
mcp-dropdownThe MCP menu
branding, kapa-brandingThe “Powered by” line
privacy-linksThe footer’s policy links
captcha-disclaimerThe “Protected by reCAPTCHA” line
kapa’s reasoning-mode-selector (the Fast/Thinking switch) has no counterpart, and its attributes are ignored.

Example

<script
  async
  src="https://widget.kelu.dev/kelu-widget.js"
  data-knowledge-base-id="YOUR_KNOWLEDGE_BASE_ID"
  data-client-key="kl_pk_..."
  data-launcher-button-background-color="#111827"
  data-launcher-button-hover-background-color="#374151"
  data-modal-header-background-color="#f5f3ff"
  data-modal-header-background-color-dark="#1e1b4b"
  data-query-input-focus-border-color="#6306B6"
  data-example-question-button-border-radius="999px"
  data-conversation-button-icon-size="16px"
></script>

Component-specific configuration options

Some components also have options of their own: labels, images and switches.

Launcher button

AttributeDescriptionDefault
data-launcher-button-hiddenDraw no launcher. Open the panel with an open trigger or the JavaScript API"false"
data-launcher-button-textLabel, tooltip and accessible name"Ask AI"
data-launcher-button-show-textShow the label beside the icon, as a pill"false"; "true" in your header
data-launcher-button-imageImage on the buttonThe product logo
data-launcher-button-image-hiddenKeep the sparkle icon even when a product logo is set"false"
data-launcher-button-image-fillLet the image fill the button, for a logo with its own background"false"
data-launcher-button-image-width / -heightImage size32px (18px in your header)
data-launcher-button-shape"circle", "pill" or "square". A circle never shows the labelPill with a label, circle without
data-launcher-button-sizeDiameter of a circle, height of a pill or square. An unshaped pill sizes to its label60px
data-launcher-button-text-sizeLabel size15px
data-launcher-button-animation-enabled"false" turns off the entrance animation"true"
data-launcher-button-hover-animation-enabled"false" turns off the grow-on-hover"true"
data-position"bottom-right" or "bottom-left""bottom-right"
To put the button in your page, next to your search box, instead of in a corner:
AttributeDescriptionDefault
data-launcher-button-anchor-selectorCSS selector. Every match gets a button beside itNot set
data-launcher-button-anchor-position"beforebegin", "afterbegin", "beforeend" or "afterend""afterend"
data-launcher-button-anchor-shapeShape of that buttonA rounded rectangle
data-launcher-button-anchor-sizeIts height36px
data-launcher-button-anchor-text-sizeIts label size13px
data-launcher-button-anchor-overlayLay the button over your header instead of inserting it, so nothing movesDecided per header
data-launcher-button-anchor-wait-msHow long to wait for the element before using the corner instead. -1 waits forever10000
data-launcher-button-floatingKeep the corner button as well"false"
See Put the button in your header.
AttributeDescriptionDefault
data-modal-sizePanel width in modal mode760px
data-sidebar-widthPanel width in sidebar mode460px
data-modal-heightPanel height. Never taller than the window780px
data-modal-expanded-sizeWidth after the ⤢ header button is pressed1500px
data-modal-x-offset / data-modal-y-offsetMove the panel sideways or up and down, such as 4vw0
data-modal-full-screenFill the window"false"
data-modal-full-screen-on-mobile"false" stops it filling the screen under 600px"true"
data-modal-lock-scroll"false" lets the page scroll behind the open panel"true"
data-modal-z-indexStacking order2147483647
data-modal-overlay-hiddenDraw no backdrop"false"
AttributeDescriptionDefault
data-modal-titleHeader titleThe product name
data-modal-title-ask-ai / -searchTitle while the chat or the Search tab is showingdata-modal-title
data-modal-subtitleThe second line. "" removes it”Answers with sources from the docs”
data-modal-logo-srcHeader logoThe product logo
data-modal-logo-src-ask-ai / -searchLogo while the chat or the Search tab is showingdata-modal-logo-src
data-modal-logo-width / -heightLogo size32px
data-modal-logo-hiddenHide the logo"false"
data-modal-logo-hidden-on-mobileHide it under 600px"false"
data-modal-close-button-hiddenHide the ✕"false"
data-modal-expand-button-hiddenHide the ⤢. It only exists in modal and sidebar mode, and not under 600px"false"

Chat disclaimer

AttributeDescriptionDefault
data-chat-disclaimerNotice above the question box, such as “Answers are AI-generated”. MarkdownNot set
Shown when data-consent-required is "true".
AttributeDescriptionDefault
data-consent-screen-titleHeading”Hi there, do you want to use the AI chat?”
data-consent-screen-disclaimerBody text. MarkdownA short notice that the chat uses AI
data-consent-screen-accept-button-textAccept button”I agree, let’s chat!”
data-consent-screen-reject-button-textReject button”No, not interested”

Inputs

AttributeDescriptionDefault
data-ask-ai-input-placeholderQuestion box placeholder”Ask anything about “
data-search-input-placeholderSearch tab placeholder”Search sources…”
data-search-input-icon-hiddenHide the magnifier in the Search tab’s field"false"

Example questions

AttributeDescriptionDefault
data-welcome-messageThe greeting above the starter questions”Ask me anything about . I answer from the documentation and link every source.”
data-suggested-questionsStarter questions, split on |. Up to four are shownThe knowledge base’s own
data-example-questions-columnsHow many per row1
data-show-suggested"false" shows no starter questions"true"
Without a list on the tag, the widget shows the knowledge base’s own starter questions (the knowledge base’s Settings → Starter Questions). Phones always show one per row.

Buttons under an answer

AttributeDescriptionDefault
data-handoff-button-textLabel of the Create ticket button. Turn it on in Behaviour”Create ticket”
data-answer-cta-button-enabledAdd a call-to-action button under every answer"false"
data-answer-cta-button-textIts label”Talk to an expert”
data-answer-cta-button-linkWhere it goes. Without a link there is no buttonNot set
Icon sizes use the icon-size property: data-conversation-button-icon-size for all of them, or data-answer-feedback-button-icon-size, data-answer-copy-button-icon-size, data-thread-clear-button-icon-size for one. Defaults: 14px under an answer, 16px in the header.

Search tab

AttributeDescriptionDefault
data-search-result-targetThe target of a result link"_blank"
data-search-ask-ai-cta-hiddenHide the “Ask AI: …” row"false"
data-switch-icon-hiddenHide the icons on the Ask AI and Search tabs, keeping the labels"false"

MCP button

AttributeDescriptionDefault
data-mcp-button-textButton label”Use MCP”
data-mcp-dropdown-descriptionLine under the menu’s title. [text](url) links work”Access this knowledge base via MCP”
AttributeDescriptionDefault
data-modal-footer-textAn extra footer line. MarkdownNot set
data-privacy-linksFooter links as JSON: [{"title":"Privacy","url":"/privacy"}]. Invalid JSON is ignored with a console warningNone
data-hide-brandingHide “Powered by Kelu”"false"
data-branding-textReplace “Powered by Kelu” with your own lineNot set
Hiding or replacing “Powered by Kelu” works on the Enterprise plan only. On other plans the line stays. The “Protected by reCAPTCHA” line stays on every plan when reCAPTCHA is on.