React中如何在index.html中按页面路径添加加载条件
解决React index.html中仅在注册页面加载GTM脚本的问题
问题原因
你在index.html中用<% if (window.location.pathname === '/signup') { %>报错,是因为模板引擎的<% %>代码是在构建/服务器渲染阶段执行的,这时候还没有浏览器环境,window对象还未创建,自然会提示“window not defined”。
可行解决方案
方案1:在index.html的客户端脚本中动态判断加载
把路径判断逻辑放到浏览器端执行的脚本里,等DOM加载完成后再检查路径,符合条件才插入GTM脚本:
<% if (process.env.NODE_ENV === 'production') { %> <script> document.addEventListener('DOMContentLoaded', function() { // 仅在注册页面加载GTM if (window.location.pathname === '/signup') { // 创建并插入GTM脚本 const gtmScript = document.createElement('script'); gtmScript.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXX'; gtmScript.async = true; document.head.appendChild(gtmScript); // 插入noscript备用代码(可选) const gtmNoscript = document.createElement('noscript'); gtmNoscript.innerHTML = '<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe>'; document.body.appendChild(gtmNoscript); } }); </script> <% } %>
方案2:在Signup组件内加载(推荐)
更符合React组件化思路,直接在注册页面的组件中通过useEffect动态加载GTM,避免在index.html中混杂逻辑:
import { useEffect } from 'react'; function Signup() { useEffect(() => { // 非生产环境直接返回 if (process.env.NODE_ENV !== 'production') return; // 避免重复加载GTM脚本 if (document.querySelector('script[src*="googletagmanager.com/gtm.js"]')) return; // 加载GTM主脚本 const gtmScript = document.createElement('script'); gtmScript.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXX'; gtmScript.async = true; document.head.appendChild(gtmScript); // 添加noscript备用代码 const gtmNoscript = document.createElement('noscript'); gtmNoscript.innerHTML = '<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe>'; document.body.appendChild(gtmNoscript); // 页面卸载时清理脚本(可选) return () => { gtmScript.remove(); gtmNoscript.remove(); }; }, []); return ( <div className="signup-page"> {/* 注册页面内容 */} </div> ); } export default Signup;
关键说明
- 模板引擎的代码运行在服务端/构建阶段,无法访问浏览器的
window对象,必须将路径判断逻辑延迟到客户端执行。 - 组件内加载的方式更灵活,能精准控制仅在注册页面加载,还能避免路由切换时重复加载脚本。
内容的提问来源于stack exchange,提问作者Haris George
相关产品推荐
相关产品推荐

