@meckin/chat-widget
v0.1.1
Published
A React chat widget for the MecKin chatbot platform. Ships as both an npm package for React apps and a standalone browser bundle for drop-in `<script>` embedding on any website.
Downloads
309
Readme
@meckin/chat-widget
A React chat widget for the MecKin chatbot platform. Ships as both an npm package for React apps and a standalone browser bundle for drop-in <script> embedding on any website.
Features
- Inline panel or floating-launcher modes
- Light/dark themes with optional theme-toggle button
- Sessions sidebar (resizable or compact drawer) with swipe gestures
- Streaming responses, retry, stop-generating, suggestion chips
- Live agent typing indicator and session reopen flow (SSE-driven)
- Server-synced unread badge on the launcher
- Markdown rendering (GFM) with sanitization and syntax-highlighted code blocks
- Virtualized message list (
@tanstack/react-virtual) postMessagebridge for host pages (external open/close, embed in iframe)- Local API probing for development (auto-falls back to cloud URL)
Installation
npm install @meckin/chat-widget react react-domPeer dependencies: React 19 and ReactDOM 19.
Usage (React)
import { Chat, configureChatApi } from "@meckin/chat-widget";
import "@meckin/chat-widget/styles.css";
import { useState } from "react";
configureChatApi({
apiUrl: "https://api.example.com",
localApiUrl: "http://localhost:8080", // optional; probed first
projectId: "your-project-id",
});
export function App() {
const [theme, setTheme] = useState<"light" | "dark">("light");
return (
<Chat
apiUrl="https://api.example.com"
projectId="your-project-id"
theme={theme}
onThemeToggle={() =>
setTheme((prev) => (prev === "dark" ? "light" : "dark"))
}
title="Ask us anything"
subtitle="Manual Agent"
fixedPosition="center"
width={"400px"}
height={"600px"}
showSidebar={true}
showLauncher={true}
showThemeToggle={false}
subtitle="We typically reply in a few minutes"
/>
);
}Inline mode
Omit showLauncher to render the chat panel inline. Use width, height, and fixedPosition to size and pin it.
<Chat
apiUrl="https://api.example.com"
theme="light"
onThemeToggle={() => {}}
width={420}
height={640}
fixedPosition="bottom-right"
/>Usage (script tag)
The build:embed output is a single self-contained bundle exposing window.ChatWidget.
<div id="chat-widget-root"></div>
<link rel="stylesheet" href="https://cdn.example.com/chat-widget/style.css" />
<script src="https://cdn.example.com/chat-widget/chat-widget.js"></script>
<script>
window.ChatWidget.init({
apiUrl: "https://api.example.com",
projectId: "your-project-id",
showLauncher: true,
theme: "light",
});
</script>If onThemeToggle is not provided, the widget toggles its theme internally.
<Chat> props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| apiUrl | string | — | Primary API base URL (required). |
| localApiUrl | string | — | Probed first via GET /health; falls back to apiUrl. |
| projectId | string | — | Sent on anonymous user creation. |
| theme | "light" \| "dark" | — | Required. |
| onThemeToggle | () => void | — | Required. |
| title / subtitle | string | — | Header copy. |
| width / height | string \| number | — | Inline-mode sizing. |
| fixedPosition | FixedPosition | — | top, bottom, left, right, center, or any corner. |
| showSidebar | boolean | true | Render the sessions sidebar. |
| compactMode | boolean | true | Sidebar as overlay drawer. |
| showLauncher | boolean | false | Floating bubble with open/close panel. |
| showThemeToggle | boolean | true | Header theme-toggle button. |
| externalToggle | boolean | false | Hide bubble; host page drives open state via postMessage. |
| defaultOpen | boolean | false | Open the launcher panel on mount. |
| buttonColor | string | var(--color-brand) | Launcher bubble background. |
| embedded | boolean | false | Full-bleed render — for iframe embedding. |
| allowedOrigin | string | "*" | targetOrigin for postMessage commands and notifications. |
| className | string | — | Extra class on the root. |
postMessage bridge
When mounted with showLauncher (typically inside an iframe), the widget listens for and emits:
- Host → widget:
"chat-widget:open","chat-widget:close","chat-widget:toggle","chat-widget:focus" - Widget → host:
"chat-widget:open","chat-widget:close"
Set allowedOrigin to restrict the targetOrigin of outgoing messages and validate inbound ones.
Exports
Top-level:
Chat,ChatProps,ChatTheme,FixedPositionconfigureChatApi,ChatApiConfig
Building blocks (advanced):
ChatPanel,MessageList,MessageInput,StreamingMessage,SidebaruseChathook +ChatMessage,ManualSessionStatus,ProjectModetypes- API types:
Attachment,MessageResponse,SessionResponse,SessionDetailResponse,WidgetConfig,VisitorSSEEvent
Styles ship as @meckin/chat-widget/styles.css and must be imported once.
Development
npm install
npm run dev # vite dev server
npm run build # library build (ESM + .d.ts)
npm run build:embed # standalone browser bundle (window.ChatWidget)
npm run lintTech stack
React 19, TypeScript, Vite, Tailwind v4, @tanstack/react-virtual, react-markdown + remark-gfm + rehype-sanitize, react-syntax-highlighter.
