npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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)

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-embedded

CDN

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:

  • clientKey
  • apiEndpoint (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; clientKey is 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-data JSON 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 apiEndpoint origin 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 defer so the page can render before the widget loads.
  • If you use programmatic init, call xemplaWidgetInit(...) after DOMContentLoaded (or once the script has loaded).
  • Keep clientKey and apiEndpoint consistent 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 + apiEndpoint are set.
  • Network errors: verify the apiEndpoint is 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).