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

Next.js 13.5:Script组件条件渲染与src条件赋值的差异原因咨询

问题场景

我正在使用Next.js 13.5,希望仅在生产环境中加载Google Recaptcha脚本。尝试了两种实现方式,第一种条件渲染<Script>组件不生效,第二种条件设置src属性却能正常工作,想了解两种写法的差异,以及该问题是否由Next.js框架导致。

第一种写法(不生效)

// _document.js, doesn't work
const isProduction = process.env.NODE_ENV === "production";
const nonce = "1234-abcd-wxyz";
// ...
<Html lang="en">
  <Head nonce={nonce}>
    {isProduction && <Script
      async
      defer
      strategy="afterInteractive"
      src={`https://www.google.com/recaptcha/api.js?render=${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""}`}
    />}
  </Head>
</Html>

第二种写法(生效)

// _document.js, working
const isProduction = process.env.NODE_ENV === "production";
const nonce = "1234-abcd-wxyz";
// ...
<Html lang="en">
  <Head nonce={nonce}>
    <Script
      async
      defer
      strategy="afterInteractive"
      src={isProduction ? `https://www.google.com/recaptcha/api.js?render=${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""}` : ""}
    />
  </Head>
</Html>
问题解答

两种写法的核心差异

  1. 组件渲染逻辑与框架处理链路不同

    • 第一种是条件渲染<Script>组件本身:在_document.js的服务器端渲染(SSR)阶段,isProduction的判断会决定是否生成<Script>组件的渲染记录。但Next.js的<Script>组件在_document.js中不会直接输出为HTML标签,而是被框架收集后,在客户端 hydration 阶段统一处理加载逻辑。如果SSR阶段不渲染组件,客户端就没有对应的加载任务,自然无法加载脚本。
    • 第二种是始终渲染组件,动态设置src属性:<Script>组件会被框架正常收集,客户端 hydration 时会读取src的实际值。当isProduction为真时,src是有效的脚本地址,框架触发加载;为假时src为空,脚本不会加载,完全符合需求。
  2. Next.js对<Script>组件的封装特性
    Next.js的<Script>是优化后的封装组件,和原生<script>标签的处理逻辑不同。它会根据指定的strategy控制加载时机,同时处理nonce、CSP等安全配置。在_document.js这类SSR入口文件中,组件的渲染结果不会直接写入HTML,而是由框架在客户端后续执行加载流程,这就导致条件渲染组件的方式无法传递加载指令到客户端。

是否由Next.js框架导致?

是的,这个差异完全由Next.js对<Script>组件的特殊处理逻辑导致。原生HTML中条件渲染<script>标签是可行的,但Next.js的<Script>组件依赖框架的客户端加载调度机制,而非直接的SSR输出。因此在_document.js中,条件渲染组件的方式无法触发脚本加载,而动态设置src的方式能让框架正常处理加载判断。

内容的提问来源于stack exchange,提问作者Aung Kaung Khant - Takao

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:20