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

Next.js中用Script组件在_head_插入Zoho跟踪代码遇阻求助

问题解答

1. 能否在_document.tsx的Head中添加Zoho跟踪代码?

可以,但你当前的写法存在问题——Next.js的<Script>组件在_document.tsx的<Head>中使用时,内联脚本的执行逻辑会受限。因为_document是服务端渲染的顶层文档组件,<Script>在这里的行为和普通页面组件里不一样,尤其是内联代码的加载时机与执行上下文,这也是你的代码被忽略但无报错的原因。

修复方案:改用原生<script>标签(在_document.tsx中)

在_document.tsx的<Head>里直接使用原生<script>标签替代<Script>组件,服务端生成HTML时会正确注入这段代码:

import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
  DocumentInitialProps,
} from "next/document";

class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }
  render() {
    return (
      <Html lang="en">
        <Head>
          {/* 原有meta与link标签保持不变 */}
          <meta charSet="utf-8" />
          <link
            href="https://fonts.googleapis.com/css?family=PT+Sans&display=optional"
            rel="stylesheet"
          />
          <meta name="msapplication-TileColor" content="#596285" />
          <meta
            name="msapplication-config"
            content="/favicon/browserconfig.xml"
          />
          <meta name="theme-color" content="#ffffff" />
          
          {/* Zoho营销自动化代码:改用原生script标签注入 */}
          <script 
            id="zoho-ma" 
            dangerouslySetInnerHTML={{ 
              __html: `
                var w = window;
                var p = w.location.protocol;
                if (p.indexOf("http") < 0) {
                  p = "http" + ":";
                }
                var d = document;
                var f = d.getElementsByTagName("script")[0],
                  s = d.createElement("script");
                s.type = "text/javascript";
                s.async = false;
                if (s.readyState) {
                  s.onreadystatechange = function () {
                    if (s.readyState == "loaded" || s.readyState == "complete") {
                      s.onreadystatechange = null;
                      try {
                        loadwaprops(
                          "myid#",
                          "myid#",
                          "myid#",
                          "myid#",
                          "0.0"
                        );
                      } catch (e) {}
                    }
                  };
                } else {
                  s.onload = function () {
                    try {
                      loadwaprops(
                        "myid#",
                        "myid#",
                        "myid#",
                        "myid#",
                        "0.0"
                      );
                    } catch (e) {}
                  };
                }
                s.src = p + "//ma.zoho.com/hub/js/WebsiteAutomation.js";
                f.parentNode.insertBefore(s, f);
              ` 
            }} 
          />
        </Head>
        <body>
          <Main />
          <NextScript />
          <div id="notifications"></div>
        </body>
      </Html>
    );
  }
}

export default MyDocument;

注:这里使用dangerouslySetInnerHTML是因为Next.js在_document中不允许直接在<script>标签内编写内联代码,必须通过该属性注入。

2. 是否更适合拆分为独立组件?

如果你的应用需要动态控制跟踪代码的加载(比如根据环境、用户权限决定是否加载),或者需要在部分页面禁用该代码,那么拆成独立组件更合适;如果只是全局所有页面都需要加载,直接在_document.tsx中用原生脚本的方案更简洁。

独立组件方案(适配Pages Router)

创建components/ZohoTracking.tsx:

import Script from "next/script";

export default function ZohoTracking() {
  return (
    <Script id="zoho-ma" strategy="beforeInteractive">
      {`
        var w = window;
        var p = w.location.protocol;
        if (p.indexOf("http") < 0) {
          p = "http" + ":";
        }
        var d = document;
        var f = d.getElementsByTagName("script")[0],
          s = d.createElement("script");
        s.type = "text/javascript";
        s.async = false;
        if (s.readyState) {
          s.onreadystatechange = function () {
            if (s.readyState == "loaded" || s.readyState == "complete") {
              s.onreadystatechange = null;
              try {
                loadwaprops(
                  "myid#",
                  "myid#",
                  "myid#",
                  "myid#",
                  "0.0"
                );
              } catch (e) {}
            }
          };
        } else {
          s.onload = function () {
            try {
              loadwaprops(
                "myid#",
                "myid#",
                "myid#",
                "myid#",
                "0.0"
              );
            } catch (e) {}
          };
        }
        s.src = p + "//ma.zoho.com/hub/js/WebsiteAutomation.js";
        f.parentNode.insertBefore(s, f);
      `}
    </Script>
  );
}

然后在_app.tsx中全局引入:

import type { AppProps } from "next/app";
import ZohoTracking from "../components/ZohoTracking";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <ZohoTracking />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

这里使用strategy="beforeInteractive"确保脚本在页面交互前加载,和_document中的加载时机一致,同时<Script>组件在_app.tsx中的执行逻辑符合预期。

关键注意事项

  • _document.tsx中优先用原生<script>处理全局跟踪代码,避免<Script>组件的上下文限制;
  • 若使用独立组件,需放在_app.tsx而非_document.tsx中,_app是页面级顶层组件,<Script>组件在这里的行为更可控;
  • 记得将loadwaprops中的myid#替换为你的实际Zoho营销自动化ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:25:27