next/script模块<Script>标签是否支持dangerouslySetInnerHTML及迁移方案
实现方案
首先在文件顶部导入next/script组件:
import Script from 'next/script'
你可以用以下两种写法实现和原代码完全等效的效果,推荐第一种更简洁的写法:
写法1:直接嵌套内联脚本(无需dangerouslySetInnerHTML)
Next.js 11+的Script组件支持直接将内联脚本作为子元素传入,不需要再用dangerouslySetInnerHTML,还可以根据加载时机需求指定strategy属性:
<Script id="gtm-init" strategy="beforeInteractive"> {`(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-******');`} </Script>
注意必须给内联脚本添加唯一的
id属性,这是Next.js要求的必填项,用于脚本追踪和去重。strategy参数可以根据实际需求调整:
beforeInteractive:在页面交互前加载,和你原来直接在HTML里写script标签的加载时机完全一致,适合GTM这类需要尽早初始化的统计脚本afterInteractive:页面可交互后加载,优先级稍低lazyOnload:浏览器空闲时加载,优先级最低
写法2:保留dangerouslySetInnerHTML的兼容写法
如果你不想改动原有脚本的结构,也可以直接把原来的script标签换成Script组件即可,其他代码不变:
<Script id="gtm-init" strategy="beforeInteractive" // eslint-disable-next-line react/no-danger 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-******');` }} />
两种写法的运行效果和原原生script标签完全一致,同时可以享受Next.js Script组件对核心网页指标的优化能力。
内容的提问来源于stack exchange,提问作者Mayank_MP5
相关产品推荐
相关产品推荐

