Next.js中_app.js与_document.js的区别及静态资源引入位置咨询
Next.js 中 _app.js 与 _document.js 的区别及资源引入指南
一、_app.js 与 _document.js 的核心区别
_app.js
- 是所有页面的共享顶层组件,客户端和服务端渲染时都会执行
- 负责全局层面的逻辑:比如全局状态管理(Redux/Context)、路由切换处理、公共布局复用、页面加载状态控制
- 直接参与页面的客户端 hydration(水合)过程,能和客户端交互逻辑联动
_document.js
- 仅在服务端渲染阶段运行,客户端不会执行它的代码
- 作用是自定义 Next.js 生成的根 HTML 文档结构:比如修改
<html>/<body>标签属性、添加全局 meta 信息、注入底层 HTML 级别的脚本 - 不参与页面组件的渲染流程,不能在这里处理客户端交互逻辑
二、CSS、JS 文件的引入规范
CSS 文件
- 全局 CSS(模板主样式、第三方框架 CSS):必须在
_app.js中引入。因为_document.js不参与客户端样式渲染,在这里引入会导致样式不生效或 hydration 错误 - 组件级模块化 CSS:直接在对应的业务组件中引入即可,无需放到这两个全局文件里
JS 文件
- 全局客户端交互脚本(模板的菜单/轮播逻辑、全局工具函数):在
_app.js中引入,或者在需要的组件中按需引入。如果是需要全局初始化的逻辑(比如全局事件监听),可以放在_app.js的useEffect钩子中执行 - 服务端专属脚本:如果有仅在服务端运行的逻辑,可在
_document.js中处理,但注意不要写入客户端会执行的代码 - 第三方脚本(统计、广告等):
- 若无需客户端交互、需页面加载时立即执行,可在
_document.js的<head>或<body>中用<script>标签引入(建议加async/defer属性) - 若需要和客户端组件交互,必须放到
_app.js中引入
- 若无需客户端交互、需页面加载时立即执行,可在
示例代码
在 _app.js 中引入全局资源
// pages/_app.js import '../styles/template-global.css'; // 模板全局样式 import '../scripts/template-main.js'; // 模板全局交互脚本 export default function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; }
在 _document.js 中自定义 HTML 结构
// pages/_document.js import Document, { Html, Head, Main, NextScript } from 'next/document'; class MyDocument extends Document { render() { return ( <Html lang="zh-CN"> <Head> <meta name="keywords" content="Next.js,HTML模板" /> {/* 注入服务端加载的第三方统计脚本 */} <script src="/scripts/analytics.js" async /> </Head> <body> <Main /> <NextScript /> </body> </Html> ); } } export default MyDocument;
内容的提问来源于stack exchange,提问作者amit
相关产品推荐
相关产品推荐

