@dgrtechlabs/chat-widget
v0.6.0
Published
Embeddable, framework-agnostic AI chat widget — a Shadow-DOM web component with a one-line <script> embed and streaming (SSE) replies.
Maintainers
Readme
@dgrtechlabs/chat-widget
Embeddable, framework-agnostic AI chat widget. It's a single <ai-chat-widget>
custom element that renders
a floating launcher + chat panel inside a Shadow DOM — so the host page's CSS/JS and
the widget's are fully isolated from each other — and streams replies token-by-token over
SSE from your chat server.
- Zero runtime dependencies, ~4 kB gzipped.
- Two ways to embed: a one-line
<script>tag (any site) or an ESMimport(frameworks). - No secrets in the page — the widget only carries a tenant public key; provider API keys live on the server.
The widget talks to a companion chat server (POST /v1/chat, SSE). You point it at your
server with server-url and identify the tenant with public-key.
Option A — drop-in <script> from a CDN (any site)
Paste one tag. embed.js reads its own data-* attributes and injects the widget into
<body> — nothing else to wire up. Served straight from npm via
jsDelivr:
<script
src="https://cdn.jsdelivr.net/npm/@dgrtechlabs/[email protected]/dist/embed.js"
data-public-key="pk_live_acme_2f9c"
data-server-url="https://chat.example.com"
data-title="Acme Assistant"
data-accent="#6c5ce7"></script>- Pin a version (
@0.1.0) in production for a stable, immutable, cached URL.@0.1tracks patch releases; omitting the version tracks@latest. - unpkg works too:
https://unpkg.com/@dgrtechlabs/[email protected]/dist/embed.js.
Option B — ESM import (Astro, Next, Vue, Svelte, plain bundlers)
Install, import the module once (that registers the <ai-chat-widget> element), then place
the element in your markup:
npm install @dgrtechlabs/chat-widgetimport '@dgrtechlabs/chat-widget'; // registers <ai-chat-widget><ai-chat-widget
public-key="pk_live_acme_2f9c"
server-url="https://chat.example.com"
title="Acme Assistant"
accent="#0ea5e9"></ai-chat-widget>The import is side-effecting (it defines the element), so keep it even if you don't reference any named exports.
Configuration
Both paths share the same options — data-* attributes on the <script> for the CDN path,
plain attributes on <ai-chat-widget> for the ESM path.
| <script> (CDN) | <ai-chat-widget> (ESM) | Required | Description |
| ------------------ | ------------------------ | :------: | ------------------------------------------------------------------ |
| data-public-key | public-key | yes | Tenant public key; safe to expose in the browser. |
| data-server-url | server-url | yes | Base URL of your chat server. The widget POSTs to …/v1/chat. |
| data-title | title | no | Header text. Defaults to Chat. |
| data-accent | accent | no | Accent color (any CSS color). Defaults to #2563eb. |
The page's origin (
scheme://host:port) must be in the tenant'sallowedOriginson the server, or requests are rejected with 403. See the server onboarding guide.
Exports
import { AIChatWidget, TAG, CONTRACT_VERSION } from '@dgrtechlabs/chat-widget';
// ^ the HTMLElement subclass ^ 'ai-chat-widget' ^ wire-contract versionTypeScript declarations (.d.ts) ship in the package; the type surface is self-contained
(no extra @types/* needed).
How it works
The widget sends the full message history on each turn ({ publicKey, messages,
conversationId }) and reads the server's text/event-stream response, appending each
delta to the live assistant bubble and finalizing on done. There is no client-side
persistence — history lives in the open panel for the session.
Links
- Embedding guide (end-to-end):
docs/embedding.md - Tenant / server onboarding:
docs/onboarding.md - Source: github.com/ndogar87/aichatbot
License
MIT
