xempla-embedded
v1.2.8
Published
Embedded widget for Xempla AI integration
Readme
Xempla Embedded Widget
A drop-in chat widget for Xempla AI integration that works in any web app.
What you get
- A floating launcher button + chat panel UI
- CDN (script tag) integration for non-framework sites
- NPM/ESM loader for modern apps (React/Vue/etc.)
Table of Contents
- Quickstart (copy/paste)
- Installation
- Version pinning (recommended for production)
- Prerequisites
- Usage
- Configuration Options
- Common integration notes
- Troubleshooting
Quickstart (copy/paste)
CDN
<script
src="https://unpkg.com/xempla-embedded/dist/xempla-embedded.umd.js"
defer
data-auto-init="true"
data-client-key="YOUR_CLIENT_KEY"
data-api-endpoint="https://api.your-domain.com"
></script>Important: Ensure the required hidden inputs are present before this script executes. See the Prerequisites section below.
npm (ESM)
import { XemplaWidgetLoader } from 'xempla-embedded';
new XemplaWidgetLoader({
clientKey: 'YOUR_CLIENT_KEY',
apiEndpoint: 'https://api.your-domain.com'
}).init();Note: Ensure the required hidden inputs are present in your page before initialization. See the Prerequisites section below.
Installation
npm
npm install xempla-embeddedCDN
You can use the widget directly via CDN (unpkg, jsdelivr, etc.):
<script src="https://unpkg.com/xempla-embedded/dist/xempla-embedded.umd.js"></script>Version pinning (recommended for production)
To avoid unexpected breaking changes, pin the widget to a specific version.
npm
npm install [email protected]To allow non-breaking updates, use a compatible range (example: xempla-embedded@^1.2.2).
CDN (unpkg)
<script
src="https://unpkg.com/[email protected]/dist/xempla-embedded.umd.js"
defer
data-auto-init="true"
data-client-key="YOUR_CLIENT_KEY"
data-api-endpoint="https://api.your-domain.com"
></script>Usage
1) CDN (Script Tag) — recommended for non-React apps
The easiest way is to include the script and configure it with data- attributes (auto-initialization).
The only required attributes are data-client-key and data-api-endpoint.
<!-- Include the widget script from CDN -->
<script
src="https://unpkg.com/xempla-embedded/dist/xempla-embedded.umd.js"
defer
data-auto-init="true"
data-client-key="YOUR_CLIENT_KEY"
data-api-endpoint="https://api.your-domain.com"
data-position="bottom-right"
data-primary-color="#4a86e8"
data-header-text="Support Assistant"
></script>Programmatic Initialization
Alternatively, you can initialize it manually:
<script src="https://unpkg.com/xempla-embedded/dist/xempla-embedded.umd.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function () {
if (window.xemplaWidgetInit) {
window.xemplaWidgetInit({
clientKey: 'YOUR_CLIENT_KEY',
apiEndpoint: 'https://api.your-domain.com',
position: 'bottom-left',
primaryColor: '#ff5722'
});
}
});
</script>2) ESM (React/Vue/etc.)
If you are building a modern web app (React, Vue, etc.), you can import the loader directly.
import { XemplaWidgetLoader } from 'xempla-embedded';
// Initialize the widget
const widget = new XemplaWidgetLoader({
clientKey: 'YOUR_CLIENT_KEY',
apiEndpoint: 'https://api.your-domain.com',
position: 'bottom-right'
});
widget.init();
// To destroy/cleanup
// widget.destroy();React example (recommended pattern)
import { useEffect } from 'react';
import { XemplaWidgetLoader } from 'xempla-embedded';
export function SupportWidget() {
useEffect(() => {
const widget = new XemplaWidgetLoader({
clientKey: 'YOUR_CLIENT_KEY',
apiEndpoint: 'https://api.your-domain.com'
});
widget.init();
return () => widget.destroy();
}, []);
return null;
}Angular example
import { isPlatformBrowser } from '@angular/common';
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
import { XemplaWidgetLoader } from 'xempla-embedded';
@Component({
selector: 'app-xempla-widget',
template: ''
})
export class XemplaWidgetComponent implements OnInit, OnDestroy {
private widget?: XemplaWidgetLoader;
constructor(@Inject(PLATFORM_ID) private platformId: object) {}
ngOnInit(): void {
if (!isPlatformBrowser(this.platformId)) return;
this.widget = new XemplaWidgetLoader({
clientKey: 'YOUR_CLIENT_KEY',
apiEndpoint: 'https://api.your-domain.com'
});
this.widget.init();
}
ngOnDestroy(): void {
this.widget?.destroy();
}
}Prerequisites
Credentials
The widget requires two values:
clientKeyapiEndpoint(example:https://api.your-domain.com)
These values must be provided by the Xempla Customer Support team for your account/environment. If you don’t have them yet, contact Xempla Customer Support and request your widget credentials.
Required hidden inputs (must be present)
Your host page must also include the following hidden inputs. The widget reads these values at runtime; if they are missing, the library will not work.
<input type="hidden" id="xempla-facility-name" value="Facility Name" />
<input type="hidden" id="xempla-asset-class-name" value="AHU" />
<input type="hidden" id="xempla-asset-name" value="AHU 1" />
<input type="hidden" id="xempla-asset-data" value='[{"date": "2025-10-21 10:00", "supply_air_temp": 20, "supply_air_fan_speed": 75},{"date": "2025-10-21 10:15", "supply_air_temp": 22, "supply_air_fan_speed": 73},{"date": "2025-10-21 13:00", "supply_air_temp": 21, "supply_air_fan_speed": 79}]' />
<input type="hidden" id="xempla-user-name" value="[email protected]" />Place these elements in the HTML that renders on the client before the widget initializes (for SSR apps, render them only in the browser).
Security & privacy
- Do not hardcode sensitive backend tokens in the page;
clientKeyis public, but keep internal API keys on the server. - Avoid logging hidden-input values to the console in production if they may include personal or sensitive information.
- Ensure
xempla-asset-dataJSON is properly escaped and kept to reasonable size for page load; prefer fetching large datasets from your backend/API. - Configure CSP/CORS to allow the
apiEndpointorigin while following your organization’s security policies.
Configuration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| clientKey | string | Yes | - | Your Xempla client key (used by the backend to validate the tenant and authorized domain) |
| apiEndpoint | string | Yes | - | Xempla-provided API base URL for your environment/tenant; the widget sends all API requests to this endpoint |
| containerId | string | No | xempla-embedded-container | DOM ID for the widget container |
| position | string | No | bottom-right | bottom-right, bottom-left, top-right, top-left |
| primaryColor | string | No | #4a86e8 | Primary theme color |
| headerText | string | No | Xempla Widget | Text displayed in the header |
| buttonText | string | No | 💬 | Text/Icon for the launcher button |
Common integration notes
- Prefer adding the CDN script with
deferso the page can render before the widget loads. - If you use programmatic init, call
xemplaWidgetInit(...)afterDOMContentLoaded(or once the script has loaded). - Keep
clientKeyandapiEndpointconsistent across environments (dev/stage/prod) based on what Xempla Customer Support provides. - If you use SSR (Next.js, Nuxt, etc.), initialize only in the browser (for example inside a
useEffect/ client-only hook).
Troubleshooting
- Widget does not appear: confirm the script loads (no 404), and that
clientKey+apiEndpointare set. - Network errors: verify the
apiEndpointis reachable from the browser and allowed by your site’s CSP/CORS settings. - SSR errors (
window is not defined): only initialize on the client (see React example).
