<CustomerService />,根据配置去加载四家 provider 之一。
切一下 config 开关,配上对应的 public env 变量,每个页面右下角就会出现聊天气泡。Provider
会自己根据 env 变量决定是否渲染——没配齐就返回 null,不会把页面弄崩。
前置条件
- 在 Crisp、Tawk.to、Intercom、Chatwoot 四家里挑一家注册账号。
- 拿到 provider dashboard 里的 site / property / app ID。
- 在 provider 后台把生产域名加到白名单(绝大多数都会拒绝来自未知 origin 的嵌入)。
一步步配置
-
在
src/config/site.ts选 provider: -
把对应的 env 变量加到
.env.local。所有变量都是NEXT_PUBLIC_*开头—— loader 脚本在浏览器跑,所以必须暴露给客户端。 - 在 provider 后台把你的域名加白名单(Crisp → Settings → Website Settings; Tawk → Property → Widget → Restrictions,etc)。
-
重启
pnpm dev——NEXT_PUBLIC_*是构建时打进去的,不重启不会生效。
怎么挑
| Provider | 适用场景 |
|---|---|
| Crisp | 免费额度大方(2 个坐席、不限联系人),后台漂亮,配置最快。独立开发者首选。 |
| Tawk.to | 完全免费,没有任何套餐限制。代价:底栏带品牌水印,去掉要 $19/月。 |
| Intercom | 企业标准款。有专门的支持团队、想上 product tour、工单、出站营销,就选它。 |
| Chatwoot | 开源、可自托管。要数据主权、或者想把客服后端跑在自己服务器上的,选这个。 |
验证生效
- 用无痕窗口打开站点——气泡应该在右下角 1 秒内出现。
- 发一条测试消息,去 provider 后台看收件箱。
- 打开
/login或/register——这两个页面故意没有 widget(<CustomerService />挂在 app 布局里,不在 auth 布局里)。 - 查看页面源码:应该只看到当前 provider 的 loader 脚本,其他三家应该没出现。
常见坑
- 忘了
NEXT_PUBLIC_前缀。浏览器要读的变量必须带前缀,否则 Next.js 在打包时 会把它剥掉,widget 就静默失败。 - 没把域名加白名单。大多数 provider 会在未知 origin 上拒绝渲染(表现是空气泡, 或者 devtools 报 CORS 错)。
- CSP 拦了脚本。你要是加了 Content-Security-Policy header,得把 provider 的 CDN
加到
script-src和connect-src(如https://client.crisp.chat、https://embed.tawk.to、https://widget.intercom.io、Chatwoot 的 base URL)。 - 同时出现两个 widget。
enable: true+ 上一家遗留的 env 不会重复渲染——src/customer-service/index.tsx的 switch 只挂当前那个。残留 env 没害处,但建议清掉。 - 认证页没 widget。这是有意为之(layout 不一样)。要全站都显示,把
<CustomerService />挂到 root layout 而不是 app layout。
加一个新 provider
模式刻意做得很小——一个 client 组件,读 env 变量,返回<Script> 标签(或 null)。
对照 src/customer-service/provider/*.tsx 任一文件依葫芦画瓢即可:
- 在
src/customer-service/types.ts的联合类型里加一个名字。 - 在
src/customer-service/index.tsx的 switch 加一个case。 - 在
src/env.ts的client.NEXT_PUBLIC_*加 env 变量。
官方文档
- Crisp:docs.crisp.chat
- Tawk.to:help.tawk.to
- Intercom:intercom.com/help/en
- Chatwoot:chatwoot.com/docs