JSPM

@ampup/chat-widget

0.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 49
  • Score
    100M100P100Q60827F
  • License MIT

Drop-in AI voice chat widget powered by ElevenLabs with a custom overlay UI

Package Exports

  • @ampup/chat-widget
  • @ampup/chat-widget/styles.css

Readme

@ampup/chat-widget

Drop-in AI voice chat widget powered by ElevenLabs. Ships with a custom chat overlay UI — the underlying ElevenLabs widget runs hidden in the background while your users interact with your branded interface.

Installation

npm install @ampup/chat-widget
# or
pnpm add @ampup/chat-widget
# or
yarn add @ampup/chat-widget

Peer dependencies — make sure your project has React 18+:

npm install react react-dom

Quick Start

import { ChatWidget } from "@ampup/chat-widget";
import "@ampup/chat-widget/styles.css";

function App() {
  return (
    <ChatWidget agentId="your_elevenlabs_agent_id" />
  );
}

That's it. A floating chat button appears in the bottom-right corner of the page.

Props

Prop Type Default Description
agentId string (required) Your ElevenLabs Conversational AI agent ID
position "bottom-right" | "bottom-left" "bottom-right" Widget position on the page
defaultOpen boolean false Start with the chat panel open
className string undefined Additional CSS class on the root element
onMessage (msg: ChatMessage) => void undefined Callback fired on every message (user or assistant)
onConnectionChange (connected: boolean) => void undefined Callback when WebSocket connection state changes
contextProvider () => string undefined Function returning context to send to the agent (e.g. current page info)
labels object see below Override default UI text

Labels

{
  placeholder: "Type your message...",
  sendButton: "Send",
  title: "Chat",
  emptyState: "Start a conversation by typing a message or using your microphone.",
}

Examples

With page context

import { ChatWidget } from "@ampup/chat-widget";
import "@ampup/chat-widget/styles.css";

function App() {
  return (
    <ChatWidget
      agentId="agent_xxxxx"
      contextProvider={() =>
        `User is viewing: ${window.location.pathname}`
      }
    />
  );
}

With message logging

<ChatWidget
  agentId="agent_xxxxx"
  onMessage={(msg) => {
    console.log(`[${msg.role}] ${msg.content}`);
  }}
/>

Custom labels and position

<ChatWidget
  agentId="agent_xxxxx"
  position="bottom-left"
  defaultOpen
  labels={{
    title: "Support",
    placeholder: "Ask us anything...",
    sendButton: "Send",
    emptyState: "Hi! How can we help?",
  }}
/>

Sending context updates programmatically

import { ChatWidget, sendContextUpdate } from "@ampup/chat-widget";
import "@ampup/chat-widget/styles.css";

function App() {
  const handlePageChange = (page: string) => {
    sendContextUpdate(`User navigated to ${page}`);
  };

  return <ChatWidget agentId="agent_xxxxx" />;
}

Styling

Import the default stylesheet:

import "@ampup/chat-widget/styles.css";

All CSS classes are prefixed with ampup-widget- to avoid collisions. You can override any class in your own CSS:

/* Example: change the FAB color */
.ampup-widget-fab {
  background: #4f46e5;
}

/* Example: change user message bubbles */
.ampup-widget-msg[data-role="user"] {
  background: #4f46e5;
}

Or skip the default styles entirely and write your own from scratch — the component uses the same class names either way.

How It Works

  1. The <ChatWidget> renders a hidden <elevenlabs-convai> custom element. It loads the ElevenLabs script from CDN, connects via WebSocket, and handles all voice AI logic.
  2. A WebSocket proxy intercepts the ElevenLabs connection to read transcripts and inject context updates in real time.
  3. The chat overlay is a plain React UI (FAB button, message list, text input, mic button) driven by events from the proxy.

Types

interface ChatMessage {
  role: "user" | "assistant";
  content: string;
  timestamp: number;
}

interface ChatWidgetProps {
  agentId: string;
  position?: "bottom-right" | "bottom-left";
  onMessage?: (message: ChatMessage) => void;
  onConnectionChange?: (connected: boolean) => void;
  contextProvider?: () => string;
  className?: string;
  labels?: {
    placeholder?: string;
    sendButton?: string;
    title?: string;
    emptyState?: string;
  };
  defaultOpen?: boolean;
}

Development

git clone https://github.com/ampup-ai/ampup-widget.git
cd ampup-widget
npm install
npm run dev     # watch mode
npm run build   # production build → dist/

License

MIT