Next.js中Script加载Watson聊天组件路由切换重复渲染如何解决?
问题根因
该问题本质是Next.js客户端路由跳转不会触发整页刷新,每次Bot组件挂载时都会重复注入Watson脚本、重复初始化聊天实例,旧实例没有被正确销毁,才会出现多个聊天窗口叠加的情况。
修复方案
新增全局判断防止重复初始化/脚本注入
在配置代码最开头增加全局标记逻辑,避免重复创建脚本、重复注册配置:
<Script> {` // 新增全局判断,防止重复加载 if (!window.watsonAssistantChatInstance && !document.querySelector('#watson-chat-script')) { window.watsonAssistantChatOptions = { showLauncher: false, openChatByDefault: true, element: document.querySelector('.chatElement'), onLoad: function(instance) { // 把实例挂载到window上,方便后续销毁 window.watsonAssistantChatInstance = instance; instance.updateHomeScreenConfig({ is_on: true, greeting: '', starters: { is_on: true, buttons: [ { label: 'Turn home screen off' }, { label: 'Add conversation starters' }, { label: 'Add custom content' }, ], }, }); instance.on({ type: "pre:send", handler: preSendhandler }); instance.render(); } }; setTimeout(function(){ const t=document.createElement('script'); // 给脚本加id,方便判断是否已经注入 t.id = 'watson-chat-script'; t.src="https://web-chat.global.assistant.watson.appdomain.cloud/versions/" + (window.watsonAssistantChatOptions.clientVersion || 'latest') + "/WatsonAssistantChatEntry.js" document.head.appendChild(t); }) } `} </Script>
组件卸载时销毁实例、清理残留DOM
如果你的Bot组件是在页面层单独挂载的,需要在组件卸载钩子中销毁已有的Watson实例,同时清理聊天容器的内容:
// 函数组件示例,加useEffect清理逻辑 useEffect(() => { return () => { if (window.watsonAssistantChatInstance) { // 调用官方destroy方法销毁实例 window.watsonAssistantChatInstance.destroy(); window.watsonAssistantChatInstance = null; // 清理聊天容器残留内容 const chatEl = document.querySelector('.chatElement'); if (chatEl) chatEl.innerHTML = ''; } } }, [])
调整组件挂载位置(可选)
如果需要所有页面都共用同一个聊天窗口,建议直接把Bot组件放到_app.js里全局挂载,不要在每个页面单独引入,配合上述全局判断逻辑,就能保证整个站点只初始化一次聊天实例,不会出现重复渲染的问题。
内容的提问来源于stack exchange,提问作者Jota
相关产品推荐
相关产品推荐

