本页面概述了 Next.js 中所有文件夹和文件约定,并提供了组织项目的建议。
顶层文件夹用于组织应用程序的代码和静态资源。

app | App 路由器 |
pages | Pages 路由器 |
public | 要提供的静态资源 |
src | 可选的应用程序源文件夹 |
顶层文件用于配置应用程序、管理依赖项、运行代理、集成监控工具以及定义环境变量。
| Next.js | |
next.config.js | Next.js 配置文件 |
package.json | 项目依赖项和脚本 |
instrumentation.ts | OpenTelemetry 和 Instrumentation 文件 |
proxy.ts | Next.js 请求代理 |
.env | 环境变量 |
.env.local | 本地环境变量 |
.env.production | 生产环境变量 |
.env.development | 开发环境变量 |
eslint.config.mjs | ESLint 配置文件 |
.gitignore | Git 忽略文件和文件夹 |
next-env.d.ts | Next.js 的 TypeScript 声明文件 |
tsconfig.json | TypeScript 配置文件 |
jsconfig.json | JavaScript 配置文件 |
添加 page 以暴露路由,layout 用于共享 UI(如页眉、导航或页脚),loading 用于骨架屏,error 用于错误边界,route 用于 API。
layout | .js .jsx .tsx | 布局 |
page | .js .jsx .tsx | 页面 |
loading | .js .jsx .tsx | 加载 UI |
not-found | .js .jsx .tsx | 未找到 UI |
error | .js .jsx .tsx | 错误 UI |
global-error | .js .jsx .tsx | 全局错误 UI |
route | .js .ts | API 端点 |
template | .js .jsx .tsx | 重新渲染的布局 |
default | .js .jsx .tsx | 并行路由回退页面 |
文件夹定义 URL 段。嵌套文件夹会嵌套段。任何层级的布局都会包裹其子段。当存在 page 或 route 文件时,路由会变为公共可访问。
| Path | URL pattern | Notes |
|---|---|---|
app/layout.tsx | — | 根布局包裹所有路由 |
app/blog/layout.tsx | — | 包裹 /blog 及其后代 |
app/page.tsx | / | 公共路由 |
app/blog/page.tsx | /blog | 公共路由 |
app/blog/authors/page.tsx | /blog/authors | 公共路由 |
使用方括号参数化段。[segment] 用于单个参数,[...segment] 用于捕获所有参数,[[...segment]] 用于可选捕获所有参数。通过 params 属性访问值。
| Path | URL pattern |
|---|---|
app/blog/[slug]/page.tsx | /blog/my-first-post |
app/shop/[...slug]/page.tsx | /shop/clothing, /shop/clothing/shirts |
app/docs/[[...slug]]/page.tsx | /docs, /zh-cn/docs/next.js/latest/layouts-and-pages, /zh-cn/docs/next.js/latest/api-reference/use-router |
使用路由组 (group) 组织代码而不改变 URL,并使用私有文件夹 _folder 协同放置不可路由的文件。
| Path | URL pattern | Notes |
|---|---|---|
app/(marketing)/page.tsx | / | 组从 URL 中省略 |
app/(shop)/cart/page.tsx | /cart | 在 (shop) 中共享布局 |
app/blog/_components/Post.tsx | — | 不可路由;UI 工具的安全位置 |
app/blog/_lib/data.ts | — | 不可路由;工具的安全位置 |
这些功能适用于特定的 UI 模式,例如基于插槽的布局或模态路由。
使用 @slot 表示由父布局渲染的命名插槽。使用拦截模式在当前布局中渲染另一个路由而不改变 URL,例如,将详细视图作为模态框显示在列表上方。
| Pattern (docs) | Meaning | Typical use case |
|---|---|---|
@folder | 命名插槽 | 侧边栏 + 主内容 |
(.)folder | 拦截同级 | 在模态框中预览同级路由 |
(..)folder | 拦截父级 | 将父级的子项作为叠加层打开 |
(..)(..)folder | 拦截两级 | 深层嵌套叠加层 |
(...)folder | 从根目录拦截 | 在当前视图中显示任意路由 |
favicon | .ico | Favicon 文件 |
icon | .ico .jpg .jpeg .png .svg | 应用程序图标文件 |
icon | .js .ts .tsx | 生成的应用程序图标 |
apple-icon | .jpg .jpeg, .png | Apple 应用程序图标文件 |
apple-icon | .js .ts .tsx | 生成的 Apple 应用程序图标 |
opengraph-image | .jpg .jpeg .png .gif | Open Graph 图片文件 |
opengraph-image | .js .ts .tsx | 生成的 Open Graph 图片 |
twitter-image | .jpg .jpeg .png .gif | Twitter 图片文件 |
twitter-image | .js .ts .tsx | 生成的 Twitter 图片 |
sitemap | .xml | Sitemap 文件 |
sitemap | .js .ts | 生成的 Sitemap |
robots | .txt | Robots 文件 |
robots | .js .ts | 生成的 Robots 文件 |
_app | .js .jsx .tsx | 自定义 App |
_document | .js .jsx .tsx | 自定义 Document |
_error | .js .jsx .tsx | 自定义错误页面 |
404 | .js .jsx .tsx | 404 错误页面 |
500 | .js .jsx .tsx | 500 错误页面 |
| 文件夹约定 | ||
index | .js .jsx .tsx | 主页 |
folder/index | .js .jsx .tsx | 嵌套页面 |
| 文件约定 | ||
index | .js .jsx .tsx | 主页 |
file | .js .jsx .tsx | 嵌套页面 |
| 文件夹约定 | ||
[folder]/index | .js .jsx .tsx | 动态路由段 |
[...folder]/index | .js .jsx .tsx | 捕获所有路由段 |
[[...folder]]/index | .js .jsx .tsx | 可选捕获所有路由段 |
| 文件约定 | ||
[file] | .js .jsx .tsx | 动态路由段 |
[...file] | .js .jsx .tsx | 捕获所有路由段 |
[[...file]] | .js .jsx .tsx | 可选捕获所有路由段 |
Next.js 对您如何组织和协同放置项目文件没有强制性意见。但它确实提供了多种功能来帮助您组织项目。
特殊文件中定义的组件以特定的层级渲染:
layout.jstemplate.jserror.js (React 错误边界)loading.js (React Suspense 边界)not-found.js (用于“未找到”UI 的 React 错误边界)page.js 或嵌套 layout.js

组件在嵌套路由中递归渲染,这意味着路由段的组件将嵌套在其父段的组件内部。


在 app 目录中,嵌套文件夹定义了路由结构。每个文件夹代表一个路由段,该路由段映射到 URL 路径中的相应段。
然而,即使路由结构是通过文件夹定义的,但在向路由段添加 page.js 或 route.js 文件之前,路由不会公开可访问。


而且,即使路由已公开可访问,也只有 page.js 或 route.js 返回的内容会发送到客户端。


这意味着项目文件可以安全地协同放置在 app 目录的路由段内,而不会意外地变得可路由。


须知:虽然您可以将项目文件协同放置在
app中,但您不必这样做。如果您愿意,可以将它们保留在app目录之外。
私有文件夹可以通过在文件夹名称前添加下划线来创建:_folderName
这表示该文件夹是一个私有实现细节,不应被路由系统考虑,从而将该文件夹及其所有子文件夹排除在路由之外。


由于 app 目录中的文件默认可以安全地协同放置,因此协同放置不需要私有文件夹。但是,它们对于以下方面很有用:
须知:
- 虽然这不是一个框架约定,但您也可以考虑使用相同的下划线模式将私有文件夹之外的文件标记为“私有”。
- 您可以通过在文件夹名称前添加
%5F(下划线的 URL 编码形式)来创建以下划线开头的 URL 段:%5FfolderName。- 如果您不使用私有文件夹,了解 Next.js 的特殊文件约定将有助于防止意外的命名冲突。
路由组可以通过将文件夹用括号包裹来创建:(folderName)
这表明该文件夹仅用于组织目的,不应包含在路由的 URL 路径中。


路由组对于以下方面很有用:
src 文件夹Next.js 支持将应用程序代码(包括 app)存储在可选的 src 文件夹中。这可以将应用程序代码与主要位于项目根目录下的项目配置文件分离。


以下部分列出了常见策略的非常高层级的概述。最简单的做法是选择一个适合您和您团队的策略,并在整个项目中保持一致。
须知:在下面的示例中,我们使用
components和lib文件夹作为通用占位符,它们的命名没有特殊的框架意义,您的项目可能使用ui、utils、hooks、styles等其他文件夹。
app 外部此策略将所有应用程序代码存储在项目根目录下的共享文件夹中,并将 app 目录纯粹用于路由目的。


app 内部的顶层文件夹中此策略将所有应用程序代码存储在 app 目录的根目录下的共享文件夹中。


此策略将全局共享的应用程序代码存储在 app 根目录中,并将更具体的应用程序代码拆分到使用它们的路由段中。


要组织路由而不影响 URL,请创建一个组以将相关路由保存在一起。括号中的文件夹将从 URL 中省略(例如 (marketing) 或 (shop))。


尽管 (marketing) 和 (shop) 内的路由共享相同的 URL 层级,但您可以通过在其文件夹内添加 layout.js 文件来为每个组创建不同的布局。


要将特定路由选择性地加入布局,请创建一个新的路由组(例如 (shop)),并将共享相同布局的路由移入该组(例如 account 和 cart)。该组之外的路由将不共享该布局(例如 checkout)。


要通过 loading.js 文件将加载骨架屏应用于特定路由,请创建一个新的路由组(例如 /(overview)),然后将您的 loading.tsx 移入该路由组中。


现在,loading.tsx 文件将仅应用于您的仪表盘 → 概览页面,而不是所有仪表盘页面,同时不影响 URL 路径结构。
要创建多个根布局,请移除顶层 layout.js 文件,并在每个路由组内添加一个 layout.js 文件。这对于将应用程序划分为具有完全不同 UI 或体验的部分非常有用。<html> 和 <body> 标签需要添加到每个根布局中。


在上面的示例中,(marketing) 和 (shop) 都拥有自己的根布局。