@loyalguru/embed-sdk
v1.0.0
Published
SDK to embed Loyal Guru White Label modules (loyalty, CDP, coupons, login) into external websites and apps using an iframe-based approach.
Readme
WhiteLabel SDK
SDK to embed Loyal Guru White Label modules (loyalty, CDP, coupons, login) into external websites and apps using an iframe-based approach.
This SDK creates and manages an <iframe> that points to your White Label webview (hosted in Loyal Guru infra or in your environment), sends the auth token to it, listens for resize events, and exposes hooks for token refresh and analytics events.
Features
- Simple initialization using a container
div - Supports multiple modules:
loyalty,cdp,coupons,login - Secure token
- Optional auto-resize (iframe grows/shrinks based on content height)
- Hooks for:
onLoadonErroronSize(height/width from iframe)- token refresh request (
REQUEST_NEW_TOKEN)
- GTM support via
LG_DATALAYER_EVENT(pushes intowindow.dataLayer)
Installation
1. From source (local development)
git clone https://github.com/loyalguru/WhiteLabel-SDK.git
cd WhiteLabel-SDK
npm installThe project uses Rollup to build a UMD bundle (
embed-sdk.umd.js) and TypeScript for typings.
Build
To generate the distributable bundle:
npm run buildThis will create the compiled files inside the dist/ folder (according to your current package.json):
dist/embed-sdk.umd.js→ UMD bundle you can include in a<script>dist/index.d.ts→ TypeScript declarations
Publish this to npm/GitHub Packages or serve it from a static/CDN bucket.
Usage
Load the SDK in a plain HTML page and initialize it like this:
<!DOCTYPE html>
<html>
<head>
<title>Test SDK</title>
<!-- Load the built SDK (UMD) -->
<script src="embed-sdk.umd.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<!-- Container where the iframe will be injected -->
<div id="loyalty-container"></div>
<script>
// Initialize the SDK
EmbedLoyaltyApp.init({
containerId: 'loyalty-container',
module: 'loyalty', // 'loyalty' | 'cdp' | 'coupons' | 'login'
iframeOrigin: 'http://localhost:4200', // URL where the white-label modules are hosted
token: 'YOUR_JWT_TOKEN_HERE', // JWT generated by your backend
locale: 'fr', // optional, defaults to 'en'
autoResize: false, // true: iframe resizes automatically
onLoad: () => console.log('[host] Iframe loaded'),
onSize: ({ height }) => console.log('[host] iframe height:', height),
onError: (err) => console.error('Loyalty iframe error', err)
});
// Listen for token refresh requests coming from the iframe
EmbedLoyaltyApp.onTokenRefreshRequested(async () => {
// fetch/refresh token from your backend
const newToken = 'NEW_TOKEN_FROM_BACKEND';
EmbedLoyaltyApp.refreshToken(newToken);
console.log('Token refreshed and sent to iframe');
});
// Listen to size messages (alternative way)
EmbedLoyaltyApp.onSizeRequested(({ height, width }) => {
console.log('[host] SIZE via onSizeRequested =>', height, width);
});
</script>
</body>
</html>API
EmbedLoyaltyApp.init(config: InitConfig)
Creates the iframe and injects it into the container.
Config shape:
type EmbedModule = 'loyalty' | 'cdp' | 'coupons' | 'login';
type InitConfig = {
containerId: string; // id of the DOM element where the iframe will be appended
module: EmbedModule; // module to load from the white-label host
iframeOrigin: string; // e.g. https://wl.loyalguru.com
token: string; // JWT to authenticate user/session
locale?: string; // optional, defaults to 'en'
onLoad?: () => void;
onError?: (e: Error) => void;
onSize?: (payload: { height: number; width?: number; origin: string }) => void;
autoResize?: boolean; // if true, SDK updates iframe height on SIZE messages
};What it does internally:
- Finds the container (
document.getElementById(...)) - Creates an
<iframe>pointing to:${iframeOrigin}/${module} - Adds secure-ish sandbox attributes:
allow-scripts, allow-same-origin, allow-popups, allow-popups-to-escape-sandbox - Sends the auth token to the iframe using
postMessage:{ type: 'AUTH_TOKEN', token: '...', locale: '...' } - Listens for messages coming from iframe:
REQUEST_NEW_TOKENLG_DATALAYER_EVENTSIZE
EmbedLoyaltyApp.refreshToken(newToken: string)
Updates the token stored in the SDK and sends it again to the iframe.
Use this when backend issues a new JWT (expiration, refresh flow, etc.):
EmbedLoyaltyApp.refreshToken(freshTokenFromBackend);EmbedLoyaltyApp.onTokenRefreshRequested(callback: () => void)
The iframe can send a message:
{ "type": "REQUEST_NEW_TOKEN" }When that happens, the SDK will call to the callback. Call your backend, get a fresh token and call refreshToken(...).
Example:
EmbedLoyaltyApp.onTokenRefreshRequested(async () => {
const newToken = await fetchNewTokenSomehow();
EmbedLoyaltyApp.refreshToken(newToken);
});EmbedLoyaltyApp.onSizeRequested(callback)
Even if autoResize is off, you can still listen to size reports coming from the iframe:
EmbedLoyaltyApp.onSizeRequested(({ height, width, origin }) => {
console.log('Iframe wants to be', height, 'px high');
});EmbedLoyaltyApp.destroy()
Removes the iframe from the DOM and clears internal references.
EmbedLoyaltyApp.destroy();Messages from the iframe
The SDK listens to window.postMessage from the iframe. Current supported messages:
REQUEST_NEW_TOKEN-> triggers the registeredonTokenRefreshRequestedcallback.LG_DATALAYER_EVENT-> pushesdata.payloadintowindow.dataLayer(for GTM).SIZE→{ type: 'SIZE', height: number, width?: number }- If
autoResizeistrue, the SDK updatesiframe.style.height. - Also forwards this to
onSize/onSizeRequested.
- If
Styling & Iframe behavior
The iframe is created with these default styles:
Object.assign(this.iframe.style, {
border: 'none',
width: '100%',
height: autoResize ? '0px' : '100vh',
margin: '0',
padding: '0',
display: 'block',
backgroundColor: 'transparent',
overflow: 'hidden',
transition: 'height 0.25s ease',
'max-height': '100vh'
});If the parent host page has scroll constraints, you can override these with your own CSS.
Development Notes
The SDK currently does not strictly enforce
event.originin themessagelistener (the line is commented):// if (event.origin !== this.origin) return;In production should keep origin checks enabled to avoid processing messages from unknown sources.
The iframe URL is built as
${iframeOrigin}/${module}. Make sure your white-label host actually serves those routes.If you plan to publish to npm as
@loyalguru/embed-sdk, update therepository,name, and CI workflow accordingly.
