@getcredify/credify-insurance-widget
v1.33.1
Published
Credify Insurance Widget - Embeddable React widget for insurance quotes
Readme
Credify Insurance Widget
A React-based insurance quote widget that can be installed via npm package or embedded via script tag or iframe.
Installation
As an npm Package
npm install @getcredify/credify-insurance-widgetPeer Dependencies
This package requires React 18+ or React 19+ as a peer dependency:
npm install react@^18.0.0 react-dom@^18.0.0
# or
npm install react@^19.0.0 react-dom@^19.0.0Note: The widget is compatible with React 18.x and 19.x. React is not bundled with the widget, so your application must provide it. The library build externalizes all React entry points (react, react-dom, react-dom/client, react/jsx-runtime), so the host must provide a single React/React-DOM (18.x or 19.x). The widget uses React 18+ APIs (like createRoot from react-dom/client), which are available in both React 18 and 19.
For Local Development
npm installDevelopment
Library Mode (Script Tag)
npm run devIframe Mode
npm run dev:iframeBuilding
Build both library and iframe versions:
npm run buildBuild only library version:
npm run build:libBuild only iframe version:
npm run build:iframeEmbedding Methods
Method 1: npm Package (Recommended)
Install and import the widget in your React application:
import { CredifyInsuranceWidget } from '@getcredify/credify-insurance-widget';
function App() {
useEffect(() => {
// Initialize the widget (styles are injected automatically)
CredifyInsuranceWidget.init({ autoOpen: false });
}, []);
return (
<div>
<button onClick={() => CredifyInsuranceWidget.open()}>Open Widget</button>
<button onClick={() => CredifyInsuranceWidget.close()}>Close Widget</button>
</div>
);
}Note: The widget injects its own styles at runtime. You can optionally import @getcredify/credify-insurance-widget/widget.css if you prefer to load styles separately (e.g. for caching).
Method 2: Script Tag Embedding (UMD)
Include the widget as a script tag on your page. No separate CSS file is required—styles are injected when the script runs.
<!DOCTYPE html>
<html>
<head>
<script src="https://widget.getcredify.com/index.umd.js"></script>
<!-- Also include React and ReactDOM if not already present -->
<!-- For React 18: Use UMD builds -->
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<!-- For React 19: Use ESM (no UMD builds available) -->
<!-- <script type="module">
import React from 'https://esm.sh/react@19';
import ReactDOM from 'https://esm.sh/react-dom@19';
window.React = React;
window.ReactDOM = ReactDOM;
</script> -->
</head>
<body>
<button onclick="window.CredifyInsuranceWidget.open()">Open Widget</button>
<script>
// Initialize the widget
window.CredifyInsuranceWidget.init({ autoOpen: false });
// Open the widget
function openWidget() {
window.CredifyInsuranceWidget.open();
}
// Close the widget
function closeWidget() {
window.CredifyInsuranceWidget.close();
}
</script>
</body>
</html>See examples/umd.html for a complete example.
CDN Options:
The widget is available via CDN. We recommend using our CloudFront CDN:
<script src="https://widget.getcredify.com/index.umd.js"></script>Alternatively, the package is also available via unpkg.com:
<script src="https://unpkg.com/@getcredify/credify-insurance-widget/dist/index.umd.js"></script>Method 3: Iframe Embedding (Cross-Origin)
The widget can be embedded as an iframe on different origins. This is useful for:
- Isolating the widget from your site's CSS/JavaScript
- Serving the widget from a different domain
- Better security and performance isolation
Step 1: Deploy the Widget
After building with npm run build:iframe, deploy the contents of dist/iframe/ to your server.
Note: The iframe HTML is available at @getcredify/credify-insurance-widget/iframe after installation, but typically you'll want to deploy it to your own server.
Step 2: Embed the Iframe
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<button id="open-btn">Open Widget</button>
<button id="close-btn">Close Widget</button>
<iframe
id="widget-iframe"
src="https://your-widget-domain.com/iframe.html"
width="100%"
height="700"
style="border: none;"
allow="clipboard-read; clipboard-write"
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
></iframe>
<script>
const iframe = document.getElementById('widget-iframe');
// Open the widget
document.getElementById('open-btn').addEventListener('click', () => {
iframe.contentWindow.postMessage(
{
type: 'open',
source: 'credify-insurance-widget'
},
'https://your-widget-domain.com'
);
});
// Close the widget
document.getElementById('close-btn').addEventListener('click', () => {
iframe.contentWindow.postMessage(
{
type: 'close',
source: 'credify-insurance-widget'
},
'https://your-widget-domain.com'
);
});
// Listen for events from the widget
window.addEventListener('message', (event) => {
// Verify origin for security
if (event.origin !== 'https://your-widget-domain.com') return;
if (event.data?.source === 'credify-insurance-widget') {
switch (event.data.type) {
case 'ready':
console.log('Widget is ready');
break;
case 'opened':
console.log('Widget opened');
break;
case 'closed':
console.log('Widget closed');
break;
}
}
});
</script>
</body>
</html>See examples/iframe.html for a complete example.
Full Page Mode
The simplest way to integrate the widget is to embed it directly in your page and open it as a full-page modal overlay. This provides the best user experience as the widget gets the full screen space in the current window.
Step 1: Load the Widget
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<!-- Load React and ReactDOM (required peer dependencies) -->
<!-- For React 18: Use UMD builds -->
<!-- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> -->
<!-- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> -->
<!-- For React 19: Use ESM (no UMD builds available) -->
<script type="module">
// Import React 19 as ESM modules - use exact same version for both
import React from 'https://esm.sh/[email protected]';
import ReactDOM from 'https://esm.sh/[email protected]';
// Expose as globals for the UMD widget build
window.React = React;
window.ReactDOM = ReactDOM;
// Load the widget script after React is available
const script = document.createElement('script');
script.src = 'https://widget.getcredify.com/index.umd.js';
script.onload = () => {
window.dispatchEvent(new Event('widget-loaded'));
};
document.head.appendChild(script);
</script>
</head>
<body>
<button id="open-btn">Get Insurance Quote</button>
<script>
window.addEventListener('DOMContentLoaded', () => {
// Initialize the widget (don't auto-open)
window.CredifyInsuranceWidget.init({ open: false });
// Open the widget when button is clicked
document.getElementById('open-btn').addEventListener('click', () => {
window.CredifyInsuranceWidget.open();
});
});
</script>
</body>
</html>The widget will open as a full-page modal overlay that covers the entire viewport. Users can close it by clicking the close button or pressing Escape.
Benefits of Full Page Mode:
- ✅ Full-page modal overlay - widget takes full screen space
- ✅ No iframe restrictions - full access to browser features
- ✅ Easier to implement - no postMessage API needed
- ✅ Better mobile experience - full screen on mobile devices
- ✅ Same origin - no cross-origin communication needed
See examples/fullpage.html for a complete example.
Mock Mode (Demo / Test Drive)
Mock mode lets you walk through the entire quote flow — postal code, every form stage, SMS verification, rate results, and bind — without entering real data or submitting a real quote. While active, every widget API call is answered from built-in sample data instead of hitting Credify's servers, so no SMS is sent and no quote is ever created.
Use it to demo or evaluate the widget on your own page before going live.
Enabling it
Mock mode is gated by an unguessable key, provided by the Credify team. It turns
on only when the page the widget runs in is loaded with a matching ?mock=<key>
query parameter — so where you add it depends on which embedding method (above) you
use:
npm Package, Script Tag (UMD), or Full Page Mode — the widget runs in your own page, so add
?mock=<key>to that page's address:https://your-site.com/insurance?mock=YOUR_KEY_FROM_CREDIFYIframe Embedding — the widget runs inside the iframe, so add
?mock=<key>to the iframe'ssrc:<iframe src="https://your-widget-domain.com/iframe.html?mock=YOUR_KEY_FROM_CREDIFY"></iframe>
Open and step through the widget exactly as a real user would. A small red
MOCK MODE badge appears in the bottom-left corner as a reminder that nothing is
being submitted. Remove the ?mock= parameter to return to the live flow.
Note: Without the matching key, mock mode stays completely off and the widget talks to the live API as usual — so the same embed code is safe to ship to production. The key only gates demo behaviour in the browser session that supplies it; it grants no access and carries no risk if shared.
PostMessage API
When using iframe embedding, the widget communicates via the postMessage API.
Commands (Parent → Widget)
Send these messages to the widget:
{ type: 'open', source: 'credify-insurance-widget' }- Opens the widget{ type: 'close', source: 'credify-insurance-widget' }- Closes the widget{ type: 'init', source: 'credify-insurance-widget' }- Initializes the widget (sent automatically)
Events (Widget → Parent)
Listen for these events from the widget:
{ type: 'ready', source: 'credify-insurance-widget' }- Widget is ready{ type: 'opened', source: 'credify-insurance-widget' }- Widget has opened{ type: 'closed', source: 'credify-insurance-widget' }- Widget has closed
Funnel/analytics events are also forwarded with type: 'event':
{ type: 'event', source: 'credify-insurance-widget', event, data }
where event is one of widgetOpened, widgetClosed, stageViewed,
stageCompleted, flowCompleted, ratesViewed, ratesBack, submissionFailed,
and data is the matching payload documented under Events. Example:
window.addEventListener('message', (e) => {
if (e.data?.source !== 'credify-insurance-widget' || e.data.type !== 'event') return;
if (e.data.event === 'stageCompleted') {
analytics.track('insurance_step', { step: e.data.data.stageKey });
}
});Server Configuration
When serving the widget for iframe embedding, ensure your server:
Allows iframe embedding - Do NOT set
X-Frame-Options: DENYorX-Frame-Options: SAMEORIGINheaders. To allow embedding from specific origins, use Content Security Policy:Content-Security-Policy: frame-ancestors 'self' https://example.com https://another-domain.com;Sets CORS headers (if needed for API calls):
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Content-Type, AuthorizationServes the iframe HTML from the
dist/iframe/directory after building
Security Considerations
- Origin Verification: In production, always verify
event.originwhen receiving postMessage events to prevent XSS attacks - Specific Origins: Replace
'*'with specific origins in postMessage calls for better security - HTTPS: Always serve the widget over HTTPS in production
- CSP: Consider implementing Content Security Policy headers for additional protection
API Reference
Script Tag API
interface CredifyInsuranceWidgetAPI {
init(options?: { autoOpen?: boolean }): void;
open(): void;
close(): void;
destroy(): void;
on<E extends WidgetEventName>(event: E, callback: (data: WidgetEventMap[E]) => void): void;
off<E extends WidgetEventName>(event: E, callback: (data: WidgetEventMap[E]) => void): void;
}init(options?)- Initialize the widget. SetautoOpen: trueto open immediately.open()- Open the widgetclose()- Close the widgetdestroy()- Remove the widget from the DOMon(event, callback)- Subscribe to a widget event (see below)off(event, callback)- Unsubscribe a previously registered callback
Events
Subscribe to widget lifecycle and funnel events to forward them to your own
analytics (Segment, GTM, Amplitude, etc.). Register listeners before calling
init/open, since widgetOpened fires as the widget mounts.
CredifyInsuranceWidget.on('stageCompleted', (data) => {
analytics.track('insurance_step', { step: data.stageKey });
});| Event | Payload | Fires when |
| ------------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------- |
| widgetOpened | none | The widget overlay opens |
| widgetClosed | none | The widget overlay closes |
| stageViewed | { stageKey, stageTitle, stepIndex, totalSteps } | A form stage becomes visible |
| stageCompleted | { stageKey, stageTitle, stepIndex, totalSteps } | A form stage is successfully completed |
| flowCompleted | none | All stages are done and rate generation starts |
| ratesViewed | { rateCount: number } | The rates screen is shown |
| ratesBack | none | The user navigates back from the rates screen |
| submissionFailed | { reason: 'submission' \| 'timeout' \| 'network' } | A quote submission fails (worker error, timeout, or repeated network errors) |
The event names and payload types (WidgetEventName, WidgetEventMap,
StageEventData) are exported from the package for TypeScript consumers. Host
callbacks are invoked in isolation — a throwing callback is reported and never
breaks the widget.
Iframe embedding: the same events are delivered to the parent window over postMessage instead (see Events (Widget → Parent)), because the in-iframe emitter is not reachable from the host page.
Examples
See the examples/ directory for complete working examples:
umd.html- Script tag embeddingiframe.html- Iframe embedding with postMessage communicationfullpage.html- Full page widget opened in a new window/tab
