Widget API
Control the widget programmatically — open, close, dismiss, identify visitors, and subscribe to events from anywhere in your app or via window.Helpway.
The Helpway widget exposes a global window.Helpway API that works from any framework, script tag, or plain JavaScript. It's also available as the return value of the onReady callback in the React component.
Quick reference
// Panel control
window.Helpway.open()
window.Helpway.close()
window.Helpway.toggle()
// Launcher visibility
window.Helpway.dismiss() // hide launcher + panel (per-page)
window.Helpway.show() // re-show launcher after dismiss
// Session
window.Helpway.shutdown() // full reset: cookies, localStorage, state
// Visitor identity
window.Helpway.identify({ externalId: "u_123", email: "j@acme.com", name: "Jane" })
// Navigation
window.Helpway.newConversation("I need help with billing")
window.Helpway.openConversation("conv_abc")
// Read-only state
window.Helpway.unreadCount // number
window.Helpway.isOpen // boolean
// Events
window.Helpway.on("open", () => { /* ... */ })
window.Helpway.on("unreadChange", (count) => { /* ... */ })
window.Helpway.off("open", myHandler)Type safety
window.Helpway is fully typed. Importing @helpway/react automatically augments the global Window interface — no extra setup needed:
// TypeScript knows about window.Helpway after this import
import "@helpway/react";
window.Helpway?.open(); // ✓ auto-complete worksMethods
open()
Open the widget panel. If the widget was dismissed, it also un-dismisses.
document.querySelector("#help-btn").addEventListener("click", () => {
window.Helpway.open();
});close()
Close the widget panel. The launcher bubble remains visible.
toggle()
Toggle between open and closed. If the widget was dismissed, it un-dismisses and opens.
dismiss()
Hide the widget entirely — both the panel and the launcher bubble. Use this for page-specific hiding:
// Hide on checkout pages
if (location.pathname.startsWith("/checkout")) {
window.Helpway.dismiss();
}show()
Re-show the launcher after a dismiss(). The panel stays closed — the visitor can open it by clicking the bubble.
shutdown()
Full session reset: closes the panel, clears the hw_visitor cookie, removes the localStorage visitor ID, and resets all widget state. Use on sign-out:
function signOut() {
window.Helpway.shutdown();
// ...your own sign-out flow
}identify(data)
Link the current visitor to a known contact in your system:
window.Helpway.identify({
externalId: "u_12345", // required — your user ID
email: "jane@acme.com", // optional
name: "Jane Doe", // optional
image: "https://...", // optional — avatar URL
metadata: { // optional — custom data
plan: "pro",
company: "Acme Inc",
},
});The contact appears in the Helpway dashboard with the name, email, and metadata you pass. Call this after your own authentication completes.
newConversation(prefill?)
Open the widget to the "new conversation" view, optionally pre-filling the message input:
// Open with pre-filled text
window.Helpway.newConversation("I need help setting up SSO");
// Open empty
window.Helpway.newConversation();openConversation(id)
Open the widget directly to a specific conversation:
window.Helpway.openConversation("conv_abc123");Useful for deep links from email notifications (the ?hw_conv= URL param does this automatically).
Getters
unreadCount
Returns the total number of unread messages across all conversations.
const badge = document.querySelector("#support-badge");
window.Helpway.on("unreadChange", (count) => {
badge.textContent = count > 0 ? String(count) : "";
});isOpen
Returns true if the widget panel is currently open.
Events
Subscribe to widget lifecycle events with on() and unsubscribe with off().
| Event | Payload | When |
|---|---|---|
open | — | Panel opened |
close | — | Panel closed |
dismiss | — | Widget dismissed via dismiss() |
show | — | Widget re-shown via show() or toggle() |
unreadChange | number | Unread count changed |
messageReceived | { conversationId, text, senderName } | Incoming message from team or AI |
ready | — | Widget bootstrapped and ready for API calls |
// Wait for ready before calling API methods
window.Helpway.on("ready", () => {
window.Helpway.identify({ externalId: currentUser.id });
});
// Custom unread badge
window.Helpway.on("unreadChange", (count) => {
document.title = count > 0 ? `(${count}) My App` : "My App";
});Common patterns
Custom launcher button
Hide the default bubble and trigger from your own UI:
<HelpwayWidget
apiKey="pk_live_xxx"
hideLauncher
customLauncherSelector="#my-support-btn"
/>
<button id="my-support-btn">
Contact Support ({unreadCount})
</button>Or without the selector prop — just call open() directly:
<HelpwayWidget apiKey="pk_live_xxx" hideLauncher />
<button onClick={() => window.Helpway.open()}>
Get Help
</button>Navbar link trigger
<nav>
<a href="/docs">Docs</a>
<a href="#" id="support-link">Support</a>
</nav><HelpwayWidget
apiKey="pk_live_xxx"
hideLauncher
customLauncherSelector="#support-link"
/>Hide on specific pages
function App() {
const isCheckout = location.pathname.startsWith("/checkout");
return (
<>
<Routes />
<HelpwayWidget
apiKey="pk_live_xxx"
hideLauncher={isCheckout}
/>
</>
);
}Or imperatively from vanilla JS:
// SPA route change
router.on("navigate", (path) => {
if (path.startsWith("/checkout")) {
window.Helpway.dismiss();
} else {
window.Helpway.show();
}
});Custom unread badge on your own button
function SupportButton() {
const [count, setCount] = useState(0);
useEffect(() => {
const handler = (n: number) => setCount(n);
window.Helpway?.on("unreadChange", handler);
return () => window.Helpway?.off("unreadChange", handler);
}, []);
return (
<button onClick={() => window.Helpway?.open()}>
Support {count > 0 && <span className="badge">{count}</span>}
</button>
);
}Identify after auth
<HelpwayWidget
apiKey="pk_live_xxx"
onReady={(api) => {
if (currentUser) {
api.identify({
externalId: currentUser.id,
email: currentUser.email,
name: currentUser.name,
metadata: {
plan: currentUser.plan,
company: currentUser.company,
},
});
}
}}
/>React props reference
These props on <HelpwayWidget> mirror the global API:
| Prop | Type | Description |
|---|---|---|
hideLauncher | boolean | Hide the default floating bubble |
customLauncherSelector | string | CSS selector — clicking the element calls toggle() |
onOpen | () => void | Fires when the panel opens |
onClose | () => void | Fires when the panel closes |
onUnreadChange | (count: number) => void | Fires when unread count changes |
onReady | (api: HelpwayAPI) => void | Fires once after bootstrap, gives full API object |
See React SDK for the full props table including apiKey, locale, and framework setup.