Reference
Configuration
Every <hive-chat> attribute and HiveChat.init option, theming CSS variables, language and RTL.
Everything below is verified against the widget source and the platform’s Zod schemas by the portal’s drift tests: if an option is listed here it exists, and if one is added to the SDK the build fails until it is documented.
Where settings come from
A setting can be supplied in up to four places. Later entries are defaults for earlier ones:
// 1. <hive-chat> attributes (highest — markup wins)
// 2. HiveChat.init() / configure() (programmatic)
// 3. key's server-side theme + config (console → Embed → Configure)
// 4. built-in defaults (lowest)The server-side theme and config live on the key and are returned by GET /v1/embed/config on every page load (and again with each session), so the console is the single place to restyle an already-deployed widget. Local overrides are for things the page knows and the console does not (the page language, a signed-in user, a container).
Options and attributes
One row per option of HiveChat.init(options). The same option is available as an attribute on <hive-chat> (column Attribute) and, for the script-tag loader, as a data-* attribute on the <script> tag (column Script data-*).
| Option | Attribute | Script data-* | Type | Default | Description |
|---|---|---|---|---|---|
keyrequired | key | data-key | string | — | Publishable embed key (hive_pk_ + 43 url-safe chars). Bound to one agent and an origin allowlist; safe to ship in HTML. |
apiUrl | api-url | data-api-url | string (origin) | origin of the loader <script> | Platform origin the widget talks to (/v1/embed/*). Inferred from the script’s own src; required when you bundle the ESM build yourself or proxy the bundle. |
locale | locale | data-locale | 'en' | 'ar' | 'auto' | key’s server config, else 'auto' | UI language. ar switches the whole panel to RTL. auto reads <html lang> then navigator.language (anything starting with ar is Arabic). |
theme | theme (JSON) | data-theme (JSON) | EmbedTheme | key’s server theme | Local theme overrides — see the theme table below. Invalid values are dropped, never thrown. Wins over the key’s server-side theme. |
title | title | data-title | string | server config title, else the agent name | Panel header title. |
subtitle | subtitle | data-subtitle | string | server config subtitle | Small line under the title. Hidden when empty. |
welcome | welcome | data-welcome | string | server config welcome | First agent bubble shown before any message is sent (rendered as Markdown, dir="auto"). |
placeholder | placeholder | data-placeholder | string | server config placeholder, else a localized default | Composer placeholder + accessible label. |
user | user-token | data-user-token | { token: string } | anonymous visitor | Identified end user: an HS256 JWT minted by YOUR backend with the key’s identity secret. The attribute form takes the raw token. |
mode | mode | data-mode | 'launcher' | 'inline' | 'launcher' | launcher = floating bubble + panel appended to document.body; inline = the panel fills its container element (use data-container with the script tag). |
open | open (presence) | data-open | boolean | false | Start with the panel open (launcher mode). Any data-open value except "false" counts as true. |
storage | storage | data-storage | 'local' | 'session' | 'none' | 'local' | Where the visitor id and current thread id persist (localStorage, sessionStorage, or in-memory only). Keys are namespaced hive-embed:<key prefix>:visitor|thread. |
visitorId | visitor-id | — | string (8–128 url-safe chars) | generated uuid, persisted per storage | Override the visitor id — e.g. to share one conversation across subdomains or devices you already identify. Attribute/programmatic only. |
Script-tag-only attributes
| Script data-* | Type | Default | Description |
|---|---|---|---|
data-container | CSS selector | document.body | Element to mount into (pair with data-mode="inline"). |
data-manual | presence | auto-init when data-key is set | Skip auto-init; call window.HiveChat.init({...}) yourself (a queued window.HiveChat = { q: [[opts]] } stub is drained on load). |
Theme
theme is an object with the fields below. The same shape is stored on the key (console → Configure → Appearance) and validated server-side with embedThemeSchema; local values are merged over server values field by field.
| Field | Type | Default | CSS variable | Description |
|---|---|---|---|---|
primary | hex color | #4f46e5 | --hive-primary | Brand color: launcher, user bubbles, send button. |
on_primary | hex color | #ffffff | --hive-on-primary | Text/icon color drawn on top of primary. |
background | hex color | #ffffff | --hive-bg | Panel background. |
foreground | hex color | #111827 | --hive-fg | Panel text. Muted/border/surface tones are derived from it. |
radius | integer 0–32 | 16px | --hive-radius | Corner radius (px) for the panel and bubbles. |
font | string (≤ 160 chars) | system-ui, …, "Noto Sans Arabic", … | --hive-font | CSS font-family stack. Characters ; { } < > are rejected. |
position | 'start' | 'end' | 'end' | — | Launcher/panel side, logical: end is right in LTR and left in RTL; start is the opposite. |
launcher_icon | 'chat' | 'sparkles' | 'help' | 'chat' | — | Icon drawn in the floating launcher button. |
z_index | integer ≥ 0 | 2147483000 | --hive-z | Stacking order of the launcher and panel. |
HiveChat.init({
key: 'hive_pk_REPLACE_WITH_YOUR_PUBLISHABLE_KEY',
theme: {
primary: '#0f766e',
on_primary: '#ffffff',
background: '#ffffff',
foreground: '#0b1324',
radius: 14,
font: 'Inter, system-ui, sans-serif',
position: 'start',
launcher_icon: 'sparkles',
z_index: 1000,
},
});Colors must be 3- or 6-digit hex (^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$). The panel derives muted text, borders and surfaces from foreground/background, so a dark theme is just a dark background with a light foreground.
CSS variables and parts
The theme is applied as CSS custom properties on the hive-chat host element, which the shadow stylesheet reads. You can therefore also theme from your own stylesheet — useful for dark-mode toggles — and style the exposed ::part()s:
/* Host-page CSS: variables are read inside the shadow root */
hive-chat {
--hive-primary: #0f766e;
--hive-on-primary: #fff;
--hive-radius: 14px;
--hive-z: 1000;
}
/* Parts: style exposed pieces without touching internals */
hive-chat::part(launcher) {
box-shadow: 0 8px 24px rgba(15, 118, 110, 0.35);
}
hive-chat::part(panel) {
border: 1px solid #d0d7de;
}| Part | What it is |
|---|---|
launcher | The floating bubble button (launcher mode). |
panel | The chat panel (role="dialog"). |
header | Title bar with avatar, title, subtitle, reset + close. |
messages | Scrollable transcript (role="log"). |
composer | The textarea + send form. |
branding | The "Powered by" footer (hidden via show_branding: false; links to branding_url when set). |
Text and language (server-side display config)
Texts are stored on the key as config (embedDisplayConfigSchema) and can be overridden locally with the options of the same name (title, subtitle, welcome, placeholder, locale). launcher_label, show_branding and branding_url are server-side only.
| Field | Type | Description |
|---|---|---|
title | string ≤ 80 | Panel header title (defaults to the agent name). |
subtitle | string ≤ 120 | Line under the title. |
welcome | string ≤ 1000 | First agent bubble before any message. |
placeholder | string ≤ 120 | Composer placeholder. |
locale | 'en' | 'ar' | 'auto' | Default UI language when the host sets none. |
launcher_label | string ≤ 60 | Accessible label + tooltip for the launcher. |
show_branding | boolean | Show the "Powered by" footer (default true). |
branding_url | https URL ≤ 500 | Where the "Powered by" footer links. Unset (or not https) renders the footer as plain text. |
Language and RTL
The widget ships English and Arabic UI strings. locale resolves in this order: the local option/attribute, the key’s server config, 'auto'. With auto, <html lang> is checked first, then navigator.language; any value starting with ar selects Arabic, everything else English.
- Arabic sets
dir="rtl"andlang="ar"on the panel: layout, icons and the launcher side flip.positionis logical —endstays “the trailing side”. - Every message bubble and the welcome text render with
dir="auto", so mixed-language conversations read correctly in either UI language. - The agent answers in whatever language the visitor writes (subject to the agent’s persona). The UI language does not constrain the model.
- Change language at runtime with
handle.update({ locale: 'ar' })— no re-mount, the session is kept.
<!-- Arabic, right-to-left, launcher at the logical end (= left in RTL) -->
<script async src="https://console.agenticworkforce.me/embed/v1/hive-embed.js"
data-key="hive_pk_REPLACE_WITH_YOUR_PUBLISHABLE_KEY"
data-locale="ar"
data-title="مساعد الدعم"
data-welcome="مرحباً! كيف يمكنني مساعدتك اليوم؟"></script>Launcher, position and open state
mode: 'launcher'(default) appends a floating button todocument.body; clicking it opens a 400 × 640 px panel (full-screen under 480 px wide).theme.positionchooses the side;theme.z_indexthe stacking order.open: true(or theopenattribute /data-open) starts with the panel open.Escapecloses it in launcher mode.mode: 'inline'renders only the panel, filling the host element (give it a height). There is no launcher, andopenis ignored.- Programmatic control (
open(),close(),toggle()) is covered in the JavaScript API.
Welcome text
welcome is shown as the first agent bubble until the visitor sends something. It is rendered as Markdown (paragraphs, emphasis, links, inline code, lists) — the same renderer used for replies — and is not sent to the model. Up to 1000 characters when stored server-side.
Visitor id, storage and metadata
Every browser gets a random visitor id (UUID), persisted according to storage under hive-embed:<first 16 chars of the key>:visitor. The current thread id is stored next to it. Threads belong to the visitor: the API refuses history for a thread minted by another visitor.
// Share one anonymous conversation across app.acme.com and help.acme.com:
// generate the id once, store it in a cookie on .acme.com, pass it on both.
HiveChat.init({
key: 'hive_pk_REPLACE_WITH_YOUR_PUBLISHABLE_KEY',
visitorId: readCookie('acme_vid'), // 8–128 chars, [A-Za-z0-9_-]
storage: 'none', // you own persistence now
});Identified users
Pass user: { token } (attribute user-token, data-user-token) with a short-lived HS256 JWT signed with the key’s identity secret. The session is then bound to your user (end_user in the session response, identified: true in hive:session), threads are scoped to them, and the console shows them under Contacts. Keys created with Require a signed identity refuse anonymous sessions with 401 EMBED_IDENTITY_REQUIRED. Replacing the token at runtime with update({ user }) starts a new session (the anonymous thread is not carried over).