Typebot React 嵌入库完整指南:Standard、Popup 与 Bubble 三种模式的实战配置
【免费下载链接】typebot.io💬 Typebot is a powerful chatbot builder that you can self-host.项目地址: https://gitcode.com/GitHub_Trending/ty/typebot.io
Typebot 提供了开箱即用的 React 嵌入库@typebot.io/react,你可以在自己的 React 应用中通过三个组件——Standard(内联容器)、Popup(弹窗)、Bubble(浮动气泡)——快速集成聊天机器人,并通过命令式 API 与变量预填实现精细化控制。本文基于仓库中的 packages/embeds/react/README.md 展开,并结合packages/embeds/react与packages/embeds/js的源码实现,讲解每个组件的用法、可用参数、命令式控制方式以及底层运行原理,读完即可在项目中完成从安装到自定义主题的完整接入。
一、安装与快速上手
@typebot.io/react是围绕@typebot.io/js封装的 React 组件库,其定位在 package.json 中描述为 "Convenient library to display typebots on your React app"。安装方式与普通 npm 包一致:
npm install @typebot.io/react从包的依赖声明可以看到,它声明了react >= 18作为 peerDependency,并在内部依赖@typebot.io/js(workspace 版本),因此安装时会自动带上底层的 JS 引擎包。构建产物通过 esbuild 打包为 ESM 格式,并将react与react/jsx-runtime标记为 external,避免重复打包 React 本体。
安装完成后,即可从包入口引入三个核心组件。从 packages/embeds/react/src/index.ts 的导出可以看到,该库对外同时暴露了Bubble、Popup、Standard三个组件,以及@typebot.io/js中的全部命令式 API(如open、close、toggle):
export * from "@typebot.io/js"; export { Bubble } from "./Bubble"; export { Popup } from "./Popup"; export { Standard } from "./Standard";其中typebot属性接受的是你在 Typebot 后台发布页面中获取到的 typebot 唯一标识(形如lead-generation-copy-3luzm6b)。
二、Standard:内联嵌入到页面布局中
Standard组件用于将聊天机器人作为普通页面元素渲染,随页面流式布局,适合嵌入到内容区、侧边栏或落地页中部。
import { Standard } from "@typebot.io/react"; const App = () => { return ( <Standard typebot="lead-generation-copy-3luzm6b" style={{ width: "100%", height: "600px" }} /> ); };上述代码创建了一个宽度 100%(跟随父容器宽度)、高度 600px 的聊天容器。Standard组件的 Props 类型定义在 Standard.tsx,它在底层BotProps之上额外支持style(React 内联样式)和className(自定义类名)两个样式相关属性,方便你自由控制容器的尺寸、边框、圆角等。
从实现细节看,Standard组件渲染的是自定义元素<typebot-standard>:
return <typebot-standard ref={ref} style={style} class={className} />;值得留意的是它初始化属性时的顺序——先通过Object.assign(ref.current, rest, { typebot })将除typebot之外的所有属性一次性写入,最后再写入typebot属性,从而确保initializeBot在拿到全部初始值之后才被触发(对应 Standard.tsx 中的注释 "We assign typebot last to ensure initializeBot is triggered with all the initial values")。
三、Popup:按需弹出的模态窗口
Popup组件将聊天机器人以模态弹窗形式呈现,默认不显示,适合作为页面右下角的交互入口。
import { Popup } from "@typebot.io/react"; const App = () => { return <Popup typebot="lead-generation-copy-3luzm6b" autoShowDelay={3000} />; };autoShowDelay={3000}表示页面加载 3 秒后自动弹出弹窗(单位为毫秒)。与Standard直接渲染自定义元素不同,Popup组件在内部维护一个容器div,并通过document.createElement("typebot-popup")动态创建弹窗元素后挂载到该容器中(见 Popup.tsx),在组件卸载时则通过popupRef.current?.remove()清理 DOM,避免内存泄漏(见 Popup.tsx)。从@typebot.io/js中定义的 PopupProps 可以看出,它还在BotProps基础上支持defaultOpen、isOpen等受控属性。
3.1 命令式打开与关闭弹窗
@typebot.io/react提供了全局命令式 API,可在任意事件回调中控制弹窗状态:
import { open } from "@typebot.io/react"; open();import { close } from "@typebot.io/react"; close();import { toggle } from "@typebot.io/react"; toggle();这三个函数分别在 packages/embeds/js/src/features/commands/utils/open.ts、close.ts、toggle.ts 中实现。它们本质上不直接操作 DOM,而是向全局派发一条携带isFromTypebot: true与命令名的消息(open/close/toggle),由对应 web component 内部监听并执行实际的开合逻辑。这种"命令消息"机制让命令与组件解耦,即使命令在弹窗组件尚未挂载时调用也不会抛错。
四、Bubble:悬浮气泡与预览消息
Bubble组件以页面角落的悬浮按钮呈现,点击后展开聊天窗口,是客服、售前咨询类场景最常见的形态。
import { Bubble } from "@typebot.io/react"; const App = () => { return ( <Bubble typebot="lead-generation-copy-3luzm6b" previewMessage={{ message: "I have a question for you!", autoShowDelay: 5000, avatarUrl: "https://avatars.githubusercontent.com/u/16015833?v=4", }} theme={{ button: { backgroundColor: "#0042DA", iconColor: "#FFFFFF" }, previewMessage: { backgroundColor: "#ffffff", textColor: "black" }, }} /> ); };这段代码会渲染一个悬浮气泡按钮,并在 5 秒后自动显示一条带头像的预览消息("I have a question for you!"),引导用户点击进入对话。其中:
previewMessage.message:预览消息文本;previewMessage.autoShowDelay:预览消息自动出现的延迟毫秒数(示例为 5000,即 5 秒);previewMessage.avatarUrl:预览消息发送者头像地址;theme.button.backgroundColor/theme.button.iconColor:悬浮按钮的背景色与图标颜色;theme.previewMessage.backgroundColor/theme.previewMessage.textColor:预览消息气泡的背景色与文字颜色。
从源码看,Bubble的类型定义继承自BotProps与 BubbleParams,后者包含theme、previewMessage、autoShowDelay三个字段。预览消息与自动打开的实际触发逻辑在 Bubble.tsx:当autoShowDelay被定义时通过setTimeout(openBot, autoShowDelay)自动打开聊天气泡,当previewMessage.autoShowDelay被定义时通过setTimeout(showPreviewMessage, previewAutoDelay)自动弹出预览消息。
需要特别说明的是,Bubble组件默认会将typebot-bubble元素直接挂载到document.body最前面(document.body.prepend(ref.current)),因此它不受页面内父容器的布局约束,始终悬浮于页面之上。只有当theme.position === "static"时,它才会以内联元素的形式随页面流式渲染,并通过resolveButtonSize计算按钮的实际像素尺寸(见 Bubble.tsx)。
4.1 控制预览消息的显示与隐藏
Bubble 模式下预览消息也可通过命令式 API 控制:
import { showPreviewMessage } from "@typebot.io/react"; showPreviewMessage();import { hidePreviewMessage } from "@typebot.io/react"; hidePreviewMessage();其底层实现位于 showPreviewMessage.ts 与 hidePreviewMessage.ts。其中showPreviewMessage还接受一个可选的message参数(含message与avatarUrl),用于临时覆盖默认预览消息内容;而hidePreviewMessage则直接派发隐藏命令。在 JS 引擎内部,showPreviewMessage处理时会先判断聊天窗口是否已打开——若已打开则不再显示预览消息,避免重复打扰用户(见 Bubble.tsx)。
4.2 控制聊天窗口的开关
与 Popup 相同,Bubble 的聊天窗口同样支持open/close/toggle三个命令:
import { open } from "@typebot.io/react"; open();import { close } from "@typebot.io/react"; close();import { toggle } from "@typebot.io/react"; toggle();三者的行为语义与 Popup 完全一致(打开 / 关闭 / 切换),Bubble 与 Popup 组件会各自监听并响应这些命令。
五、变量预填:prefilledVariables
聊天机器人中的变量可以在嵌入时直接预填,避免用户重复输入已知信息。以Standard为例:
import { Standard } from "@typebot.io/react"; const App = () => { return ( <Standard typebot="lead-generation-copy-3luzm6b" style={{ width: "100%", height: "600px" }} prefilledVariables={{ "Current URL": "https://my-site/account", "User name": "John Doe", }} /> ); };以上配置会将Current URL变量预填为https://my-site/account,将User name变量预填为John Doe。关于 Typebot 变量的完整说明可参考仓库文档 variables。
从实现层面看,变量预填包含两条注入路径,它们最终会被合并:
- 组件属性注入:
prefilledVariables作为BotProps的一部分(定义见 Bot.tsx)传入,类型为Record<string, unknown>; - URL 查询参数自动注入:只要你的站点 URL 携带查询参数(例如
https://typebot.io?User%20name=John%20Doe),这些参数就会被自动解析进聊天机器人,无需手动把它们搬运到嵌入配置中。该逻辑在 Bot.tsx 中实现:组件初始化时通过new URLSearchParams(location.search)读取当前页面 URL 的全部查询参数,然后以{ ...prefilledVariables, ...props.prefilledVariables }的顺序合并——组件显式传入的prefilledVariables会覆盖 URL 中的同名参数,最终合并结果随启动请求一起发送给后端。
这意味着你可以直接用?User%20name=John%20Doe这类带编码空格的查询参数在投放链接层面完成变量透传,适合落地页广告、邮件营销等场景。
六、底层原理:Web Component 封装与懒加载
理解@typebot.io/react的架构,有助于排查 SSR 兼容性、包体积等工程问题。其核心设计是:React 组件只是薄封装,真正的渲染由@typebot.io/js注册的自定义元素(Web Component)完成。
6.1 组件如何与自定义元素通信
三个组件在挂载时都会调用 ensureWebComponentsLoaded.ts 中的ensureWebComponentsLoaded()。该函数做了两件事:
- SSR 守卫:通过
import.meta.env?.SSR ?? typeof window === "undefined"判断是否处于服务端渲染环境,如果是则直接返回,避免在 Node 环境执行浏览器专有代码; - 懒加载注册:将
import("./web")的结果缓存为webComponentsLoadPromise,确保自定义元素注册代码(web.ts 中的import "@typebot.io/js/web")只在浏览器端、且只执行一次,从而把 JS 引擎的代码拆分为独立 chunk,减小首屏加载体积。
随后组件通过Object.assign把 React props 直接写到自定义元素实例上(这正是"属性即配置"的实现基础),并在 props 变化时由useEffect重新赋值以触发更新。
6.2 类型声明的两种形态
由于组件需要渲染非标准 HTML 标签,源码中通过declare module "react"扩展了JSX.IntrinsicElements,为typebot-standard、typebot-popup、typebot-bubble补充类型声明(分别见 Standard.tsx、Popup.tsx、Bubble.tsx),让你在 TSX 中使用这些自定义元素时获得完整的类型提示。
七、完整示例与选型建议
综合以上内容,一个包含三种形态的典型接入如下:
import { Standard, Popup, Bubble, open, toggle } from "@typebot.io/react"; // 内联模式:嵌入页面内容区 export const InlineSection = () => ( <Standard typebot="lead-generation-copy-3luzm6b" style={{ width: "100%", height: "600px" }} /> ); // 弹窗模式:3 秒后自动弹出 export const PopupLauncher = () => ( <Popup typebot="lead-generation-copy-3luzm6b" autoShowDelay={3000} /> ); // 气泡模式:带主题与预览消息 export const FloatingButton = () => ( <Bubble typebot="lead-generation-copy-3luzm6b" previewMessage={{ message: "需要帮助吗?", autoShowDelay: 3000 }} theme={{ button: { backgroundColor: "#0042DA", iconColor: "#FFFFFF" }, previewMessage: { backgroundColor: "#ffffff", textColor: "black" }, }} /> ); // 任意事件回调中命令式打开 <button onClick={() => open()}>打开聊天</button>选型建议:内容型页面用Standard保证机器人随页面布局流动;需要在特定时机(如表单放弃、页面停留 N 秒)触达用户的场景用Popup配合autoShowDelay或命令式open();希望常驻页面一角、提供持续入口的客服场景优先选择Bubble,并搭配previewMessage做主动引导。所有模式均可通过prefilledVariables预填变量,配合 URL 查询参数实现投放级变量透传,将用户上下文无缝带入对话流程。
【免费下载链接】typebot.io💬 Typebot is a powerful chatbot builder that you can self-host.项目地址: https://gitcode.com/GitHub_Trending/ty/typebot.io
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考