在React应用中插入百度推广代码

在React应用中添加百度推广(百度统计)代码需要注意React的单页应用(SPA)特性,确保代码能正确加载并跟踪页面浏览。以下是几种实现方法:

方法一:直接在public/index.html中添加

打开 public/index.html文件

在 标签内添加百度统计代码:

<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?你的站点ID";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

方法二:使用React组件方式添加

1. 创建BaiduAnalytics组件

// src/components/BaiduAnalytics.js
import { useEffect } from 'react';

const BaiduAnalytics = () => {
  useEffect(() => {
    // 确保代码只在客户端执行
    if (typeof window !== 'undefined') {
      var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?你的站点ID";
        var s = document.getElementsByTagName("script")[0]; 
        s.parentNode.insertBefore(hm, s);
      })();
    }
  }, []);

  return null; // 这个组件不渲染任何内容
};

export default BaiduAnalytics;

2. 在App.js中使用该组件

import BaiduAnalytics from './components/BaiduAnalytics';

function App() {
  return (
    <>
      <BaiduAnalytics />
      {/* 其他应用内容 */}
    </>
  );
}

方法三:使用React Helmet (推荐)

1. 安装react-helmet

npm install react-helmet
# 或
yarn add react-helmet

2. 创建Helmet组件

// src/components/BaiduAnalyticsHelmet.js
import { Helmet } from 'react-helmet';

const BaiduAnalyticsHelmet = () => {
  return (
    <Helmet>
      <script>
        {`
          var _hmt = _hmt || [];
          (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?你的站点ID";
            var s = document.getElementsByTagName("script")[0]; 
            s.parentNode.insertBefore(hm, s);
          })();
        `}
      </script>
    </Helmet>
  );
};

export default BaiduAnalyticsHelmet;

3. 在App.js中使用

import BaiduAnalyticsHelmet from './components/BaiduAnalyticsHelmet';

function App() {
  return (
    <>
      <BaiduAnalyticsHelmet />
      {/* 其他应用内容 */}
    </>
  );
}

跟踪单页应用(SPA)的页面浏览

由于React是单页应用,需要手动发送页面浏览事件给百度统计:

// 在路由变化时调用
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

const TrackPageView = () => {
  const location = useLocation();

  useEffect(() => {
    // 确保代码只在客户端执行
    if (typeof window !== 'undefined' && window._hmt) {
      window._hmt.push(['_trackPageview', location.pathname]);
    }
  }, [location]);

  return null;
};

// 在App.js中使用
function App() {
  return (
    <>
      <BaiduAnalytics />
      <TrackPageView />
      {/* 其他应用内容 */}
    </>
  );
}

注意事项

​​站点ID​​:替换代码中的"你的站点ID"为百度统计提供的实际ID

​​生产环境​​:确保只在生产环境加载统计代码

​​隐私合规​​:根据当地法规(如GDPR)可能需要添加用户同意机制

​​性能影响​​:统计代码可能会轻微影响页面加载性能

​​开发环境​​:可以在开发环境禁用统计代码以避免干扰测试数据

完整示例(推荐方案)

// src/components/BaiduTracker.js
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

const BaiduTracker = () => {
  const location = useLocation();

  useEffect(() => {
    if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
      // 加载百度统计脚本
      if (!window._hmt) {
        window._hmt = [];
        const hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?你的站点ID";
        const s = document.getElementsByTagName("script")[0]; 
        s.parentNode.insertBefore(hm, s);
      }

      // 发送页面浏览事件
      if (window._hmt) {
        window._hmt.push(['_trackPageview', location.pathname]);
      }
    }
  }, [location]);

  return null;
};

export default BaiduTracker;

然后在你的App.js中:

import BaiduTracker from './components/BaiduTracker';

function App() {
  return (
    <>
      <BaiduTracker />
      {/* 其他应用内容 */}
    </>
  );
}

这种方法会自动处理脚本加载和页面浏览跟踪,并且只在生产环境生效。

解决 "s.parentNode 可能为 null" 的问题

在添加百度统计代码时遇到的 s.parentNode可能为 null 的错误,是因为脚本注入的逻辑在某些情况下可能找不到参考节点。以下是几种解决方案:

原因分析

当 document.getElementsByTagName("script")[0]返回 undefined 时(页面中没有任何 script 标签),s变量会是 undefined,导致 s.parentNode报错。

解决方案

方案1:使用更可靠的DOM节点作为参考

(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?你的站点ID";

  // 使用document.head或document.body作为插入点
  var firstScript = document.getElementsByTagName("script")[0];
  var insertPoint = firstScript || document.head || document.body;

  insertPoint.parentNode.insertBefore(hm, insertPoint);
})();

方案2:直接追加到head或body

(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?你的站点ID";

  // 直接追加到head(推荐)
  (document.head || document.body).appendChild(hm);
})();

方案3:使用document.write(传统方式)

document.write(`
  <script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?你的站点ID";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>
`);

React中的完整解决方案(推荐)

import { useEffect } from 'react';

const BaiduAnalytics = () => {
  useEffect(() => {
    if (typeof window === 'undefined') return; // 服务端渲染时不执行

    // 更安全的插入方式
    const injectBaiduAnalytics = () => {
      if (window._hmt) return; // 防止重复加载

      window._hmt = [];
      const script = document.createElement('script');
      script.src = 'https://hm.baidu.com/hm.js?你的站点ID';

      // 优先插入head,其次body
      const container = document.head || document.body;
      if (container) {
        container.appendChild(script);
      } else {
        // 极端情况下,等待DOM加载完成
        document.addEventListener('DOMContentLoaded', () => {
          (document.head || document.body).appendChild(script);
        });
      }
    };

    injectBaiduAnalytics();
  }, []);

  return null;
};

export default BaiduAnalytics;