把 widget 的 script 标签贴进 React 项目的 index.html,能用。但你的组件跟它说不上话——hero 区放不了"来聊聊"按钮,用户登录了没法 identify,切深色模式换不了主题。@lanechat/react 就是为这事存在的:让 widget 像应用的一部分,而不是贴在上面的一张贴纸。
三步:装包、拿 App ID、包住组件树。然后重点讲那个 hook,好玩的都在里面。
第一步:装包
npm install @lanechat/react @lanechat/js
react 16.8 以上是 peer dependency(hooks 是 16.8 来的,这个包全是 hooks)。两个包当前都是 0.2.x。
第二步:拿 App ID
控制台:Applications → 你的应用 → Settings → Embed tab。最上面那张绿卡——"App ID · public identifier",带 Copy App ID 按钮——就是它。标 "Safe to share" 是真的可以公开:它只标识应用,不授权任何敏感操作。下面红色的 Secret Key 是服务端的事,永远别进前端代码。

第三步:Provider 在外,hook 在内
import React from 'react';
import { LaneChatProvider, useLaneChat } from '@lanechat/react';
function Hero() {
const { open } = useLaneChat();
return (
<button onClick={open}>Questions? Chat with us</button>
);
}
export default function App() {
return (
<LaneChatProvider appId="YOUR_APP_KEY">
<Hero />
</LaneChatProvider>
);
}
这就是一个完整接入。<LaneChatProvider> 负责加载 widget、管理生命周期:appId 变了会重新初始化,可选的 config 变了就地生效,组件卸载时 widget 自动摘除。launcher 会自己出现——默认样式是右下角一颗蓝色圆按钮。
有个结构上的事值得想通:没有 <LaneChat /> 这种组件可渲染。widget 自己挂到 document.body 上,在 React 树之外,跟 script 标签版一模一样。Provider 是生命周期管家,hook 是遥控器。
由此引出最容易绊倒人的一条规则:useLaneChat() 必须在 Provider 下层的组件里调。小项目图省事,把 Provider 和 hook 塞进同一个 App 组件——hook 就看不见 context。上面例子里 Hero 是子组件,就是这个道理。

遥控器上有什么
useLaneChat() 返回的不止 open:
open()/close()/toggle()/isOpen()——面板控制isReady——widget 是否加载完identify(traits)——告诉它这个用户是谁updateTheme(theme)——运行时换肤on(event, cb)——订阅事件,返回退订函数instance——底层 widget 实例,留作逃生舱
所有方法在 widget 没加载完之前都能安全调用——调用会被缓冲,加载好后重放。所以点击事件里不用包一层 isReady 判断;这个值主要给你自己的渲染逻辑用。
告诉 widget 谁在聊
用户一登录,就把身份递过去:
const { identify } = useLaneChat();
useEffect(() => {
if (user) {
identify({ email: user.email, name: user.name, plan: user.plan });
}
}, [user, identify]);
email、name、phone 是标准字段——访客档案里对应位置为空时会填上。其他键(比如上面的 plan)存成自定义属性。两类都会出现在客服会话旁边的访客面板里。"Visitor #99890391" 和"Jane,pro 套餐,在问发票",是两种完全不同的接待起点。
响应开与合
事件就两个:'open' 和 'close'。effect 里订阅,返回的函数拿来清理:
const { on } = useLaneChat();
useEffect(() => {
const off = on('open', () => {
analytics.track('support_chat_opened');
});
return off;
}, [on]);
事件面就这么大——没有 message 事件,也没有未读数 API。围绕面板状态做设计,别指望拿到消息内容。
Next.js 与 SSR
widget 是纯浏览器生物,但包本身对 SSR 有准备。Next.js app router 里,放 Provider 的那个文件顶上加 'use client'。widget 只在 effect 里加载,服务端渲染阶段不碰 window;effect 跑之前 hook 返回安全的空实现,isReady 是 false。在 Provider 外面调 hook 也只会拿到空实现,不会崩——用了它的组件挪进没有聊天的组件树,照常活。
就这些
没有配置文件,没有构建插件,不用手贴 script。一个带 App ID 的 Provider、需要的地方来个 hook、identify 接上你的登录态。剩下的 widget 自己处理,跟它在任何网站上一样——只是你的 React 应用多了指挥它的权力。