Next.js中document.js如何条件性动态添加script脚本
Next.js 自定义文档(_document.js)脚本加载方案
动态添加脚本的基础写法
_document.js 是Next.js应用的HTML文档入口,仅在服务端渲染阶段执行一次,不会响应客户端的状态更新。在该文件中添加脚本不需要特殊API,直接在<Head>组件内,或<body>标签中<NextScript />组件的前后位置写入<script>标签即可,脚本的src地址、内联内容、属性都可以在服务端渲染阶段动态拼接生成。
如果是Next.js 11及以上版本,也可以在_document.js中使用next/script组件配置脚本加载优先级,但注意客户端动态更新的逻辑不要放在这里,_document.js的渲染内容只会在首屏HTML生成时生效。
无默认props场景下的条件脚本实现
默认导出的Document组件不会自动接收业务侧props,但可以通过Document组件提供的静态getInitialProps方法,拿到SSR阶段的全量上下文,包括请求对象、当前路由、环境变量、自定义配置等,将条件判断需要的字段通过getInitialProps返回值传递给Document组件,即可实现脚本的条件性加载。
常用的判断维度包括:
- 部署环境(生产/测试/开发环境区分加载脚本)
- 当前请求的路径、域名、请求头参数
- 页面对应组件挂载的自定义静态属性
- 构建时注入的环境变量、灰度开关配置
完整实现代码
import { Html, Head, Main, NextScript } from 'next/document' export default function Document(props) { const { isProduction, needLoadAdScript } = props.customDocProps return ( <Html> <Head> {/* 动态注入全局变量示例 */} <script dangerouslySetInnerHTML={{ __html: `window.RUNTIME_ENV = "${process.env.NODE_ENV}"` }} /> {/* 条件加载:仅生产环境加载埋点统计脚本 */} {isProduction && ( <script src="https://statics.example.com/analytics.js" async /> )} </Head> <body> <Main /> {/* 条件加载:仅广告落地页在核心脚本前加载广告依赖 */} {needLoadAdScript && <script src="/static/ad-helper.js" />} <NextScript /> </body> </Html> ) } // 注入上下文判断逻辑 Document.getInitialProps = async (ctx) => { const initialProps = await ctx.defaultGetInitialProps(ctx) const isProduction = process.env.NODE_ENV === 'production' // 根据当前路由判断是否需要加载广告脚本 const needLoadAdScript = ctx.pathname.startsWith('/landing/ad-') return { ...initialProps, customDocProps: { isProduction, needLoadAdScript } } }
注意:
getInitialProps内的逻辑会阻塞文档HTML的返回,不要在其中执行耗时超过100ms的接口请求,避免拖慢首屏加载速度。非首屏强依赖的脚本,建议放到_app.js或具体业务页面中使用next/script加载,灵活度更高。
内容的提问来源于stack exchange,提问作者ali marefati
相关产品推荐
相关产品推荐

