@classic-homes/chat-widget
v0.0.0-dev-20260125214240
Published
High-performance embeddable chat widget built with Svelte
Readme
@classic-homes/chat-widget
High-performance embeddable chat widget built with Svelte. Can be integrated via multiple methods: Vanilla JS, React, Docusaurus plugin, or Custom Element.
Installation
npm install @classic-homes/chat-widgetFor React projects, ensure you have React 17+ installed:
npm install react react-domUsage
Vanilla JavaScript
The simplest way to add the widget to any website:
import { init, destroy } from '@classic-homes/chat-widget/vanilla';
// Initialize the widget
init({
apiBase: 'https://api.example.com',
site: 'docs',
siteName: 'Documentation',
title: 'Help Assistant',
welcomeMessage: 'How can I help you today?',
welcomeTopics: ['Getting started', 'API reference', 'Troubleshooting'],
});
// Later, to destroy the widget
destroy();React Component
Use the React adapter for seamless integration with React applications:
import { ChatWidget } from '@classic-homes/chat-widget/react';
function App() {
return (
<ChatWidget
apiBase="https://api.example.com"
site="docs"
siteName="Documentation"
title="Help Assistant"
welcomeMessage="How can I help you today?"
welcomeTopics={['Getting started', 'API reference', 'Troubleshooting']}
/>
);
}The React adapter also provides ChatWidgetElement for using the custom element directly:
import { ChatWidgetElement } from '@classic-homes/chat-widget/react';
function App() {
return (
<ChatWidgetElement
apiBase="https://api.example.com"
site="docs"
siteName="Documentation"
/>
);
}Docusaurus Plugin
For Docusaurus 3.x sites:
// docusaurus.config.js
module.exports = {
plugins: [
[
'@classic-homes/chat-widget/docusaurus',
{
apiBase: 'https://api.example.com',
site: 'docs',
siteName: 'Documentation',
title: 'Help Assistant',
},
],
],
};Custom Element (Web Component)
Use the <chat-widget> custom element directly in HTML:
<script type="module">
import '@classic-homes/chat-widget';
</script>
<chat-widget
api-base="https://api.example.com"
site="docs"
site-name="Documentation"
title="Help Assistant"
welcome-message="How can I help you today?"
welcome-topics='["Getting started", "API reference"]'
></chat-widget>Note: Attribute names use kebab-case (e.g., api-base instead of apiBase).
Configuration Options
| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| apiBase | string | Yes | - | Base URL for the chat API |
| site | string | Yes | - | Site identifier (e.g., "docs", "marketing") |
| siteName | string | Yes | - | Display name for current site |
| title | string | No | "Chat Assistant" | Widget header title |
| logoUrl | string | No | - | Logo URL for header |
| primaryColor | string | No | - | Primary brand color (CSS color value) |
| position | "bottom-right" | "bottom-left" | No | "bottom-right" | Widget position |
| fullscreen | boolean | No | false | Enable fullscreen mode |
| welcomeMessage | string | No | - | Welcome message text |
| welcomeTopics | string[] | No | - | Suggested topics shown in welcome |
| disclaimerHtml | string | No | - | Disclaimer HTML shown below welcome |
| storagePrefix | string | No | "chat_" | Prefix for localStorage keys |
| sentryDsn | string | No | - | Sentry DSN for error tracking |
| environment | "development" | "production" | No | "production" | Environment name |
| sites | Record<string, SiteConfig> | No | - | Cross-site configuration |
| onNavigate | (url: string) => void | No | - | Custom navigation handler |
| onOpen | () => void | No | - | Called when widget opens |
| onClose | () => void | No | - | Called when widget closes |
Widget API
The initChatWidget function returns a ChatWidgetAPI object with the following methods:
Conversation Management
const widget = initChatWidget(element, config);
// List all conversations
const conversations = await widget.listConversations();
// Get a specific conversation with messages
const conversation = await widget.getConversation(id);
// Switch to a conversation
await widget.selectConversation(id);
// Start a new conversation
await widget.startNewConversation();
// Delete a conversation
await widget.deleteConversation(id);
// Rename a conversation
await widget.renameConversation(id, 'New Title');State Getters
// Get current conversation ID (null if new chat)
const currentId = await widget.getCurrentConversationId();
// Get current conversation title
const title = await widget.getCurrentTitle();Lifecycle Methods
// Clear messages and reset chat
widget.clearMessages();
// Refresh widget (reload from storage)
widget.refresh();
// Destroy the widget
widget.destroy();Events
Subscribe to widget events using the on method:
const widget = initChatWidget(element, config);
// Subscribe to events
const unsubscribe = widget.on('message:received', ({ message }) => {
console.log('New message:', message.content);
});
// One-time subscription
widget.once('ready', () => {
console.log('Widget is ready');
});
// Unsubscribe
unsubscribe();Available Events
| Event | Payload | Description |
|-------|---------|-------------|
| ready | undefined | Widget has finished initializing |
| conversation:created | { id: string, title: string \| null } | New conversation created |
| conversation:selected | { id: string \| null, title: string \| null } | Conversation selected/switched |
| conversation:deleted | { id: string } | Conversation deleted |
| conversation:titleChanged | { id: string, title: string } | Conversation renamed |
| conversations:updated | { conversations: ConversationPreview[] } | Conversation list changed |
| message:sent | { message: Message } | User sent a message |
| message:received | { message: Message } | Assistant response received |
| error | { message: string, error?: Error } | Error occurred |
TypeScript Support
Full TypeScript definitions are included. Import types as needed:
import type {
ChatWidgetConfig,
ChatWidgetAPI,
PageContext,
Message,
ConversationPreview,
} from '@classic-homes/chat-widget';Styling
The widget includes all necessary styles. For custom styling, you can target the widget's CSS custom properties:
chat-widget {
--chat-primary-color: #0066cc;
--chat-border-radius: 12px;
}Browser Support
- Chrome/Edge 88+
- Firefox 78+
- Safari 14+
The widget requires support for:
- Custom Elements v1
- ES Modules
- CSS Custom Properties
License
MIT
