You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14.1(App Router)中Zendesk Widget导航后消失求助

Next.js 14.1 App Router中Zendesk Messaging Widget客户端导航后消失的解决方法

问题背景

在Next.js 14.1 App Router应用中集成Zendesk Messaging Widget时,页面初始加载时Widget按钮正常显示且可点击,但通过客户端导航(无全页刷新)后,Widget按钮和对应的iframe完全消失。尝试将组件放在layout.js中或单独页面引入,以及使用next/script加载脚本,问题均未解决。

原因分析

Next.js App Router的客户端导航会触发组件的卸载与重新挂载:

  1. 原代码中组件卸载时移除了Zendesk脚本,导致Widget依赖的全局对象zE和DOM元素被清理;
  2. Zendesk脚本首次加载后会缓存全局zE对象,直接重新加载脚本不会触发初始化逻辑,因此导航后无法恢复Widget。

解决方案

方案1:保留脚本+路由变化时重新初始化

将组件转为客户端组件,移除脚本清理逻辑,监听路由变化,每次导航后检查zE对象是否存在,存在则重新显示Widget并执行用户登录逻辑,不存在则加载脚本。

'use client';

import { useEffect, useRef } from 'react';
import { usePathname } from 'next/navigation';

const ZendeskWidget = () => {
  const pathname = usePathname();
  const isScriptLoaded = useRef(false);

  useEffect(() => {
    const initZendesk = () => {
      // 已有zE对象,直接重新初始化Widget
      if (window.zE) {
        window.zE('messenger', 'show');
        window.zE("messenger", "loginUser", (callback) => {
          fetch('/api/zendesk')
            .then(res => res.json())
            .then(jsonRes => {
              if (jsonRes.success) callback(jsonRes.token);
            });
        });
        return;
      }

      // 首次加载脚本
      const script = document.createElement('script');
      script.id = 'ze-snippet';
      script.type = 'text/javascript';
      script.src = `https://static.zdassets.com/ekr/snippet.js?key=${process.env.NEXT_PUBLIC_ZENDESK_KEY}`;
      script.async = true;
      script.onload = () => {
        window.zE("messenger", "loginUser", (callback) => {
          fetch('/api/zendesk')
            .then(res => res.json())
            .then(jsonRes => {
              if (jsonRes.success) callback(jsonRes.token);
            });
        });
        isScriptLoaded.current = true;
      };
      document.body.appendChild(script);
    };

    initZendesk();
  }, [pathname]); // 监听路由变化触发重新初始化

  return null;
};

export default ZendeskWidget;

方案2:使用Next.js Script组件+路由监听

利用Next.js的Script组件加载脚本,同时监听路由变化,导航后重新触发Widget初始化:

'use client';

import { useEffect } from 'react';
import { Script } from 'next/script';
import { usePathname } from 'next/navigation';

const ZendeskWidget = () => {
  const pathname = usePathname();

  const initZendeskUser = () => {
    window.zE("messenger", "loginUser", (callback) => {
      fetch('/api/zendesk')
        .then(res => res.json())
        .then(jsonRes => {
          if (jsonRes.success) callback(jsonRes.token);
        });
    });
  };

  useEffect(() => {
    // 路由变化时,若zE已存在则重新显示并初始化用户
    if (window.zE) {
      window.zE('messenger', 'show');
      initZendeskUser();
    }
  }, [pathname]);

  return (
    <Script
      id="ze-snippet"
      type="text/javascript"
      src={`https://static.zdassets.com/ekr/snippet.js?key=${process.env.NEXT_PUBLIC_ZENDESK_KEY}`}
      onReady={initZendeskUser}
      strategy="lazyOnload"
    />
  );
};

export default ZendeskWidget;

关键注意事项

  • 必须添加'use client'指令:App Router中组件默认是服务器组件,需转为客户端组件才能使用useEffect、usePathname等客户端API;
  • 不要移除Zendesk脚本:脚本卸载会导致Widget的DOM元素和全局状态丢失,后续无法快速恢复;
  • 监听路由变化:客户端导航不会触发全页刷新,需通过usePathname监听路由变更,主动触发Widget的重新初始化。

内容的提问来源于stack exchange,提问作者SteffenK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 16:52:08