如何在Next.js中移除DOM内的__NEXT_DATA__元素?
针对Next.js SSR+动态路由场景移除__NEXT_DATA__的可行方案
__NEXT_DATA__是Next.js默认注入的服务端预取数据,用于客户端水合,直接移除会导致水合失败,需要搭配配套逻辑处理,以下是可落地的操作方案:
方案1:关闭不必要的预取数据注入(适合无客户端交互的纯静态展示页)
如果对应的页面完全不需要客户端交互、没有事件绑定,可以直接在页面组件导出配置关闭JS runtime注入,框架会自动省略__NEXT_DATA__输出:
- Next.js 12及之前的Pages Router版本,在页面组件中添加如下配置:
export const config = { unstable_runtimeJS: false }
- Next.js 13+ App Router版本,给页面组件添加
'use server'指令,同时设置该路由段为静态导出、不引入任何客户端组件即可。
方案2:自定义Document改造,手动移除__NEXT_DATA__(适合保留部分客户端交互的场景)
如果需要保留部分客户端交互,不能完全禁用JS,可以通过自定义入口文件过滤掉__NEXT_DATA__脚本标签,Pages Router示例代码如下:
// pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document' class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx) // 过滤__NEXT_DATA__相关内容 const filteredHtml = initialProps.html.replace(/<script id="__NEXT_DATA__"[^>]*>[\s\S]*?<\/script>/, '') return { ...initialProps, html: filteredHtml } } render() { return ( <Html> <Head /> <body> <Main /> <NextScript /> </body> </Html> ) } } export default MyDocument
注意:使用该方案前需要自行处理客户端水合需要的数据,比如通过接口按需拉取动态路由对应的参数和页面数据,否则会出现水合不匹配报错。
方案3:拆分预取数据降低体积(不需要完全移除的轻量化优化方案)
如果不需要完全移除__NEXT_DATA__,只是要降低DOM体积,可以在getServerSideProps(Pages Router)或者服务端组件的异步请求中,仅返回客户端水合必须的字段,过滤掉冗余的大体积数据,比如列表页不需要返回全量内容字段,仅返回分页参数、ID即可,详情内容可以客户端按需拉取。
以上方案均适配动态路由场景,动态路由参数可以通过
ctx.params或者路由上下文获取,不需要依赖__NEXT_DATA__传递。
内容的提问来源于stack exchange,提问作者Archana Agivale
相关产品推荐
相关产品推荐

