@getcredify/credify-insurance-widget
v1.41.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.
Test Mode (internal)
Test mode is for walking the live flow — real API, real carriers, real SMS —
without the quote landing in the funnel stats. Quotes created in a test session
are flagged is_test and excluded from reporting. It is not a demo mode: use
Mock Mode for that.
Turn it on by loading the page with ?credify_test=1 (bare ?credify_test and
?credify_test=true also work; ?credify_test=0 turns it off):
https://your-site.com/insurance?credify_test=1The widget captures the flag, strips the parameter from the address bar, and
remembers it in sessionStorage for the rest of the browser session — the quote
is created a few stages in, long after the URL has been cleaned. While it is
active, an amber Test mode note sits above the step card on every screen, so
nobody has to check the database to find out whether the walkthrough counted.
Iframe embeds put the parameter on the iframe src instead, as with mock mode.
Choosing the flow
The widget quotes one product — Home, Auto, or Bundle — and it has to know
which before the first step renders: the product decides which stages exist, so
it is answered outside the form rather than inside it, exactly as the website's
/home-insurance and /auto-insurance routes do. The visitor is never asked
again during the flow.
Two ways to say it, in order of precedence:
1. A link parameter — ?credify_product=
https://partner.example.com/insurance?credify_product=autoThe widget picks up the product, opens straight into that flow, and strips the parameter from the address bar. Use it for campaign links, emails, and ads that should land in a specific funnel. Accepted values (case-insensitive):
| Product | Values |
| --- | --- |
| Home | home, home-insurance, homeowners |
| Auto | auto, auto-insurance, car, vehicle |
| Bundle | bundle, bundle-insurance |
An unrecognised value is ignored, and the visitor gets the page's own product.
2. The host's option — init({ product })
CredifyInsuranceWidget.init({ product: 'Auto' });What this page quotes by default, for an embed that sits on a product page. A
?credify_product= link overrides it for the visit that carries it.
With neither, the widget quotes Home.
Iframe embeds can use either the ?credify_product= parameter on the iframe
src or the product field on the init message; the parameter wins, and
unlike the script-tag embed it does not open the modal — visibility stays with
the parent's open message.
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). Accepts an optionalproduct: 'Home' | 'Auto' | 'Bundle'— see Choosing the flow
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; product?: 'Home' | 'Auto' | 'Bundle' }): 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, andproductto say which flow the page quotes (see Choosing the flow).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
