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

在React项目中添加Heap Analytics代码遇报错求助

解决React中Heap Analytics脚本“heap is not defined”的问题

Hey,我之前也碰到过类似的问题,Heap这个脚本的坑确实容易踩,尤其是在React这种单页应用里。咱们一步步来解决这个报错:

为什么会出现“heap is not defined”?

核心原因有两个:

  • Heap的脚本还没加载完成,你的代码就提前尝试调用了heap全局对象
  • 脚本没有正确挂载到<head>中,导致全局对象没有被初始化

而GTM、FB像素能正常运行,大概率是因为它们的脚本加载逻辑更“容错”,或者你调用它们的时机刚好在脚本加载完成之后。

具体解决方法

方法1:直接修改public/index.html的标签(最推荐)

这是Heap官方推荐的方式,直接把脚本放到根HTML的<head>里,确保页面加载时优先加载它:
打开你的React项目根目录下的public/index.html,在<head>标签内插入Heap的官方脚本:

<head>
  <!-- 其他head内容 -->
  <script type="text/javascript">
    window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])};
    // 替换成你的Heap App ID
    heap.load("YOUR_HEAP_APP_ID");
  </script>
</head>

这样页面一加载就会初始化window.heap对象,之后在React组件里直接调用window.heap.track()之类的方法就不会报错了。

方法2:用React的useEffect动态加载脚本(适合动态控制场景)

如果需要根据环境(比如只在生产环境加载)或者组件条件加载脚本,可以用useEffect在组件挂载时动态插入脚本到<head>:

import { useEffect } from 'react';

function App() {
  useEffect(() => {
    // 只在生产环境加载(可选)
    if (process.env.NODE_ENV !== 'production') return;

    const heapScript = document.createElement('script');
    heapScript.type = 'text/javascript';
    heapScript.async = true;
    // 脚本内容可以直接写,或者加载外部CDN
    heapScript.textContent = `
      window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])};
      heap.load("YOUR_HEAP_APP_ID");
    `;

    document.head.appendChild(heapScript);

    // 组件卸载时移除脚本(可选,避免内存泄漏)
    return () => {
      document.head.removeChild(heapScript);
    };
  }, []);

  // 在组件中调用Heap方法时,先检查window.heap是否存在
  const trackButtonClick = () => {
    if (window.heap) {
      window.heap.track('Button Clicked', { buttonName: 'Submit' });
    }
  };

  return (
    <div>
      <button onClick={trackButtonClick}>Submit</button>
    </div>
  );
}

export default App;

方法3:封装工具函数避免报错

不管用哪种加载方式,都建议封装一个工具函数来调用Heap的方法,确保全局对象存在时才执行:

// utils/heap.js
export const trackHeapEvent = (eventName, properties = {}) => {
  // 检查是否在浏览器环境,且heap已初始化
  if (typeof window !== 'undefined' && window.heap) {
    window.heap.track(eventName, properties);
  }
};

export const identifyUser = (userId) => {
  if (typeof window !== 'undefined' && window.heap) {
    window.heap.identify(userId);
  }
};

然后在组件里直接导入使用:

import { trackHeapEvent } from './utils/heap';

function MyComponent() {
  const handleClick = () => {
    trackHeapEvent('My Component Click');
  };

  return <button onClick={handleClick}>Click Me</button>;
}

额外注意事项

  • 不要省略window.前缀直接写heap,React的编译环境(比如Webpack)会把heap当作局部变量处理,导致报错
  • 如果用的是Next.js这类SSR框架,一定要加上typeof window !== 'undefined'的检查,避免服务器端渲染时找不到window对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:45:05