This page covers the HyperHelp widget's JavaScript API. If you just need to install the widget, start with the installation guide.
Initialization#
The widget is initialized via window.HyperhelpWidget.init():
<script
src="https://app.hyperhelp.ai/widget/chat.js"
async
onload='window.HyperhelpWidget.init({
"chatbotKey": "YOUR_WIDGET_KEY"
})'
></script>
Init options#
| Option | Type | Description |
|---|---|---|
chatbotKey |
string |
Required. Your chatbot's widget key. |
copy |
object |
Override any widget text string. See Copy overrides. |
styleOverrides |
object |
Inline style overrides per widget element. See Style overrides. |
customCss |
string |
Raw CSS injected into the widget's Shadow DOM. See Custom CSS. |
customCssUrl |
string |
URL to an external CSS file injected into the widget's Shadow DOM. |
callbacks |
object |
Event callback functions. See Callbacks. |
Widget API#
init() returns a widget instance with programmatic control:
const widget = window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY"
});
// Open the widget programmatically
widget.open();
// Close the widget
widget.close();
Common use cases:
- Open the widget after a delay:
setTimeout(() => widget.open(), 5000) - Open on a custom button click:
document.getElementById('help-btn').addEventListener('click', () => widget.open())
Copy overrides#
Override any widget string via the copy option. You only need to include the keys you want to change — unset keys fall back to the dashboard defaults.
window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY",
copy: {
title: "Ask Nova",
subtitle: "Help from our docs",
badge_label: "Chat",
composer_placeholder: "Ask about pricing...",
composer_send: "Send",
empty_title: "Start the conversation",
empty_description: "Ask your first question to see answers.",
assistant_label: "Assistant",
user_label: "You",
sources_title: "Sources",
disclaimer: "Answers are generated from this site.",
error: "Something went wrong, please contact the site owner.",
unavailable: "Something is not working as it should. Please contact the site owner.",
close_label: "Close",
new_conversation_label: "New conversation",
copy_label: "Copy",
copied_label: "Copied",
lead_close_label: "Close lead form",
lead_submit_label: "Submit",
lead_success: "Thanks! Your details have been submitted."
}
});
Tip: You don't need to override every key — only the ones you want to change. Unset keys fall back to the dashboard defaults.
Style overrides#
Pass inline style objects (camelCase CSS properties) to customize specific widget elements without writing CSS:
window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY",
styleOverrides: {
panel: { boxShadow: "0 24px 60px rgba(15, 23, 42, 0.18)" },
openButton: { backgroundColor: "#0f172a" },
userBubble: { backgroundColor: "#4338ca", color: "#fff" },
header: { borderBottom: "2px solid #e5e7eb" }
}
});
Available style override keys#
Layout
| Key | What it styles |
|---|---|
panel |
The main chat panel container |
header |
Panel header bar |
title |
Header title text |
subtitle |
Header subtitle text |
body |
Message area |
footer |
Panel footer |
Messages
| Key | What it styles |
|---|---|
emptyState |
Empty conversation state |
error |
Error message display |
messageRow |
Individual message row |
messageGroup |
Grouped messages wrapper |
userBubble |
Visitor's message bubble |
assistantBubble |
Bot's message bubble |
Sources
| Key | What it styles |
|---|---|
sources |
Sources section container |
sourcesLabel |
"Sources" heading |
sourcesList |
Sources link list |
sourcesLink |
Individual source link |
Composer
| Key | What it styles |
|---|---|
composer |
Message input area container |
composerInput |
Text input field |
composerButton |
Send button |
Open button
| Key | What it styles |
|---|---|
openButton |
Floating open button |
openDot |
Pulse indicator dot |
badgeLabel |
Button badge text |
Lead capture
| Key | What it styles |
|---|---|
leadRow |
Lead form row container |
leadCard |
Lead form card |
leadHeadline |
Lead form headline |
leadDescription |
Lead form description |
leadFieldLabel |
Form field label |
leadInput |
Form input field |
leadError |
Field validation error |
leadSubmitButton |
Form submit button |
Custom CSS#
For full CSS control — hover states, media queries, animations — inject CSS directly into the widget's Shadow DOM.
Inline CSS:
window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY",
customCss: `
.widget-panel {
border: 2px solid #e5e7eb;
}
.widget-message-user {
background: linear-gradient(135deg, #667eea, #764ba2);
}
.widget-open-button:hover {
transform: scale(1.1);
}
`
});
External stylesheet:
window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY",
customCssUrl: "https://example.com/widget-overrides.css"
});
CSS class hooks#
These stable CSS classes are available for targeting in custom CSS. Classes prefixed with widget- are part of the public API and won't change between releases.
Layout:
.widget-panel, .widget-header, .widget-title, .widget-subtitle, .widget-body, .widget-footer
Messages:
.widget-message-row, .widget-message-group, .widget-message-user, .widget-message-assistant, .widget-message-copy
Sources:
.widget-sources, .widget-sources-label, .widget-sources-list, .widget-sources-link
Recommendations:
.widget-recommendations, .widget-recommendation
Composer:
.widget-composer, .widget-composer-input, .widget-composer-button
Open button:
.widget-open-button, .widget-open-dot, .widget-badge-label
Empty and error states:
.widget-empty-state, .widget-error
Lead capture:
.widget-lead-row, .widget-lead-card, .widget-lead-headline, .widget-lead-description, .widget-lead-field-label, .widget-lead-input, .widget-lead-error, .widget-lead-submit, .widget-lead-success
Note: These classes are stable and safe to target. Internal class names (not prefixed with
widget-) may change between releases.
Callbacks#
Register callback functions to react to widget events:
window.HyperhelpWidget.init({
chatbotKey: "YOUR_WIDGET_KEY",
callbacks: {
onReady(payload) {
console.log("Widget loaded", payload);
},
onOpen(payload) {
// Track widget open in analytics
},
onClose(payload) {
// Track widget close
},
onConversationStart(payload) {
console.log("New conversation:", payload.conversationId);
},
onConversationReset(payload) {
// Visitor started a new conversation
},
onMessageSent(payload) {
console.log("Visitor asked:", payload.message);
},
onMessageDelta(payload) {
// Streaming chunk received (real-time)
},
onMessageCompleted(payload) {
console.log("Answer:", payload.answer);
console.log("Sources:", payload.sources);
},
onError(payload) {
console.error("Widget error:", payload.error);
},
onStatus(payload) {
console.log("Status:", payload.status);
}
}
});
Callback payload#
Every callback receives a payload object with these common fields:
| Field | Type | Description |
|---|---|---|
event |
string |
The event name (e.g., "open", "messageSent") |
widget |
object |
Widget API instance with open(), close(), isOpen() methods |
chatbotKey |
string |
The chatbot's widget key |
visitorId |
string |
Unique visitor identifier (persisted in localStorage) |
conversationId |
string | null |
Current conversation ID (null before first message) |
pageUrl |
string |
The page URL where the widget is embedded |
Event-specific fields#
| Callback | Additional fields |
|---|---|
onReady |
ready — boolean, status — readiness status string |
onMessageSent |
message — the visitor's question |
onMessageDelta |
delta — the streaming text chunk |
onMessageCompleted |
answer — full response text, sources — array of cited sources |
onError |
error — error description |
onStatus |
status — current widget status string |
Full example#
A complete embed snippet combining copy overrides, style overrides, and callbacks:
<script
src="https://app.hyperhelp.ai/widget/chat.js"
async
onload='window.HyperhelpWidget.init({
"chatbotKey": "YOUR_WIDGET_KEY",
"copy": {
"title": "Ask Acme",
"subtitle": "Answers from our docs",
"badge_label": "Help"
},
"styleOverrides": {
"openButton": { "backgroundColor": "#1e40af" },
"header": { "background": "linear-gradient(135deg, #1e40af, #3b82f6)" },
"title": { "color": "#ffffff" },
"subtitle": { "color": "#bfdbfe" }
},
"callbacks": {
"onConversationStart": function(p) {
analytics.track("widget_conversation", { page: p.pageUrl });
}
}
})'
></script>