Embeddable healthcare chatbot widget for websites and mobile apps
npm install @mypatientspace/chatbot-widgetA standalone chatbot widget that third-party websites can embed via a single tag.

- Self-contained React application bundled into a single JS file
- Easy integration with any website
- Floating button mode (default) or embedded mode
- Customizable theming
- Style isolation (won't conflict with host site CSS)
- Native mobile support via WebView
- React 19 with TypeScript
- Vite (library mode build)
- Emotion (CSS-in-JS for style isolation)
- lucide-react (icons)
When using the UMD bundle via tag, the widget bundles its own React and renders in an isolated container. Your project's React version doesn't matter — this works with any framework (or no framework at all), including:
- Vanilla JavaScript/HTML
- jQuery
- Angular, Vue, Svelte
- Older React versions (14, 15, 16, etc.)
When importing as an ES module in a React project:
``javascript`
import '@mypatientspace/chatbot-widget';
You need React 18 or higher. The widget uses modern React features (hooks, Context API) that aren't available in older versions.
| Integration Method | React Version Required |
|--------------------|------------------------|
| CDN / Script tag | Any (bundles own React) |
| npm import | React 18+ |
unpkg:
`html`
jsDelivr:
`html`
bash
npm install @mypatientspace/chatbot-widget
`Development
`bash
Install dependencies
yarn installStart dev server (includes demo UI)
yarn devBuild for production
yarn build # Builds both widget and demo
yarn build:widget # Widget only
yarn build:demo # Demo onlyPreview production build
yarn preview
`Demo Widget
An embeddable demo page with configuration panel and live preview. Useful for testing and showcasing the widget.
$3
`html
`> Note: The "Use Mock API" toggle is only available in development mode (
yarn dev). When embedding the demo in production, you must provide apiEndpoint and token in the initialConfig.$3
`javascript
ChatbotWidgetDemo.init(config); // Initialize demo
ChatbotWidgetDemo.destroy(); // Remove demo
ChatbotWidgetDemo.update(config); // Update configuration
`$3
| Option | Type | Default | Description |
|--------|------|---------|-------------|
|
containerSelector | string | Required | CSS selector for container |
| showConfigPanel | boolean | true | Show left config panel |
| showPreviewPanel | boolean | true | Show right preview panel |
| showJsonEditor | boolean | true | Show Form/JSON toggle |
| showDisplaySettings | boolean | true | Show display settings section |
| showSessionSettings | boolean | true | Show session settings section |
| showAppearanceSettings | boolean | true | Show appearance section |
| showThemeSettings | boolean | true | Show theme colors section |
| showContentSettings | boolean | true | Show content settings section |
| showQuickActions | boolean | true | Show quick actions section |
| initialConfig | Partial | {} | Pre-fill widget config (including apiEndpoint and token) |
| onConfigChange | (config) => void | - | Called when config changes |Web Integration
$3
`html
`$3
`html
`$3
`javascript
import '@mypatientspace/chatbot-widget';ChatbotWidget.init({
apiEndpoint: 'https://your-api.com/chat'
});
`$3
`javascript
ChatbotWidget.open(); // Open chat window
ChatbotWidget.close(); // Close chat window
ChatbotWidget.toggle(); // Toggle open/close
ChatbotWidget.destroy(); // Remove widget completely
`Embedded Mode
By default, the widget displays as a floating button that opens a popup. You can also embed the chat directly inside any container on your page.
$3
Embed the chat inside an existing element:
`html
`$3
Enable floating mode with FAB button (classic chatbot style):
`html
`$3
| Feature | Embedded (default) |
floatingMode: true |
|---------|-------------------|----------------------|
| FAB button | Hidden | Shown |
| Chat visibility | Always open | Opens on click |
| Position | Fills container | Fixed bottom-right/left |
| Sizing | 100% of parent | 380x520px |Mobile Integration
$3
`kotlin
class ChatActivity : AppCompatActivity() {
private lateinit var webView: WebView override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webView = WebView(this).apply {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
loadDataWithBaseURL(
"https://your-domain.com",
"""
""".trimIndent(),
"text/html", "UTF-8", null
)
}
setContentView(webView)
}
}
`$3
`swift
import UIKit
import WebKitclass ChatViewController: UIViewController {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let config = WKWebViewConfiguration()
config.preferences.javaScriptEnabled = true
webView = WKWebView(frame: view.bounds, configuration: config)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(webView)
let html = """
""" webView.loadHTMLString(html, baseURL: URL(string: "https://your-domain.com"))
}
}
`$3
`jsx
import { WebView } from 'react-native-webview';const ChatScreen = () => {
const html =
; return (
source={{ html }}
javaScriptEnabled={true}
domStorageEnabled={true}
/>
);
};
`Configuration Reference
$3
| Option | Type | Required | Description |
|--------|------|----------|-------------|
|
apiEndpoint | string | No | Chat API endpoint URL (widget offline if not set) |
| token | string | No | Auth token for API requests |
| sessionId | string | No | Existing session ID to resume |
| assistantId | string | No | Specific assistant ID to use |
| contextPatientId | string | No | Patient context for the chat |
| loadHistory | boolean | No | Load previous chat history (default: true) |
| colorMode | 'light' \| 'dark' \| 'system' | No | Color mode for the widget (default: 'light') |
| theme | ThemeConfig | No | Custom theme (see Theme Configuration below) |
| position | 'bottom-right' \| 'bottom-left' | No | FAB button position |
| containerSelector | string | No | CSS selector for embedded container |
| floatingMode | boolean | No | Show FAB button and floating chat (default: false) |
| greeting | string | No | Initial bot greeting message |
| placeholder | string | No | Input field placeholder text |
| headerTitle | string | No | Chat window header title |
| headerSubtitle | string | No | Chat window header subtitle |
| headerIcon | string | No | Header icon image URL |
| fabIcon | string | No | FAB button image URL |
| brandingText | string | No | Footer branding text |
| quickActions | string[] | No | Predefined quick action buttons (displayed as labels and sent as messages) |$3
| Callback | Parameters | Description |
|----------|------------|-------------|
|
onOpen | () | Called when chat window opens |
| onClose | () | Called when chat window closes |
| onMessageSent | (message: Message) | Called after user sends a message |
| onMessageReceived | (message: Message) | Called after bot response completes |
| onQuickAction | (action: string) | Called when quick action is clicked |
| onStreamChunk | (chunk: string) | Called for each streamed response chunk |$3
`typescript
interface Message {
id: string;
content: string;
sender: 'user' | 'bot';
timestamp: Date;
status: 'sending' | 'sent' | 'error';
audioUrl?: string; // Base64 audio data URL for TTS playback
}
`$3
`typescript
interface ThemeConfig {
colors?: Partial; // Any subset of theme colors
fontFamily?: string;
borderRadius?: string;
shadow?: string;
}
`$3
| Color | Default | Description |
|-------|---------|-------------|
|
primary | #00c2d1 | FAB button, links, main accent |
| primaryDark | #017992 | Hover states |
| secondary | #3c4d73 | Header background |
| accent | #33b1e6 | Secondary accent color |
| accentLight | #b8ebff | Light accent |
| success | #00dec4 | Success states |
| info | #30d7ed | Info states |
| background | #ffffff | Chat window background |
| surface | #fdfefe | Input/card backgrounds |
| text | #3c4d73 | Primary text |
| textLight | #6b7280 | Secondary text, timestamps |
| userBubble | #00c2d1 | User message background |
| userBubbleText | #ffffff | User message text |
| botBubble | #e0f7fa | Bot message background |
| botBubbleText | #3c4d73 | Bot message text |
| border | #d1d5db | Border color |
| borderLight | #e5e7eb | Light border |
| error | #ef4444 | Error states |
| white | #ffffff | White color |
| recording | #ef4444 | Voice recording indicator |Default Values
| Option | Default Value |
|--------|---------------|
|
headerTitle | "AI Doctor" |
| greeting | "Hello! Welcome to our healthcare support. How can I assist you today?" |
| placeholder | "Type a message..." |
| brandingText | "Developed by myPatientSpace" |
| headerIcon | https://web.mypatientspace.com/img/logo-symbol.png |
| fabIcon | https://web.mypatientspace.com/img/logo-symbol.png |
| position | "bottom-right" |
| colorMode | "light" |
| loadHistory | true |
| containerSelector | undefined (creates container in body) |
| floatingMode | false (embedded is default) |
| quickActions` | Book Appointment, Hours, Contact, Location |MIT