SDK Reference
The JavaScript SDK provides programmatic control over widget initialization, theming, prefill, modal mode, and event handling.
Installation
Script tag (CDN)
<script src="https://cdn.benefithub.com/widget/v1/widget.js"></script>
<!-- The SDK exposes window.BHWidget -->
<script>
const widget = BHWidget.init({
key: 'YOUR_KEY',
type: 'auto',
baseUrl: 'https://widget.benefithub.insure',
});
</script>npm / pnpm (coming soon)
The @benefithub/insurance-widget npm package is not yet published. Use the CDN script tag above in the meantime.
BHWidget.init(config)
Creates and inserts the widget. Returns a BHWidgetInstance for later control. All config properties are flat (not nested):
const widget = BHWidget.init({
key: 'wk_abc123',
type: 'auto',
container: '#my-container',
mode: 'embedded',
baseUrl: 'https://widget.benefithub.insure',
agentId: 'agent_456',
// Theme — flat properties, not a nested object
'color-primary': '#1a365d',
'color-accent': '#3182ce',
'color-btn': '#2563eb',
'color-btn-text': '#ffffff',
'border-radius': '12px',
// Prefill — flat properties, not a nested object
firstName: 'Jane',
lastName: 'Doe',
email: 'jane@example.com',
zip: '90210',
// Callbacks
onReady: () => console.log('Ready'),
onQuoteResults: (count) => console.log(count + ' quotes'),
onOpen: () => console.log('Modal opened'),
onClose: () => console.log('Modal closed'),
});Config Properties
| Property | Type | Default | Description |
|---|---|---|---|
| key | string | -- | Required. Widget authentication key. |
| type | 'auto' | 'home' | 'auto' | Insurance quote type. |
| container | string | '#bh-insurance-widget' | CSS selector for the container element. |
| mode | 'embedded' | 'modal' | 'embedded' | Display as inline embed or centered modal overlay. |
| baseUrl | string | auto-detected | Widget app URL. Required when loading SDK from CDN. |
| agentId | string | -- | Vendor/agent ID for attribution. |
| logo / logoUrl | string | -- | Custom logo URL (replaces default logo). Both property names are accepted. |
Theme Properties
Theme values are passed as flat config properties, not a nested object. Both short and long aliases are accepted:
| Property | Alias | Description |
|---|---|---|
| color-primary | -- | Primary brand color |
| color-accent | -- | Accent/highlight color |
| color-bg | color-background | Page background color |
| color-surface | -- | Card/surface background |
| color-text | -- | Primary text color |
| color-text-secondary | -- | Secondary/muted text color |
| color-btn | color-button-primary | Button background color |
| color-btn-text | color-button-text | Button text color |
| color-input-border | -- | Form input border color |
| color-input-focus | -- | Form input focus ring color |
| color-progress | -- | Progress bar color |
| font-family | -- | Font family name |
| border-radius | -- | Border radius (e.g., "12px") |
| max-width | -- | Max width of widget (e.g., "600px") |
| padding | -- | Inner padding (e.g., "24px") |
Prefill Properties
Prefill values are passed as flat config properties. PII is sent securely via postMessage after the iframe loads — never in the URL.
| Property | Description |
|---|---|
| firstName | First name |
| lastName | Last name |
| Email address | |
| phone | Phone number |
| zip | ZIP code |
| address | Street address |
| city | City |
| state | State abbreviation |
Event Callbacks
| Callback | Signature | Description |
|---|---|---|
| onReady | () => void | Widget iframe loaded and ready. |
| onStep | (step: number, name: string) => void | User navigated to a form step. |
| onQuoteSubmitted | () => void | Quote request submitted to carriers. |
| onQuoteResults | (count: number) => void | Quotes received. count is the number of results. |
| onNoQuotes | () => void | No quotes were returned. |
| onError | (message: string) => void | An error occurred. |
| onUserRegistered | (email: string) => void | User registered/logged in. |
| onResize | (height: number) => void | Content height changed. Iframe auto-resizes. |
| onOpen | () => void | Modal opened (modal mode only). |
| onClose | () => void | Modal closed (modal mode only). |
| onMessage | (data: object) => void | Catch-all handler for every bh:* message from the widget. |
BHWidgetInstance
Returned by BHWidget.init().
| Method | Returns | Description |
|---|---|---|
| open() | void | Open the modal overlay (modal mode only). Fires onOpen callback and bh:modal-open CustomEvent. |
| close() | void | Close the modal overlay. Fires onClose callback and bh:modal-close CustomEvent. |
| isOpen() | boolean | Returns whether the modal is currently visible. |
| destroy() | void | Remove the widget iframe, modal overlay, and clean up event listeners. |
| getIframe() | HTMLIFrameElement | null | Get a reference to the underlying iframe element. |
Static Methods
| Method | Returns | Description |
|---|---|---|
| BHWidget.init(config) | BHWidgetInstance | Create a new widget instance. |
| BHWidget.getInstance() | BHWidgetInstance | null | Get the auto-initialized instance (from script tag with data-bh-* attributes). |
Modal Mode Example
<button id="quote-btn">Get Insurance Quote</button>
<div id="bh-insurance-widget"></div>
<script src="https://cdn.benefithub.com/widget/v1/widget.js"></script>
<script>
const widget = BHWidget.init({
key: 'wk_abc123',
type: 'auto',
mode: 'modal',
baseUrl: 'https://widget.benefithub.insure',
onOpen: () => console.log('Modal opened'),
onClose: () => console.log('Modal closed'),
});
// Open on button click
document.getElementById('quote-btn')
.addEventListener('click', () => widget.open());
// Also dispatches CustomEvents you can listen to:
window.addEventListener('bh:modal-open', () => {
analytics.track('insurance_modal_opened');
});
</script>Full Embedded Example
<div id="insurance-widget"></div>
<script src="https://cdn.benefithub.com/widget/v1/widget.js"></script>
<script>
const widget = BHWidget.init({
key: 'wk_abc123',
type: 'auto',
container: '#insurance-widget',
baseUrl: 'https://widget.benefithub.insure',
mode: 'embedded',
agentId: 'agent_456',
logoUrl: 'https://example.com/logo.png',
// Theme colors (flat — not nested)
'color-primary': '#1a365d',
'color-accent': '#3182ce',
'color-btn': '#2563eb',
'color-btn-text': '#ffffff',
'border-radius': '12px',
// Prefill (flat — not nested)
firstName: 'Jane',
lastName: 'Doe',
email: 'jane@example.com',
phone: '5551234567',
zip: '90210',
onReady: () => {
console.log('Widget ready');
},
onStep: (step, name) => {
analytics.track('insurance_step', { step, name });
},
onQuoteResults: (count) => {
analytics.track('insurance_quotes', { count });
},
onError: (msg) => {
console.error('Widget error:', msg);
},
});
// Clean up when navigating away (SPA)
window.addEventListener('beforeunload', () => widget.destroy());
</script>