@developer.notchatbot/webchat

中文文档
2.8.4发布于 2026/11/12MITTypeScriptESM + CJS近 30 天下载 4453

A beautiful React chatbot widget with single-file bundle

原始使用文档
文档目录30 节
  1. 📦 Quick Start
  2. 1. Add the widget to your website
  3. 2. That's it! 🎉
  4. ⚙️ Configuration Options
  5. 🎯 Targeting a non-production backend
  6. 📦 Installation and Basic Usage
  7. 📦 Installation and Basic Usage
  8. Direct HTML
  9. JavaScript/TypeScript
  10. ⚙️ Complete Configuration
  11. Required Properties
  12. Content Properties
  13. Size Properties
  14. Appearance Properties
  15. Section Control Properties
  16. Input Configuration
  17. Custom CSS
  18. Size Control
  19. Visual Customization
  20. 📋 Complete Property Reference
  21. EmbedChatConfig Configuration Table
  22. 🛠️ Dynamic Control via API and Events
  23. WebChat Global Methods
  24. EmbedChat Global Methods
  25. WhatsApp Global Methods
  26. Listen to lifecycle & message events (🆕)
  27. Change position and padding dynamically (WebChat)
  28. Use custom events (addCustomPadding and open/close control)
  29. Accepted object formats
  30. Inject and remove custom CSS in WebChat

🔷 WebChat - Embedded Chat

Webchat 2.0.0 uses origin-bound visitor credentials and requires the matching NotChatbot backend and Cloudflare presence service. See the rollout guide before upgrading an existing install.

📦 Quick Start

1. Add the widget to your website

<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>

2. That's it! 🎉

The chatbot button will appear in the bottom-right corner of your page. CSS is automatically injected!

⚙️ Configuration Options

interface WebChatConfig {
  title?: string;                       // Chat window title
  placeholder?: string;                 // Input placeholder text
  primaryColor?: string;                // Primary theme color (also the user bubble)
  bubbleBotColor?: string;              // Bot bubble background ('' / omitted = #f1f2f4; text contrast adapts)
  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
  };
  apiBaseUrl?: string;                  // Backend override (see "Targeting a non-production backend")
  realtimeUrl?: string;                 // Convex deployment override (same section)
}

interface WebChatPositionConfig {
  position?: 'bottom-right' | 'bottom-left';
  marginBottom?: number;
  marginSide?: number;
}

Example:

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"
    }
});

🎯 Targeting a non-production backend

By default the widget picks its backend from the hostname of the page it runs on: localhost → http://localhost:3000, anything else → production (https://next.notchatbot.com). That default is right for a merchant's storefront, but wrong wherever the page itself is a non-production deployment — a Vercel preview, dev.notchatbot.com, or a local dev server on a port other than 3000. Without an override, a message typed on a preview lands in the production inbox.

apiBaseUrl and realtimeUrl override that detection:

WebChat.initialize({
    apiKey: "your-chatbot-uid",
    apiBaseUrl: window.location.origin,          // HTTP: /api/webchat, /upload, /rate
    realtimeUrl: "https://<deployment>.convex.cloud" // Convex realtime subscriptions
});
  • Both must be https:// (or http://localhost / http://127.0.0.1); anything else is ignored with a console warning and the defaults are kept.
  • Set them as a pair. apiBaseUrl alone writes to one deployment while the widget keeps listening on the default Convex, so agent replies never arrive.
  • Omitting them keeps the previous behaviour exactly — existing embeds are unaffected, and each initialize() clears any override from a prior call.

💬 WhatsApp Button

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.

📦 Installation and Basic Usage

<!-- 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 - Embedded Chat

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.

📦 Installation and Basic Usage

Direct 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/TypeScript

import { EmbedChatAPI } from './webchat';

const chatInstance = EmbedChatAPI.initialize({
  elementId: "my-chat-embed",
  apiKey: "your-api-key",
  title: "Chat Assistant",
  width: 400,
  height: 500
});

⚙️ Complete Configuration

Required Properties

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
})

Content Properties

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
})

Size Properties

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)
})

Appearance Properties

EmbedChatAPI.initialize({
  // Colors
  primaryColor: "#3b82f6",           // Primary color (header, buttons, etc.)
  textColor: "#333333",              // Message text color
  bubbleUserColor: "#3b82f6",        // User message bubble background
  bubbleBotColor: "#e0f2fe",         // Bot message bubble background (default #f1f2f4)
  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
})

Section Control Properties

EmbedChatAPI.initialize({
  showHeader: true,                  // Show/hide header (default: true)
  showFooter: true,                  // Show/hide footer (default: true if footerText is provided)
})

Input Configuration

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
  }
})

Custom CSS

EmbedChatAPI.initialize({
  customCSS: `
    #notchatbot-embed-chat {
      /* Your custom styles here */
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
    }
  `
})

Size Control

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
})

Visual Customization

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: `
    #notchatbot-embed-chat {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
      border-radius: 20px !important;
    }
  `
})

📋 Complete Property Reference

EmbedChatConfig Configuration Table

PropertyTypeRequiredDefaultDescription
elementIdstring✅-ID of the HTML element where the chat will be mounted
apiKeystring✅-API key for the chat service
titlestring❌"Chat"Title shown in the chat header
placeholderstring❌"Type your message..."Input field placeholder text
primaryColorstring❌"#3b82f6"Primary color (header, buttons, links)
avatarstring❌-Bot avatar URL (optional)
initialMessagestring❌-First message shown by the bot
footerTextstring❌-Footer text (if provided, it is shown)
widthstring | number❌"100%"Chat width (px or CSS units)
heightstring | number❌400Chat height (px or CSS units)
maxWidthstring | number❌"100%"Maximum chat width
maxHeightstring | number❌"100vh"Maximum chat height
minWidthstring | number❌280Minimum chat width
minHeightstring | number❌300Minimum chat height
showHeaderboolean❌trueShow/hide the header
showFooterboolean❌trueShow/hide the footer (if footerText is provided)
borderRadiusstring | number❌12Container border radius
borderstring❌"1px solid #e5e7eb"Container border (CSS border)
boxShadowstring❌"0 10px 25px..."Container shadow
chatTransparentboolean❌falseIf true, chat background is transparent
chatBackgroundstring❌"#ffffff"Chat background color
textColorstring❌-Message text color
bubbleUserColorstring❌-User message bubble background color
bubbleBotColorstring❌"#f1f2f4"Bot message bubble background color. Empty string = default; text contrast adjusts automatically
footerColorstring❌-Footer background color
inputEmbedChatInputConfig❌-Input-specific configuration
customCSSstring❌-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

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

EmbedChat Global Methods

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.

Example

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

WhatsApp Global Methods

You can programatically show, hide, or destroy the standalone WhatsApp button from the Global window object.

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

Listen to lifecycle & message events (🆕)

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.

WidgetEvent nameFired whendetail payload
WebChatnotchatbot-webchat-openThe floating chat is opened{ conversationId }
WebChatnotchatbot-webchat-closedThe floating chat is closed{ conversationId }
WebChatnotchatbot-webchat-message-sentThe user sends one or more messages{ messages: Message[] }
WebChatnotchatbot-webchat-message-receivedA message is received from the server{ message: Message, role: 'assistant' | 'employee' }
WebChatnotchatbot-webchat-button-clickThe round chat widget activator button is clickedN/A
WebChatnotchatbot-chatbubble-popover-clickThe initial presentation chat bubble is clickedN/A
WebChatnotchatbot-webchat-menu-whatsapp-clickThe WhatsApp button inside the WebChat multi-option menu is clickedN/A
WebChatnotchatbot-webchat-menu-webchat-clickThe standard Webchat button inside the multi-option menu is clickedN/A
WhatsAppnotchatbot-whatsapp-button-clickThe standalone WhatsApp widget is clickedN/A
EmbedChatnotchatbot-embedchat-message-sentThe user sends a message{ message: Message }
EmbedChatnotchatbot-embedchat-message-receivedA 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

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);
});

Google Tag Manager / Google Analytics (GA4)

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:

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.

Meta / Facebook Pixel

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.

Change position and padding dynamically (WebChat)

1. Change position and margin globally (flat)

window.setWebChatPosition({
  position: 'bottom-left',
  marginBottom: 40,
  marginSide: 30
});

2. Change only for mobile

window.setWebChatPosition({
  mobile: {
    position: 'bottom-right',
    marginBottom: 100,
    marginSide: 20
  }
});

3. Change only for desktop

window.setWebChatPosition({
  desktop: {
    position: 'bottom-left',
    marginBottom: 60,
    marginSide: 40
  }
});

4. Change using device format

window.setWebChatPosition({
  device: 'mobile',
  marginBottom: 120,
  marginSide: 15
});

Use custom events (addCustomPadding and open/close control)

You can dispatch events to change padding/margin or open/close the chat from anywhere in your app:

1. Open, close, or toggle the floating WebChat

window.dispatchEvent(new CustomEvent('openWebChatbot'));
window.dispatchEvent(new CustomEvent('closeWebChatbot'));
window.dispatchEvent(new CustomEvent('toggleWebChatbot'));

2. Change padding for both devices (flat)

window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { y: 100, x: 30 } }));

3. Change only for mobile

window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'mobile', marginBottom: 120, marginSide: 20 } }));

4. Change only for desktop

window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: { device: 'desktop', marginBottom: 60, marginSide: 40 } }));

5. Change using nested object

window.dispatchEvent(new CustomEvent('addCustomPadding', { detail: {
  mobile: { marginBottom: 90, marginSide: 10 },
  desktop: { marginBottom: 50, marginSide: 30 }
}}));

Accepted object formats

  • 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.

Inject and remove custom CSS in WebChat

You can inject hot CSS into the floating WebChat using the global API:

// Change the header background color
window.injectWebChatCSS(`
  #notchatbot-webchat-header {
    background: #111 !important;
    color: #fff !important;
  }
`);

// Hide the floating button
window.injectWebChatCSS(`#notchatbot-webchat-button { display: none !important; }`);

// Change the chat window width
window.injectWebChatCSS(`#notchatbot-webchat-window { width: 500px !important; }`);

// Change the floating button color
window.injectWebChatCSS(`#notchatbot-webchat-button { background: #f59e0b !important; }`);

// Remove all custom styles
window.removeWebChatCSS();

Internal element IDs for WebChat

You can use these IDs to select and style specific parts of the widget:

  • #notchatbot-webchat-button — Floating chat button
  • #notchatbot-webchat-header — Chat window header
  • #notchatbot-webchat-window — Main chat window

Example to change the header and button color:

window.injectWebChatCSS(`
  #notchatbot-webchat-header { background: #222 !important; color: #fff !important; }
  #notchatbot-webchat-button { background: #f59e0b !important; }
`);

You can combine these selectors to fully customize the widget.

Stable classes for message bubbles

Message bubbles (WebChat and EmbedChat) carry stable classes, safe to target from injectWebChatCSS or customCSS:

  • .nbc-bot-bubble — Bot/agent message bubble
  • .nbc-user-bubble — Visitor message bubble
  • .nbc-bubble-tail — The small tail at the top corner of each bubble

The bubble background is painted with var(--nbc-bubble-bg, <configured color>), and the tail and the options-menu fade inherit it. The text (message, time, reply quote and menu icon) is painted with var(--nbc-bubble-fg, <computed text color>). Set the custom properties instead of background / color so everything changes together, without !important:

window.injectWebChatCSS(`
  .nbc-bot-bubble { --nbc-bubble-bg: #e0f2fe; }
  .nbc-user-bubble { --nbc-bubble-bg: #1e293b; --nbc-bubble-fg: #ffffff; }
`);

The default text color is computed from the configured color (bubbleBotColor / the primary color), not from the CSS override. When the override changes contrast a lot, also set --nbc-bubble-fg on the same class (a plain color loses to the inline style), or prefer the bubbleBotColor option, which picks readable text automatically.


版本与发布记录

@developer.notchatbot/webchat 共发布 65 个版本,首次发布于 2025/06/11;过去 12 个月发布了 30 个版本。

版本发布日期距今
2.8.4latest2026/11/12今天
2.8.32026/11/102 天前
2.8.22026/11/102 天前
2.8.12026/11/092 天前
2.8.02026/11/092 天前
2.7.22026/11/065 天前

其他发布通道:next → 2.5.2。

关于 @developer.notchatbot/webchat 的常见问题

@developer.notchatbot/webchat 是什么?

A beautiful React chatbot widget with single-file bundle

如何安装 @developer.notchatbot/webchat?

在项目目录运行 npm install @developer.notchatbot/webchat,或使用 pnpm add / yarn add / bun add。

@developer.notchatbot/webchat 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@developer.notchatbot/webchat 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@developer.notchatbot/webchat 可以商用吗?

@developer.notchatbot/webchat 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@developer.notchatbot/webchat 的下载量有多少?

根据 npm 官方下载统计,@developer.notchatbot/webchat 在 2026/10/12 – 2026/11/10 这 30 天内被下载 4,453 次,日均约 148 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@developer.notchatbot/webchat 还在维护吗?

最新版本 2.8.4 发布于 2026/11/12(今天);至今共发布 65 个版本,其中过去 12 个月发布了 30 个;首次发布于 2025/06/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。