NextJS13中rootLayout内的Script未加载到客户端页面问题
解决Next.js中Google Tag Manager脚本无法在客户端页面加载的问题
问题分析
你在rootLayout中使用dangerouslySetInnerHTML添加GTM脚本但客户端页面未加载成功,可能的原因包括:
- rootLayout默认是服务器组件,直接插入的脚本可能无法在客户端渲染流程中正确生效
- 你提供的代码片段存在标签未闭合、模板字符串不完整的语法错误
- GTM需要在客户端环境初始化,服务器组件中的脚本注入逻辑不符合其加载要求
解决方案1:使用Next.js官方next/script组件(推荐)
Next.js的next/script组件专门用于处理第三方脚本,会自动根据指定策略在客户端正确加载,无需手动处理dangerouslySetInnerHTML。
在rootLayout中添加以下代码:
import Script from 'next/script'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> {/* GTM核心脚本 - 交互后立即加载 */} <Script id="gtm-script" strategy="afterInteractive" dangerouslySetInnerHTML={{ __html: ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXXXXX'); `, }} /> {/* GTM noscript备用方案(针对禁用JS的场景) */} <noscript> <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style={{ display: 'none', visibility: 'hidden' }} /> </noscript> {children} </body> </html> ); }
strategy="afterInteractive":确保脚本在页面可交互后立即加载,适配GTM的用户行为跟踪需求- 替换
GTM-XXXXXXX为你的实际GTM容器ID
解决方案2:将GTM脚本封装到客户端组件中
如果需要更灵活的客户端控制,可以把GTM脚本放到标记为'use client'的组件中,再在rootLayout中引入:
- 创建
components/GTMScript.jsx:
'use client'; export default function GTMScript() { return ( <> <script dangerouslySetInnerHTML={{ __html: ` (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-XXXXXXX'); `, }} /> <noscript> <iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX" height="0" width="0" style={{ display: 'none', visibility: 'hidden' }} /> </noscript> </> ); }
- 在rootLayout中导入该组件:
import GTMScript from '@/components/GTMScript'; export default function RootLayout({ children }) { return ( <html lang="zh-CN"> <body> <GTMScript /> {children} </body> </html> ); }
额外检查项
- 确认GTM容器ID正确且容器已发布
- 检查浏览器控制台是否存在脚本加载错误(如网络问题、CORS限制)
- 修正代码中的语法错误(你提供的原始代码存在标签未闭合问题)
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

