window.hcWidget lets your page drive the widget: open and close it, point it at a category or an article, hand it sign-in tokens and fire events for proactive messages. It appears a moment after init.js runs, and takes commands once the widget is ready.
Plans: All plans. trigger() needs proactive messages with a Custom event rule (Growth and Catalyst). setJwt() needs single sign-on (Catalyst).
Methods
Method | What it does | Before the widget is ready |
|---|---|---|
| Opens the widget. After | Lost |
| Closes the widget to its launcher. | Lost |
| Hides the widget, launcher included, until the next | Works |
| Lists a category's articles on the home screen. Doesn't open the widget. | Lost |
| Loads an article, and opens the widget on it when | Lost |
| The same as | Lost |
| Hands the widget a sign-in token. | See Sign readers in, below |
| Returns | Returns |
| Fires a custom event for proactive messages. | Queued, up to 20 events |
| Runs | Queued |
| Removes the widget from the page. | Works |
Every method except isReady() returns undefined. None of them throws when the widget can't act on it: a lost call does nothing.
Wait until the widget is ready
The widget becomes ready a moment after init.js runs, once its frame has loaded and checked that your page's host is in Embedding origins. On a page whose host isn't on that list, it never becomes ready. For code that should run at startup, use onWidgetReady in your options:
window.hcOptions = {
app_id: 'YOUR_WIDGET_ID',
onWidgetReady: function () {
window.hcWidget.setCategory(4821);
}
};
For code that runs later, such as a click handler, wrap the call in onReady, and check for window.hcWidget first. It isn't there before init.js runs, nor for a moment after: init.js first loads a second script, for usage statistics, and only then creates window.hcWidget. So code that runs right after init.js, such as a load handler on its script tag, finds it undefined:
if (window.hcWidget) {
window.hcWidget.onReady(function () {
window.hcWidget.setHrefAndOpen('/content/reset-your-password');
});
}
To only check, window.hcWidget.isReady() returns true or false.
Open and close the widget
window.hcWidget.show(); // open the widget
window.hcWidget.hide(); // close it to the launcher
window.hcWidget.hideAll(); // hide it completely, launcher included
After hideAll(), the next show() opens the widget; there's no call that brings back only the launcher. With the launcher on (the default), that first show() opens a panel only a few pixels wide. Call show() a second time, a moment later, to open it at full width:
window.hcWidget.show();
setTimeout(function () {
window.hcWidget.show();
}, 300);
To keep the launcher off a page for good, use showButton: false in your options instead; see Open the widget from your own UI.
Show a category's articles
setCategory takes a category ID, as a number or a string, and lists up to seven published articles from that category and its subcategories on the home screen. It doesn't open the widget, so call show() when you want it open:
window.hcWidget.setCategory(4821);
window.hcWidget.show();
An ID that doesn't exist, or a category visitors can't see, lists your most viewed articles instead.
0,nulland other empty values are ignored. No call returns the home screen to its default list: reload the page for that.
Category IDs are in your help center's category addresses, /category/4821-billing, and in the Categories API; see Open the widget from your own UI.
Open an article
setHrefAndOpen opens the widget on an article. setHref loads it for later, without opening the widget:
window.hcWidget.setHrefAndOpen('https://help.example.com/content/reset-your-password');
// Loaded now, shown the next time the visitor opens the widget:
window.hcWidget.setHref('/content/reset-your-password');
Everything up to
/content/is ignored, so a full article URL and a path both work. What follows/content/is the article's slug in your default language: a translated address, such as/es/content/restablecer-tu-contrasena, doesn't find the article.setHref(href)withouttruecloses the widget if it's open.When no published article has that slug, the widget opens without it, on what it showed before.
An address without
/content/opens nothing, and the console logs "Unsupported content type for href."
Links on your page can do the same without code: see Open the widget from your own UI.
Sign readers in
On a private help center with JWT single sign-on, the widget gets its first token from the jwt option and asks onAuthExpired for each one after that. setJwt hands it a token outside that exchange:
window.hcWidget.setJwt(tokenFromYourServer);
The widget uses that token in two cases only: when it has never had a token (the token then signs its next request), and when a request is waiting for a token. Otherwise it discards the token. It never reloads what it shows by itself. So when a user signs in or out while the page is open, reload the page, or remove the widget and load it again with the new user's token (see Remove the widget, below). The complete setup is in Sign readers into the widget with a JWT.
Trigger a proactive message
A proactive message with a Custom event rule shows when your page fires that event. Pass the event name exactly as it's written in the rule:
window.hcWidget.trigger('checkout_failed');
Events fired before the widget is ready wait, up to 20 of them, and apply once it is. Proactive messages never show while the widget is open, or when the launcher is hidden with showButton: false. To see how your rules evaluate on a page, add ?hcnudge=debug to the page's address and open the browser console. Setting up messages and rules is covered in Invite visitors with proactive messages.
Remove the widget
destroy() takes the widget off your page. It removes the widget's frame, stops its proactive messages and usage statistics, and drops the trigger() events and onReady callbacks that are still waiting:
if (window.hcWidget) {
window.hcWidget.destroy();
}
Links with a
data-hc-articleattribute become ordinary links again. FAQ sections on the page stay.A second call does nothing.
window.hcWidgetstays defined. Its commands do nothing, but if the widget was ready,isReady()still returnstrueandonReady()still runs a callback, so neither tells you whether a widget is on the page.To put a widget back, for example when another user signs in, set
window.hcOptionsagain and loadinit.jsagain. Calldestroy()first: loadinginit.jsagain without it adds a second widget. Put the code that needs the new widget in the new options'onWidgetReady: until the new widget replaces it,window.hcWidgetis still the removed one.
Callbacks
Four options in window.hcOptions are functions the widget calls:
Option | Called | Details |
|---|---|---|
| Once, when the widget is ready for commands | Wait until the widget is ready, above |
| When a visitor asks to contact you | |
| Each time the widget needs a new sign-in token | |
| Many times, with | Below |
onStateChange is called when the widget opens or closes, whether the visitor or your code opened it, and many more times in between with the same value, each time the widget redraws: while it loads, while a visitor types a search, while an answer appears. Keep the callback quick, keep the last value, and act only when it changes:
var helpIsOpen = false;
window.hcOptions = {
app_id: 'YOUR_WIDGET_ID',
onStateChange: function (isOpen) {
if (isOpen === helpIsOpen) {
return;
}
helpIsOpen = isOpen;
document.getElementById('chat-button').hidden = isOpen;
}
};
An exception thrown in onWidgetReady or onAuthExpired, or in an onReady callback that waited for the widget, is caught and ignored. One thrown in onStateChange, or in an onReady callback added after the widget is ready, shows in the console as an uncaught error.
What the API doesn't do
No events about what visitors do in the widget. Besides the callbacks above, nothing tells your page that a visitor searched or read an article.
No resetting. There's no method to switch the widget's language or return it to its first state. Remove it with
destroy()and load it again, or reload the page.No identify call. To tell the widget who the visitor is, sign them in with a JWT.
No styling. The widget's look comes from your dashboard; see Match the widget to your brand.