@evolve-packages/chat-widget

中文文档
0.5.1发布于 2026/10/23MITTypeScriptESM + CJS近 30 天下载 6386

Embeddable chat widget for Evolve e-commerce platform

原始使用文档
文档目录28 节
  1. Features
  2. Installation
  3. Script Tag (easiest)
  4. pnpm Package
  5. Configuration
  6. Required Options
  7. Display Options
  8. Branding Options
  9. Label Options
  10. Context Options
  11. Callbacks
  12. Project assistant
  13. Backend contract
  14. AI SDK version
  15. Examples
  16. Floating Widget (bottom-right)
  17. Floating Widget (bottom-left)
  18. Inline Embed
  19. With Cart Integration
  20. Custom Branding
  21. Development
  22. Build
  23. Development Mode
  24. Type Check
  25. Architecture
  26. Cookie Requirements
  27. Browser Support
  28. License

Evolve Chat Widget

Embeddable chat widget for the Evolve e-commerce platform. Allows customers to interact with an AI shopping assistant directly on your website.

Features

  • Floating button or inline embed mode
  • Product cards with images, prices, and quantities
  • Shopping cart and wishlist integration
  • Configurable branding and labels
  • Automatic user name extraction from JWT
  • Cross-origin support with shared cookies

Installation

Script Tag (easiest)

Add the widget script to your HTML:

<script src="https://chat.evolve-platform.com/widget.js"></script>
<script>
  EvolveChat.init({
    tenantId: 'evolve',
    mode: 'floating',
    position: { horizontal: 'right', vertical: 'bottom' },
  });
</script>

pnpm Package

pnpm install @evolve-packages/chat-widget
import { EvolveChatWidget } from '@evolve-platform/chat-widget';

function App() {
  return (
    <EvolveChatWidget
      tenantId="evolve"
      mode="floating"
      branding={{ primaryColor: '#f97316' }}
    />
  );
}

Configuration

Required Options

OptionTypeDescription
tenantIdstringTenant identifier for multi-tenant support

Display Options

OptionTypeDefaultDescription
mode'floating' | 'inline''floating'Display mode
containerstring-CSS selector for inline mode container
positionWidgetPositionSee belowPosition for floating mode
zIndexnumber9999z-index for floating widget

Position Configuration

interface WidgetPosition {
  horizontal: 'left' | 'right';  // default: 'right'
  vertical: 'top' | 'bottom';    // default: 'bottom'
  offsetX?: number;              // default: 20
  offsetY?: number;              // default: 20
}

Branding Options

interface WidgetBranding {
  primaryColor?: string;      // Primary color (default: '#f97316')
  primaryTextColor?: string;  // Text on primary (default: '#ffffff')
  accentColor?: string;       // Call-to-action colour (default: primaryColor)
  accentTextColor?: string;   // Text on accent (default: primaryTextColor)
  headerTitle?: string;       // Widget header title
  logoUrl?: string;           // Custom logo URL
  avatarUrl?: string;         // Avatar for assistant messages
  showHeader?: boolean;       // Inline only: header bar with logo and title (default: true)
}

Label Options

interface WidgetLabels {
  placeholder?: string;  // Input placeholder text
  greeting?: string;     // Greeting message (use {name} for user name)
  thinking?: string;     // "Thinking" indicator text
  close?: string;        // Close button label
  sendLabel?: string;    // Accessible name of the send button (default: 'Send message')
}

Context Options

OptionTypeDescription
apiBaseUrlstringAPI base URL (default: current origin)
cartIdstringShopping cart ID for cart operations
firstNamestringUser's first name for personalized greeting
modelIdstringAI model ID to use

Callbacks

interface WidgetCallbacks {
  onOpen?: () => void;              // Called when widget opens
  onClose?: () => void;             // Called when widget closes
  onMessage?: (message: string) => void;  // Called when user sends message
  onError?: (error: Error) => void; // Called on error
}

Project assistant

The project assistant is an opt-in feature that turns the backend's project-assistant tools (ask_user, select_product, present_kit, offer_help, …) into interactive cards: question tiles, a product lane, a materials list with cart/list actions, manual links with a contact form, a quick-start screen and a progress bar.

<EvolveChatWidget
  tenantId="evolve"
  features={["projectAssistant"]}
  isAuthenticated={isLoggedIn}
  labels={{
    projectAssistant: {
      quickStartJobs: [
        { id: "roof", emoji: "🏠", title: "Solar panels on a roof", prompt: "I want to install solar panels on my roof" },
      ],
      questSteps: ["Roof", "Panels", "Inverter", "Materials list"],
    },
  }}
/>
  • features={["projectAssistant"]} turns the feature on; without it the widget renders these tools as before. WidgetFeatureId is exported for typing the list.
  • isAuthenticated decides which materials-list actions are offered: signed-in shoppers get "Add to cart" and "Save as list", anonymous shoppers only "Share list".
  • loadShoppingLists (optional, () => Promise<WidgetShoppingList[]>, each { id, version, name }) turns a signed-in shopper's "Save as list" into a favourites menu. The widget calls it every time the menu opens and never fetches lists itself, so the host loads them with its own session. Picking a list sends save_list with that list's listId and version; "New shareable list" sends it without a listId. Without the callback, "Save as list" sends save_list straight away as before.
  • createShoppingList (optional, (name: string) => Promise<WidgetShoppingList>) puts a "New list" in that menu instead of "New shareable list": the shopper enters a name, the host creates the list in the customer's account with its own session and returns { id, version, name }, and the widget then sends save_list with that listId and version. A rejected promise keeps the menu open with receiptNewListError. Without it the menu keeps the anonymous "New shareable list".
  • labels.projectAssistant (ProjectAssistantLabels) overrides any copy. The package ships generic defaults and no catalogue content, so the host supplies quickStartJobs (tiles on the empty state; prompt is sent as the first message) and questSteps (the progress bar; its names must match the questStep values the backend tools emit). Leaving either empty hides that element.
  • When quickStartJobs is non-empty, the quick-start screen replaces the host greeting on an empty chat. It shows quickStartTitle, quickStartSubtitle, quickStartQuestion, the job tiles and quickStartHint; an empty string hides any of the texts.
  • While the feature is active the composer is a large rounded field with a round send button. branding.primaryColor drives the stepper, links, tile borders, card header bars and the bubble tints; branding.accentColor drives the calls to action: the send button, the receipt's first action and the help offer's contact button, with secondary receipt actions outlined in the primary colour. Without an accent both fall back to the primary colour. Either may be a CSS variable such as var(--brand-main).
  • A page that already titles the chat can pass branding={{ showHeader: false }} in inline mode; the widget then also drops its card shadow and radius so the host container frames it.

Backend contract

Every answer a project-assistant card sends is a regular user message whose text is a JSON object with a pa_action field. The backend system prompt must understand these six actions:

pa_actionFields
answerquestion, values: string[]
product_selectedsku, name
product_enteredtext
add_to_cartitems: { sku, quantity }[]
save_listitems: { sku, quantity }[], version, optional listId
contactfirstName, lastName, email, companyName, phone, question

The widget shows these messages as short badges instead of raw JSON.

AI SDK version

The widget runs on AI SDK 7. Chat-backend releases built on AI SDK 7 add toolMetadata to MCP tool chunks, which older widgets reject, so upgrade this package together with @evolve-framework/chat-backend (its ai-7 releases). The widget still parses streams from an AI SDK 6 backend.

Examples

Floating Widget (bottom-right)

EvolveChat.init({
  tenantId: 'evolve',
  mode: 'floating',
  position: {
    horizontal: 'right',
    vertical: 'bottom',
    offsetX: 20,
    offsetY: 20,
  },
  branding: {
    primaryColor: '#f97316',
  },
});

Floating Widget (bottom-left)

EvolveChat.init({
  tenantId: 'evolve',
  mode: 'floating',
  position: {
    horizontal: 'left',
    vertical: 'bottom',
  },
});

Inline Embed

<div id="chat-container" style="width: 400px; height: 600px;"></div>

<script>
  EvolveChat.init({
    tenantId: 'evolve',
    mode: 'inline',
    container: '#chat-container',
  });
</script>

With Cart Integration

EvolveChat.init({
  tenantId: 'evolve',
  mode: 'floating',
  cartId: 'abc123-cart-id',
  firstName: 'Jan',
});

Custom Branding

EvolveChat.init({
  tenantId: 'evolve',
  mode: 'floating',
  branding: {
    primaryColor: '#1e40af',
    primaryTextColor: '#ffffff',
    headerTitle: 'Shop Assistant',
  },
  labels: {
    placeholder: 'Stel je vraag...',
    greeting: 'Hoi {name}! Hoe kan ik je helpen?',
    thinking: 'Even denken...',
  },
});

Development

Build

pnpm run build

Outputs:

  • dist/widget.js - UMD bundle (for script tag, includes React)
  • dist/widget.css - Extracted styles
  • dist/index.esm.js - ESM bundle (for pnpm, React as peer dep)
  • dist/index.js - CJS bundle (for pnpm, React as peer dep)

Development Mode

pnpm run dev     # Watch mode with auto-rebuild
pnpm run serve   # Serve dist folder for testing

Type Check

pnpm run typecheck

Architecture

widget/
├── src/
│   ├── index.ts              # pnpm package entry
│   ├── init.ts               # Script tag entry (EvolveChat.init)
│   ├── components/
│   │   ├── ChatWidget.tsx    # Main wrapper
│   │   ├── FloatingButton.tsx
│   │   ├── ChatPanel.tsx
│   │   ├── WidgetChat.tsx    # Chat UI (no Next.js deps)
│   │   ├── WidgetProductCard.tsx
│   │   └── WidgetToolQuery.tsx
│   ├── context/
│   │   └── WidgetProvider.tsx
│   ├── styles/
│   │   └── widget.css
│   ├── types/
│   │   └── config.ts
│   └── utils/
│       ├── api.ts
│       └── graphql-product-mapper.ts
├── dist/                     # Build output
├── package.json
├── rollup.config.js
└── tsconfig.json

For authentication to work across domains, cookies must be configured:

  1. Cookie domain: .evolve-platform.com (with leading dot for subdomains)
  2. SameSite: Lax or None (with Secure flag)
  3. CORS: Server must send Access-Control-Allow-Credentials: true

Browser Support

  • Chrome 80+
  • Firefox 75+
  • Safari 13+
  • Edge 80+

License

MIT

版本与发布记录

@evolve-packages/chat-widget 共发布 13 个版本,首次发布于 2025/12/18;过去 12 个月发布了 13 个版本。

版本发布日期距今
0.5.1latest2026/10/2321 天前
0.5.02026/10/2321 天前
0.4.12026/08/182 个月前
0.4.02026/08/142 个月前
0.3.12026/08/123 个月前
0.3.02026/08/043 个月前

关于 @evolve-packages/chat-widget 的常见问题

@evolve-packages/chat-widget 是什么?

Embeddable chat widget for Evolve e-commerce platform

如何安装 @evolve-packages/chat-widget?

在项目目录运行 npm install @evolve-packages/chat-widget,或使用 pnpm add / yarn add / bun add。

@evolve-packages/chat-widget 支持 TypeScript 吗?

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

@evolve-packages/chat-widget 支持 ESM 还是 CommonJS?

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

@evolve-packages/chat-widget 可以商用吗?

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

@evolve-packages/chat-widget 的下载量有多少?

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

@evolve-packages/chat-widget 还在维护吗?

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