@developer.notchatbot/webchat
Version:
A beautiful React chatbot widget with single-file bundle
574 lines (478 loc) β’ 20.9 kB
Markdown
```html
<div id="webchat-component"></div>
<script src="https://your-cdn.com/webchat-bundle.min.umd.cjs"></script>
<script>
WebChat.initialize({
title: "Customer Support",
placeholder: "Ask us anything...",
primaryColor: "#667eea"
});
</script>
```
The chatbot button will appear in the bottom-right corner of your page. CSS is automatically injected!
```typescript
interface WebChatConfig {
title?: string; // Chat window title
placeholder?: string; // Input placeholder text
primaryColor?: string; // Primary theme color
apiKey?: string; // Your chatbot UID (required for API)
position?: 'bottom-right' | 'bottom-left'; // Widget position
initialMessage?: string; // Custom initial bot message
closeButtonIcon?: 'default' | 'text' | 'custom'; // Close button type
closeButtonText?: string; // Text for close button (when type is 'text')
closeButtonCustomIcon?: string; // Custom icon SVG or URL (when type is 'custom')
marginBottom?: number; // Distance from bottom edge in pixels (default: 16)
marginSide?: number; // Distance from left/right edge in pixels (default: 16)
mobile?: WebChatPositionConfig; // Mobile-specific position settings
desktop?: WebChatPositionConfig; // Desktop-specific position settings
whatsapp?: { // Integrated WhatsApp Options
phoneNumber: string; // WhatsApp phone number
message?: string; // Optional default message text
active?: boolean; // Enable or disable the button (default: true)
color?: string; // Customize the internal WhatsApp button color
};
}
interface WebChatPositionConfig {
position?: 'bottom-right' | 'bottom-left';
marginBottom?: number;
marginSide?: number;
}
```
Example:
```js
WebChat.initialize({
title: "Chat Assistant",
placeholder: "Type your message...",
primaryColor: "#007bff",
apiKey: "your-chatbot-uid", // Chatbot UID from admin panel
position: "bottom-right",
initialMessage: "Hi! π I'm your virtual assistant. How can I help you today?",
closeButtonIcon: "default", // or "text" or "custom"
marginBottom: 20, // Distance from bottom edge (default: 16px)
marginSide: 20, // Distance from side edge (default: 16px)
// Device-specific overrides
mobile: {
position: "bottom-left",
marginBottom: 80,
marginSide: 15
},
desktop: {
position: "bottom-right",
marginBottom: 30,
marginSide: 30
},
whatsapp: { // Adds a dual-button menu for WhatsApp & WebChat
phoneNumber: "YOUR_PHONE_NUMBER",
message: "Hello! I need help...",
active: true,
color: "#25D366"
}
});
```
If you simply want a floating WhatsApp action button with no WebChat, you can use `WhatsAppButtonAPI`, which isolates itself in the Shadow DOM to avoid CSS conflicts.
```html
<!-- Load the script -->
<script src="path/to/webchat.js"></script>
<script>
WhatsAppButtonAPI.initialize({
phoneNumber: "1234567890",
message: "Hola, me gustarΓa tener mΓ‘s informaciΓ³n.",
color: "#25D366",
position: "bottom-right",
marginBottom: 20,
marginSide: 20,
active: true,
size: 48, // Button dimension in px
// Customize device-specific positioning
desktop: {
position: "bottom-right",
marginBottom: 30,
marginSide: 30
},
mobile: {
position: "bottom-right",
marginBottom: 80,
marginSide: 15
}
});
</script>
```
EmbedChat allows you to integrate a complete chat system directly into any element of your web page, with full control over size, position, and style.
```html
<!-- Element to embed the chat -->
<div id="my-chat-embed"></div>
<!-- Load the script -->
<script src="path/to/webchat.js"></script>
<script>
EmbedChat.initialize({
elementId: "my-chat-embed",
apiKey: "your-api-key",
title: "Chat Assistant",
width: 400,
height: 500
});
</script>
```
```javascript
import { EmbedChatAPI } from './webchat';
const chatInstance = EmbedChatAPI.initialize({
elementId: "my-chat-embed",
apiKey: "your-api-key",
title: "Chat Assistant",
width: 400,
height: 500
});
```
```javascript
EmbedChatAPI.initialize({
// REQUIRED
elementId: "my-chat-embed", // ID of the HTML element to embed the chat
apiKey: "your-api-key", // API key of the service
})
```
```javascript
EmbedChatAPI.initialize({
// Texts and content
title: "Chat Assistant", // Title shown in the header
placeholder: "Type your message...", // Input placeholder text
initialMessage: "Hello! π I'm your chat assistant. How can I help you today?", // First message from the bot
footerText: "Powered by NotChatBot", // Footer text (optional)
avatar: "https://example.com/avatar.jpg", // Bot avatar URL
})
```
```javascript
EmbedChatAPI.initialize({
// Main dimensions
width: 400, // Width: number (px) or string ("100%", "50vw")
height: 500, // Height: number (px) or string ("100%", "80vh")
// Size limits
maxWidth: 600, // Maximum width
maxHeight: "90vh", // Maximum height (accepts CSS units)
minWidth: 280, // Minimum width (default: 280px)
minHeight: 300, // Minimum height (default: 300px)
})
```
```javascript
EmbedChatAPI.initialize({
// Colors
primaryColor: "#3b82f6", // Primary color (header, buttons, etc.)
textColor: "#333333", // Message text color
bubbleUserColor: "#3b82f6", // User message bubble background
chatBackground: "#ffffff", // Chat background color
footerColor: "#f3f4f6", // Footer background color
// Borders
borderRadius: 12, // Border radius: number (px) or string
border: "2px solid #3b82f6", // Custom border (CSS border)
boxShadow: "0 10px 30px rgba(0,0,0,0.2)", // Custom shadow
chatTransparent: false, // If true, chat background is transparent
})
```
```javascript
EmbedChatAPI.initialize({
showHeader: true, // Show/hide header (default: true)
showFooter: true, // Show/hide footer (default: true if footerText is provided)
})
```
```javascript
EmbedChatAPI.initialize({
input: {
backgroundColor: "#ffffff", // Input area background color
inputBorder: "2px solid #e5e7eb", // Input field border
inputBorderRadius: "8px", // Input border radius
iconColor: "#3b82f6" // Send icon color
}
})
```
```javascript
EmbedChatAPI.initialize({
customCSS: `
/* Your custom styles here */
background: linear-gradient(135deg,
}
`
})
```
```javascript
EmbedChatAPI.initialize({
elementId: "mi-chat",
// Main sizes
width: 400, // Number (px) or string ("100%", "50vw")
height: 500, // Number (px) or string ("100%", "80vh")
// Size limits
maxWidth: 600, // Maximum size
maxHeight: "90vh", // Can use CSS units
minWidth: 280, // Minimum size
minHeight: 300,
// More
width: "100%", // Occupies the entire width of the container
height: "50vh", // 50% of the window height
maxWidth: "500px", // Maximum 500px
})
```
```javascript
EmbedChatAPI.initialize({
elementId: "mi-chat",
// Borders and effects
borderRadius: 12, // Border radius in px
border: "2px solid #3b82f6", // Custom border
boxShadow: "0 10px 30px rgba(0,0,0,0.2)", // Custom shadow
// Section control
showHeader: true, // Show/hide header (default: true)
showFooter: true, // Show/hide footer (default: true if footerText is provided)
// π Custom CSS
customCSS: `
background: linear-gradient(135deg,
border-radius: 20px !important;
}
`
})
```
| Property | Type | Required | Default | Description |
|-----------|------|-----------|---------|-------------|
| `elementId` | `string` | β
| - | ID of the HTML element where the chat will be mounted |
| `apiKey` | `string` | β
| - | API key for the chat service |
| `title` | `string` | β | `"Chat"` | Title shown in the chat header |
| `placeholder` | `string` | β | `"Type your message..."` | Input field placeholder text |
| `primaryColor` | `string` | β | `"#3b82f6"` | Primary color (header, buttons, links) |
| `avatar` | `string` | β | - | Bot avatar URL (optional) |
| `initialMessage` | `string` | β | - | First message shown by the bot |
| `footerText` | `string` | β | - | Footer text (if provided, it is shown) |
| `width` | `string \| number` | β | `"100%"` | Chat width (px or CSS units) |
| `height` | `string \| number` | β | `400` | Chat height (px or CSS units) |
| `maxWidth` | `string \| number` | β | `"100%"` | Maximum chat width |
| `maxHeight` | `string \| number` | β | `"100vh"` | Maximum chat height |
| `minWidth` | `string \| number` | β | `280` | Minimum chat width |
| `minHeight` | `string \| number` | β | `300` | Minimum chat height |
| `showHeader` | `boolean` | β | `true` | Show/hide the header |
| `showFooter` | `boolean` | β | `true` | Show/hide the footer (if footerText is provided) |
| `borderRadius` | `string \| number` | β | `12` | Container border radius |
| `border` | `string` | β | `"1px solid #e5e7eb"` | Container border (CSS border) |
| `boxShadow` | `string` | β | `"0 10px 25px..."` | Container shadow |
| `chatTransparent` | `boolean` | β | `false` | If true, chat background is transparent |
| `chatBackground` | `string` | β | `"#ffffff"` | Chat background color |
| `textColor` | `string` | β | - | Message text color |
| `bubbleUserColor` | `string` | β | - | User message bubble background color |
| `footerColor` | `string` | β | - | Footer background color |
| `input` | `EmbedChatInputConfig` | β | - | Input-specific configuration |
| `customCSS` | `string` | β | - | Custom CSS for the chat |
---
## π οΈ Dynamic Control via API and Events
WebChat exposes a global API and custom events to dynamically control the position, padding, and visibility of the widget from anywhere in your app or from the browser console.
### WebChat Global Methods
```js
window.openWebChat(); // Open the floating chat
window.closeWebChat(); // Close the floating chat
window.toggleWebChat(); // Toggle open/close
window.unmountWebChat(); // Unmount the floating chat
window.mountWebChat(); // Mount the floating chat if it was unmounted
window.hideWebChat(); // Hide the chat (display: none)
window.showWebChat(); // Show the chat if it was hidden
window.injectWebChatCSS(css); // Inject custom CSS into the shadow DOM
window.removeWebChatCSS(); // Remove custom CSS
window.setWebChatPosition(obj); // Change position/padding dynamically
```
```js
window.unmountEmbedChat(elementId); // Unmount the EmbedChat instance for the given elementId
window.mountEmbedChat(elementId); // Mount the EmbedChat instance again (with the last used config)
```
- `window.unmountEmbedChat(elementId)`: Unmounts the EmbedChat instance from the specified element. The last configuration is saved.
- `window.mountEmbedChat(elementId)`: Remounts the EmbedChat instance in the specified element using the last configuration used for that element. If no config was previously used, a warning is shown in the console.
```js
window.unmountEmbedChat('embed-small'); // Unmounts the chat from the element with id 'embed-small'
window.mountEmbedChat('embed-small'); // Remounts the chat in the same element with the last config
```
You can programatically show, hide, or destroy the standalone WhatsApp button from the Global window object.
```js
window.WhatsAppButton.initialize(config); // Initializes the standalone widget
window.hideWhatsApp(); // Hides WhatsApp button (display: none)
window.showWhatsApp(); // Unhides it
window.unmountWhatsApp(); // Removes from DOM entirely
```
---
We emit **custom browser events** so you can capture interactions and feed them into Google Tag Manager, Google Analytics, Meta Pixel, or any other analytics tool.
| Widget | Event name | Fired when | `detail` payload |
|--------|------------|------------|------------------|
| WebChat | `notchatbot-webchat-open` | The floating chat is opened | `{ conversationId }` |
| WebChat | `notchatbot-webchat-closed` | The floating chat is closed | `{ conversationId }` |
| WebChat | `notchatbot-webchat-message-sent` | The user sends one or more messages | `{ messages: Message[] }` |
| WebChat | `notchatbot-webchat-message-received` | A message is received from the server | `{ message: Message, role: 'assistant' \| 'employee' }` |
| WebChat | `notchatbot-webchat-button-click` | The round chat widget activator button is clicked | N/A |
| WebChat | `notchatbot-chatbubble-popover-click` | The initial presentation chat bubble is clicked | N/A |
| WebChat | `notchatbot-webchat-menu-whatsapp-click` | The WhatsApp button inside the WebChat multi-option menu is clicked | N/A |
| WebChat | `notchatbot-webchat-menu-webchat-click` | The standard Webchat button inside the multi-option menu is clicked | N/A |
| WhatsApp | `notchatbot-whatsapp-button-click` | The standalone WhatsApp widget is clicked | N/A |
| EmbedChat | `notchatbot-embedchat-message-sent` | The user sends a message | `{ message: Message }` |
| EmbedChat | `notchatbot-embedchat-message-received` | A message is received | `{ message: Message, role: 'assistant' \| 'employee' }` |
`Message` follows the same interface used internally by the widget (id, text, sender, timestamp, etc.).
#### Quick example
```js
window.addEventListener('notchatbot-webchat-open', e => console.log('WebChat opened', e.detail));
window.addEventListener('notchatbot-webchat-closed', e => console.log('WebChat closed', e.detail));
window.addEventListener('notchatbot-webchat-message-sent', e => console.log('Sent', e.detail.messages));
window.addEventListener('notchatbot-webchat-message-received', e => {
const { role, message } = e.detail;
console.log('Received', role, message);
});
```
**NEW:** All the events listed above are automatically pushed to the **dataLayer** simultaneously, alongside the window events! This means you can just create a trigger in GTM for `notchatbot-webchat-message-sent` or `notchatbot-whatsapp-button-click` right out of the box, without writing manual JS event listeners.
If you prefer firing custom data structures or if you need the message contents cleanly mapped, you can still listen to the `window` events and push to dataLayer manually:
```js
window.addEventListener('notchatbot-webchat-message-sent', e => {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'webchat_message_sent',
messages: e.detail.messages,
conversationId: e.detail.messages[0]?.conversationId || null
});
});
```
Then in GTM, add a **Custom Event** trigger called `webchat_message_sent` (or `notchatbot-webchat-message-sent` natively) and link it to a GA4 event tag.
```js
window.addEventListener('notchatbot-webchat-open', () => {
if (window.fbq) {
fbq('trackCustom', 'WebChatOpened');
}
});
window.addEventListener('notchatbot-webchat-message-received', e => {
if (window.fbq) {
fbq('trackCustom', 'WebChatMessageReceived', {
role: e.detail.role
});
}
});
```
These events make it easy to measure engagement and conversions driven by the chat widget without modifying its source code.
```js
window.setWebChatPosition({
position: 'bottom-left',
marginBottom: 40,
marginSide: 30
});
```
```js
window.setWebChatPosition({
mobile: {
position: 'bottom-right',
marginBottom: 100,
marginSide: 20
}
});
```
```js
window.setWebChatPosition({
desktop: {
position: 'bottom-left',
marginBottom: 60,
marginSide: 40
}
});
```
```js
window.setWebChatPosition({
device: 'mobile',
marginBottom: 120,
marginSide: 15
});
```
You can dispatch events to change padding/margin or open/close the chat from anywhere in your app:
```js
window.dispatchEvent(new CustomEvent('openWebChatbot'));
window.dispatchEvent(new CustomEvent('closeWebChatbot'));
window.dispatchEvent(new CustomEvent('toggleWebChatbot'));
```
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { y: 100, x: 30 } }));
```
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'mobile', marginBottom: 120, marginSide: 20 } }));
```
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'desktop', marginBottom: 60, marginSide: 40 } }));
```
```js
window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: {
mobile: { marginBottom: 90, marginSide: 10 },
desktop: { marginBottom: 50, marginSide: 30 }
}}));
```
- **Flat:** `{ marginBottom, marginSide, position }` (applies to both if no override in mobile/desktop)
- **By device:** `{ device: 'mobile'|'desktop', marginBottom, marginSide }`
- **Nested:** `{ mobile: { ... }, desktop: { ... } }`
- **Alias:** `{ y, x }` (`y` β marginBottom, `x` β marginSide)
You can combine these formats as needed.
You can inject hot CSS into the floating WebChat using the global API:
```js
// Change the header background color
window.injectWebChatCSS(`
background:
color:
}
`);
// Hide the floating button
window.injectWebChatCSS(`
// Change the chat window width
window.injectWebChatCSS(`
// Change the floating button color
window.injectWebChatCSS(`
// Remove all custom styles
window.removeWebChatCSS();
```
You can use these IDs to select and style specific parts of the widget:
- `
- `
- `
Example to change the header and button color:
```js
window.injectWebChatCSS(`
`);
```
You can combine these selectors to fully customize the widget.
---