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

Next.js中页面切换时<Script />标签无法加载,仅页面刷新才生效的问题求助

Next.js中页面切换时
return (<Script />)
标签无法加载,仅页面刷新才生效的问题求助

各位大佬好,我最近在Next.js项目里碰到个头疼的问题,想请教下大家:

我做了个加载第三方祈祷时间小部件的组件,用了Next.js自带的<Script />标签。但发现用Next Link跳去别的页面再返回时,小部件根本没加载出来,反而直接显示了链接https://masjidbox.com/prayer-times/bpjm,只有手动刷新页面,小部件才会正常显示。

下面是我目前的组件代码(部分内容未写完):

"use client";
import { useRef } from "react";
import Script from "next/script";

const MasjidboxWidget: React.FC = () => {
  const widgetContainerRef = useRef<HTMLDivElement>(null);
  
  // 后续渲染逻辑省略
  return (
    <div ref={widgetContainerRef}>
      <Script src="https://masjidbox.com/widget/prayer-times/bpjm" />
    </div>
  );
};

export default MasjidboxWidget;

问题原因

这是因为Next.js的客户端路由切换时,不会重新加载整个文档,而<Script />标签默认的加载策略不会在组件重新挂载时重新执行脚本,导致小部件无法再次初始化。

可行解决方案

方案1:用useEffect手动控制脚本加载卸载

既然是客户端组件,我们可以用useEffect在组件挂载时手动插入脚本,卸载时移除,这样每次组件回来都会重新加载脚本:

"use client";
import { useRef, useEffect } from "react";

const MasjidboxWidget: React.FC = () => {
  const widgetContainerRef = useRef<HTMLDivElement>(null);
  const scriptRef = useRef<HTMLScriptElement | null>(null);

  useEffect(() => {
    if (!widgetContainerRef.current) return;

    // 创建新的脚本元素
    const script = document.createElement('script');
    script.src = "https://masjidbox.com/widget/prayer-times/bpjm";
    script.async = true;
    script.onload = () => {
      console.log("小部件脚本加载完成");
    };

    // 把脚本插到容器里
    widgetContainerRef.current.appendChild(script);
    scriptRef.current = script;

    // 组件卸载时移除脚本,避免重复加载
    return () => {
      if (scriptRef.current && widgetContainerRef.current) {
        widgetContainerRef.current.removeChild(scriptRef.current);
        scriptRef.current = null;
      }
    };
  }, []);

  return <div ref={widgetContainerRef}></div>;
};

export default MasjidboxWidget;

方案2:给Script标签加key强制重新渲染

利用Next.js的key机制,给<Script />标签加一个和当前路由绑定的key,这样路由变化(返回页面)时,key改变,Next.js会重新渲染这个脚本标签:

"use client";
import { useRef } from "react";
import Script from "next/script";
import { usePathname } from "next/navigation";

const MasjidboxWidget: React.FC = () => {
  const widgetContainerRef = useRef<HTMLDivElement>(null);
  const pathname = usePathname(); // 获取当前路由路径

  return (
    <div ref={widgetContainerRef}>
      <Script
        key={pathname} // 路由变了key就变,脚本重新加载
        src="https://masjidbox.com/widget/prayer-times/bpjm"
        strategy="afterInteractive"
        onLoad={() => {
          // 如果小部件需要手动初始化,这里可以加初始化逻辑
        }}
      />
    </div>
  );
};

export default MasjidboxWidget;

额外提醒

如果第三方脚本本身会检测是否已加载过,就算重新插入也不执行的话,记得在清理函数里把脚本创建的全局变量或者DOM元素删掉,确保下次能重新初始化。也可以看看第三方小部件的文档,有没有提供手动初始化的API,那样会更靠谱。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:55:32