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

NextJS中如何将变量传递到前端脚本?

解决Next.js中Script组件无法获取用户邮箱的问题

问题分析

你的代码里userEmail在组件外部和<title>标签中正常生效,但在Script组件的dangerouslySetInnerHTML里失效,核心原因大概率是这两点:

  • 异步状态未同步:如果useEmail()是异步获取数据(比如从认证库、后端API请求),组件初始渲染时userEmail可能是undefined或null,而Script组件的执行时机可能早于数据加载完成的时间。
  • 脚本语法转义问题:如果邮箱包含特殊字符(比如单引号'),直接用模板字符串拼接会破坏脚本语法,导致代码无法正常执行。

解决方案

方案1:条件渲染+字符转义+指定执行策略

确保userEmail有有效值时才渲染脚本,同时转义特殊字符并指定客户端执行策略:

const userEmail = useEmail();

console.log({userEmail});

return (
  <Layout>
    <Head>
      <title key="title">
        Onboarding {userEmail}| {configuration.site.siteName}
      </title>
    </Head>
    {userEmail && (
      <Script
        id="gr-event"
        strategy="afterInteractive" // 确保客户端交互后执行,适配异步数据
        dangerouslySetInnerHTML={{
          __html: `console.log('${userEmail.replace(/'/g, "\\'")}')`, // 转义单引号避免语法错误
        }}
      />
    )}
  </Layout>
);

方案2:用useEffect动态注入脚本

通过useEffect监听userEmail的变化,当数据就绪后再创建并插入脚本,彻底规避执行时机问题:

import { useEffect, useRef } from 'react';

const userEmail = useEmail();
const scriptRef = useRef(null);

useEffect(() => {
  if (!userEmail) return;

  // 移除已存在的脚本,避免重复执行
  if (scriptRef.current) {
    scriptRef.current.remove();
  }

  // 动态创建脚本
  const script = document.createElement('script');
  script.id = 'gr-event';
  script.textContent = `console.log('${userEmail.replace(/'/g, "\\'")}')`;
  document.body.appendChild(script);
  scriptRef.current = script;

  // 组件卸载时清理脚本
  return () => script.remove();
}, [userEmail]); // 监听userEmail的状态变化

return (
  <Layout>
    <Head>
      <title key="title">
        Onboarding {userEmail}| {configuration.site.siteName}
      </title>
    </Head>
  </Layout>
);

方案3:全局变量传递数据(适配支持全局变量的追踪脚本)

如果你的转化追踪脚本允许读取全局变量,可以先把userEmail挂载到全局,再在脚本中读取:

import { useEffect } from 'react';

const userEmail = useEmail();

useEffect(() => {
  if (userEmail) {
    window.trackingUserEmail = userEmail; // 将邮箱挂载到全局对象
  }
}, [userEmail]);

return (
  <Layout>
    <Head>
      <title key="title">
        Onboarding {userEmail}| {configuration.site.siteName}
      </title>
    </Head>
    <Script
      id="gr-event"
      strategy="afterInteractive"
      dangerouslySetInnerHTML={{
        __html: `console.log(window.trackingUserEmail)`,
      }}
    />
  </Layout>
);

关键注意事项

  • 必须转义特殊字符:邮箱中的单引号、反斜杠等字符会破坏脚本语法,用replace(/'/g, "\\'")处理单引号是基础操作。
  • 合理选择Script策略:afterInteractive适合需要用户交互后执行的追踪脚本,lazyOnload适合非关键脚本,确保脚本在数据就绪后运行。
  • 异步状态必须处理:如果useEmail()是异步获取数据,一定要通过条件渲染或useEffect监听状态变化,避免在数据未加载时执行脚本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 12:42:50