JSPM

  • Created
  • Published
  • Downloads 5020
  • Score
    100M100P100Q128685F
  • License MIT

Help AI embeddable AI agent elements for the browser. Six chat layouts (floating / inline / modal / drawer / page / standalone) plus an iframe wrapper. Shadow-DOM-isolated, streaming SSE.

Package Exports

  • @helpai/elements
  • @helpai/elements/cjs
  • @helpai/elements/configurator
  • @helpai/elements/configurator.css
  • @helpai/elements/esm
  • @helpai/elements/schema
  • @helpai/elements/schema.json
  • @helpai/elements/style.css
  • @helpai/elements/web-component
  • @helpai/elements/web-component-esm

Readme

Help AI Elements

Embeddable AI agent elements for help.ai. A library of browser elements — Web Components and a programmatic API — that drop your AI agent into any website. Five layout variations of the chat element ship today (floating launcher, inline block, modal, full-page, standalone) plus an iframe wrapper for strict isolation. Shadow-DOM-isolated, streaming SSE, zero React in the bundle.

Full documentation: https://help.ai/docs/elements

This README is a quick-start. Configuration reference, theming, lifecycle hooks, framework recipes, and the backend contract live on the docs site.


Identity

Every element requires both publicKey AND aiAgentDeploymentId. Get them from your dashboard. The publicKey + secretKey flow is server-to-server only (API SDK) — never use a secret in browser code.


Install

CDN (one-line script tag)

<script
  src="https://cdn.help.ai/elements.js"
  data-public-key="agent_pk_..."
  data-ai-agent-deployment-id="..."
  defer
></script>

Boots the floating launcher in the bottom-right of the page. No further setup needed.

NPM

npm install @helpai/elements
import { mount } from "@helpai/elements";

const agent = mount({
  publicKey: "agent_pk_...",
  aiAgentDeploymentId: "...",
  mode: "inline",
  target: document.getElementById("chat"),
});

agent.on("message", (m) => console.log(m));

Web Component

<script type="module" src="https://cdn.help.ai/elements.js"></script>

<web-ai-chat
  public-key="agent_pk_..."
  ai-agent-deployment-id="..."
  mode="inline"
  style="display: block; height: 600px"
></web-ai-chat>

The custom element observes attribute changes — flip mode, theme, api-env, public-key, or ai-agent-deployment-id and the element re-resolves at runtime.

Build catalog — every release ships every format

File Format Use with
elements.js IIFE Plain <script> (defines window.HelpAI)
elements.esm.js ESM <script type="module"> import (CDN-friendly)
elements-web-component.esm.js ESM Same, registers <web-ai-chat> on import
index.mjs / web-component.mjs ESM Bundlers (Vite, webpack, esbuild) — bare imports kept
elements.cjs.js CJS require() from Node / legacy tooling
style.css CSS <link rel="stylesheet">
schema.json JSON Schema Dashboard config UIs, backend handshake validation, 3rd-party tooling
schema.mjs ESM Zod runtime schemas: import { widgetConfigSchema } from "@helpai/elements/schema"

Every bundle exposes the same surface (mount, init, hook, types). Pick whichever matches how your page loads scripts.

Standalone ESM bundle (browser-ready, no build needed)

elements.esm.js is a fully self-contained ESM bundle — every dependency (preact, signals, streaming-markdown) inlined. Drop into any page with <script type="module">. No bundler, no import map.

<script type="module">
  import { mount } from "https://cdn.jsdelivr.net/npm/@helpai/elements@latest/elements.esm.js";

  mount({
    publicKey: "agent_pk_...",
    aiAgentDeploymentId: "...",
    mode: "inline",
    target: document.querySelector("#chat"),
  });
</script>

Web-component variant (self-registers <web-ai-chat> on import):

<script type="module">
  import "https://cdn.jsdelivr.net/npm/@helpai/elements@latest/elements-web-component.esm.js";
</script>

<web-ai-chat
  public-key="agent_pk_..."
  ai-agent-deployment-id="..."
></web-ai-chat>

The brand CDN serves the same files:

  • https://cdn.help.ai/elements.js — IIFE (one-line <script>, no type="module")
  • https://help.ai/elements.esm.js — standalone ESM
  • https://help.ai/elements-web-component.esm.js — web-component ESM

Production tip. Pin a specific version (@1.4.0, not @latest) so a published patch can't surprise you. jsDelivr caches per-version aggressively; pinned URLs are immutable and CDN-friendly.

+esm vs elements.esm.js. jsDelivr's /+esm flag tries to auto-bundle on demand but trips on bare-specifier resolution for some packages. elements.esm.js is pre-bundled at release time — always works, always immutable.


Framework integrations

React / Next.js / Preact

// app/_components/Chat.tsx
import { useEffect, useRef } from "react";
import type { ChatWidgetInstance } from "@helpai/elements";

export function Chat() {
  const containerRef = useRef<HTMLDivElement>(null);
  const instanceRef = useRef<ChatWidgetInstance | null>(null);

  useEffect(() => {
    let alive = true;
    import("@helpai/elements").then(({ mount }) => {
      if (!alive || !containerRef.current) return;
      instanceRef.current = mount({
        publicKey: "agent_pk_...",
        aiAgentDeploymentId: "...",
        mode: "inline",
        target: containerRef.current,
      });
    });
    return () => {
      alive = false;
      instanceRef.current?.destroy();
    };
  }, []);

  return <div ref={containerRef} style={{ height: 600 }} />;
}

Or just register the web component once and use it as JSX (React 19+ treats unknown tags as web components automatically):

import "@helpai/elements/web-component";

export function Chat() {
  return <web-ai-chat public-key="agent_pk_..." ai-agent-deployment-id="..." mode="inline" />;
}

Vue 3

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";
import type { ChatWidgetInstance } from "@helpai/elements";

const containerRef = ref<HTMLDivElement | null>(null);
let instance: ChatWidgetInstance | null = null;

onMounted(async () => {
  const { mount } = await import("@helpai/elements");
  if (containerRef.value) {
    instance = mount({
      publicKey: "agent_pk_...",
      aiAgentDeploymentId: "...",
      mode: "inline",
      target: containerRef.value,
    });
  }
});
onUnmounted(() => instance?.destroy());
</script>

<template>
  <div ref="containerRef" style="height: 600px" />
</template>

Vue treats <web-ai-chat> as a custom element automatically — no config needed for unknown tags. To silence the dev warning, mark it explicitly in vite.config.ts:

export default defineConfig({
  plugins: [vue({ template: { compilerOptions: { isCustomElement: (t) => t.startsWith("web-ai-") } } })],
});

Angular

// app.config.ts — allow custom elements
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
@NgModule({ schemas: [CUSTOM_ELEMENTS_SCHEMA] })
export class AppModule {}
// chat.component.ts
import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from "@angular/core";

@Component({
  selector: "app-chat",
  template: `<div #host style="height: 600px"></div>`,
})
export class ChatComponent implements AfterViewInit, OnDestroy {
  @ViewChild("host", { static: true }) host!: ElementRef<HTMLDivElement>;
  private instance: { destroy(): void } | null = null;

  async ngAfterViewInit() {
    const { mount } = await import("@helpai/elements");
    this.instance = mount({
      publicKey: "agent_pk_...",
      aiAgentDeploymentId: "...",
      mode: "inline",
      target: this.host.nativeElement,
    });
  }
  ngOnDestroy() {
    this.instance?.destroy();
  }
}

Svelte / SvelteKit

<script lang="ts">
  import { onMount } from "svelte";
  import type { ChatWidgetInstance } from "@helpai/elements";

  let host: HTMLDivElement;
  let instance: ChatWidgetInstance | null = null;

  onMount(async () => {
    const { mount } = await import("@helpai/elements");
    instance = mount({
      publicKey: "agent_pk_...",
      aiAgentDeploymentId: "...",
      mode: "inline",
      target: host,
    });
    return () => instance?.destroy();
  });
</script>

<div bind:this={host} style="height: 600px" />

Vanilla / no-framework

<script type="module">
  import { mount } from "https://cdn.jsdelivr.net/npm/@helpai/elements@latest/elements.esm.js";
  mount({
    publicKey: "agent_pk_...",
    aiAgentDeploymentId: "...",
    mode: "inline",
    target: document.querySelector("#chat"),
  });
</script>
<div id="chat" style="height: 600px"></div>

Element variations

Variation UX
floating Floating launcher FAB + popover panel (default)
inline Full chat block in page flow, sized to its container
modal Centered modal window with dimmed backdrop. Page brings its own trigger button
page Full viewport with sidebar (logo + nav + conversation list)
standalone Full viewport, panel only (no sidebar)

Plus an orthogonal iframe: true flag that wraps any of the above in a same-origin iframe for strict JS + CSS isolation.

Pick at mount time via mode: '<value>' option or the mode="<value>" attribute. See https://help.ai/docs/elements/modes.


Configuration

The element reads its per-deployment configuration from your Help AI workspace at handshake time — colors, launcher chrome, strings, action layout, model defaults, history visibility all flow through StartConversationResponse.settings. You don't recompile per-customer.

A handful of options live in the install snippet itself:

mount({
  publicKey: "agent_pk_...",
  aiAgentDeploymentId: "...",
  presentation: { mode: "floating" },
  baseUrl: "https://help.ai",    // omit to use the brand default
  user: { id: "u_123", email: "alice@help.ai" },
  theme: "dark",                   // "auto" | "light" | "dark" | overrides object
  i18n: { defaultLocale: "en" },
  debug: "info",                   // optional — opens the structured log firehose
});

Full option reference: https://help.ai/docs/elements/configuration.


Lifecycle hooks

import { hook } from "@helpai/elements";

hook("*", "open", (inst) => analytics.track("agent_opened", { id: inst.widgetId }));
hook("*", "message", (inst, _event, msg) => console.log(msg.role, msg.text));

The global object exposes the same API for non-bundled usage:

HelpAI.hook("*", "*", (inst, event, data) => {
  /* … */
});

Full event map: https://help.ai/docs/elements/events.


Theming

Pass theme overrides at mount:

mount({
  publicKey: "agent_pk_...",
  aiAgentDeploymentId: "...",
  theme: {
    accent: "#10B981",
    accentText: "#ffffff",
    radius: "10px",
    fontFamily: "Inter, system-ui, sans-serif",
  },
});

Or import the standalone stylesheet and style the host element yourself:

@import "@helpai/elements/style.css";

Full theming reference: https://help.ai/docs/elements/theming.


More framework recipes

WordPress, Webflow, Shopify, vanilla CMS, code playgrounds, MDX — https://help.ai/docs/elements/frameworks.


Browser support

Modern evergreens: Chrome / Edge ≥ 109, Firefox ≥ 110, Safari ≥ 16. iOS ≥ 16. No IE / Legacy Edge.


License

MIT