You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:15:43