跳到主要内容

项目结构和组织

本页提供了 Next.js 中所有文件夹和文件约定的概述,以及组织项目的建议。

文件夹和文件约定

顶级文件夹

顶级文件夹用于组织应用程序的代码和静态资源。

路由段到路径段的映射路由段到路径段的映射
appApp 路由
pagesPages 路由
public要提供的静态资源
src可选的应用程序源代码文件夹

顶级文件

顶级文件用于配置应用程序、管理依赖项、运行中间件、集成监控工具和定义环境变量。

Next.js
next.config.jsNext.js 配置文件
package.json项目依赖项和脚本
instrumentation.tsOpenTelemetry 和检测文件
middleware.tsNext.js 请求中间件
.env环境变量
.env.local本地环境变量
.env.production生产环境变量
.env.development开发环境变量
.eslintrc.jsonESLint 配置文件
.gitignoreGit 要忽略的文件和文件夹
next-env.d.tsNext.js 的 TypeScript 声明文件
tsconfig.jsonTypeScript 配置文件
jsconfig.jsonJavaScript 配置文件

路由文件

layout.js .jsx .tsx布局
page.js .jsx .tsx页面
loading.js .jsx .tsx加载界面
not-found.js .jsx .tsx未找到界面
error.js .jsx .tsx错误界面
global-error.js .jsx .tsx全局错误界面
route.js .tsAPI 端点
template.js .jsx .tsx重新渲染的布局
default.js .jsx .tsx并行路由回退页面

嵌套路由

folder路由段
folder/folder嵌套路由段

动态路由

[folder]动态路由段
[...folder]捕获所有路由段
[[...folder]]可选捕获所有路由段

路由组和私有文件夹

(folder)在不影响路由的情况下对路由进行分组
_folder将文件夹和所有子段从路由中排除

并行和拦截路由

@folder命名槽
(.)folder拦截同一级别
(..)folder拦截上一级别
(..)(..)folder拦截上两级
(...)folder从根目录拦截

元数据文件约定

应用图标

favicon.ico网站图标文件
icon.ico .jpg .jpeg .png .svg应用图标文件
icon.js .ts .tsx生成的应用图标
apple-icon.jpg .jpeg, .pngApple 应用图标文件
apple-icon.js .ts .tsx生成的 Apple 应用图标

Open Graph 和 Twitter 图片

opengraph-image.jpg .jpeg .png .gifOpen Graph 图片文件
opengraph-image.js .ts .tsx生成的 Open Graph 图片
twitter-image.jpg .jpeg .png .gifTwitter 图片文件
twitter-image.js .ts .tsx生成的 Twitter 图片

SEO

sitemap.xml网站地图文件
sitemap.js .ts生成的网站地图
robots.txtRobots 文件
robots.js .ts生成的 Robots 文件

pages文件约定

_app.js .jsx .tsx自定义应用
_document.js .jsx .tsx自定义文档
_error.js .jsx .tsx自定义错误页面
404.js .jsx .tsx404 错误页面
500.js .jsx .tsx500 错误页面

路由

文件夹约定
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.js
  • template.js
  • error.js (React 错误边界)
  • loading.js (React suspense 边界)
  • not-found.js (React 错误边界)
  • page.js 或嵌套的 layout.js
文件约定的组件层次结构文件约定的组件层次结构

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

嵌套文件约定组件层次结构嵌套文件约定组件层次结构

并置(Colocation)

app 目录中,嵌套文件夹定义路由结构。每个文件夹代表映射到 URL 路径中相应段的路由段。

但是,即使路由结构是通过文件夹定义的,在向路由段添加 page.jsroute.js 文件之前,路由不会公开访问

显示在向路由段添加 page.js 或 route.js 文件之前路由不可公开访问的图表。显示在向路由段添加 page.js 或 route.js 文件之前路由不可公开访问的图表。

而且,即使路由变为公开访问,也只有 page.jsroute.js 返回的内容会发送给客户端。

显示 page.js 和 route.js 文件如何使路由公开访问的图表。显示 page.js 和 route.js 文件如何使路由公开访问的图表。

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

显示即使段包含 page.js 或 route.js 文件,并置的项目文件也不可路由的图表。显示即使段包含 page.js 或 route.js 文件,并置的项目文件也不可路由的图表。

提示: 虽然你可以app 中并置项目文件,但你不必这样做。如果你愿意,你可以将它们保留在 app 目录之外

私有文件夹

可以通过在文件夹前加下划线来创建私有文件夹:_folderName

这表示该文件夹是私有实现细节,不应被路由系统考虑,从而将文件夹及其所有子文件夹从路由中排除。

使用私有文件夹的示例文件夹结构使用私有文件夹的示例文件夹结构

由于 app 目录中的文件可以默认安全并置,因此并置不需要私有文件夹。但是,它们对于以下情况很有用:

  • 将 UI 逻辑与路由逻辑分离。
  • 在项目和 Next.js 生态系统中一致地组织内部文件。
  • 在代码编辑器中排序和分组文件。
  • 避免与未来 Next.js 文件约定的潜在命名冲突。

提示:

  • 虽然不是框架约定,但你可能还会考虑使用相同下划线模式将私有文件夹外的文件标记为"私有"。
  • 你可以通过用 %5F(下划线的 URL 编码形式)作为文件夹名称前缀来创建以下划线开头的 URL 段:%5FfolderName
  • 如果你不使用私有文件夹,了解 Next.js 特殊文件约定将有助于防止意外的命名冲突。

路由组

可以通过用括号包装文件夹来创建路由组:(folderName)

这表示该文件夹用于组织目的,不应包含在路由的 URL 路径中。

使用路由组的示例文��件夹结构使用路由组的示例文件夹结构

路由组对于以下情况很有用:

src 文件夹

Next.js 支持将应用程序代码(包括 app)存储在可选的 src 文件夹中。这会将应用程序代码与主要位于项目根目录的项目配置文件分离。

带有 `src` 文件夹的示例文件夹结构带有 `src` 文件夹的示例文件夹结构

示例

以下部分列出了常见策略的非常高级概述。最简单的要点是选择一个适合你和你的团队的策略,并在整个项目中保持一致。

提示: 在下面的示例中,我们使用 componentslib 文件夹作为通用占位符,它们的命名没有特殊的框架意义,你的项目可能使用其他文件夹,如 uiutilshooksstyles 等。

将项目文件存储在 app 之外

此策略将所有应用程序代码存储在项目根目录的共享文件夹中,并保持 app 目录纯粹用于路由目的。

项目文件在 app 之外的示例文件夹结构项目文件在 app 之外的示例文件夹结构

将项目文件存储在 app 内的顶级文件夹中

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

项目文件在 app 内的示例文件夹结构项目文件在 app 内的示例文件夹结构

按功能或路由拆分项目文件

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

按功能或路由拆分项目文件的示例文件夹结构按功能或路�由拆分项目文件的示例文件夹结构

在不影响 URL 路径的情况下组织路由

要在不影响 URL 的情况下组织路由,创建一个组来保持相关路由在一起。括号中的文件夹将从 URL 中省略(例如 (marketing)(shop))。

使用路由组组织路由使用路由组组织路由

即使 (marketing)(shop) 内的路由共享相同的 URL 层次结构,你也可以通过在其文件夹中添加 layout.js 文件为每个组创建不同的布局。

具有多个布局的路由组具有多个布局的路由组

选择特定段进入布局

要让特定路由进入布局,创建一个新的路由组(例如 (shop))并将共享相同布局的路由移动到组中(例如 accountcart)。组外的路由不会共享布局(例如 checkout)。

具有选择进入布局的路由组具有选择进入布局的路由组

为特定路由选择加载骨架屏

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

显示路由组内 loading.tsx 和 page.tsx 的文件夹结构显示路由组内 loading.tsx 和 page.tsx 的文件夹结构

现在,loading.tsx 文件将只应用于你的 dashboard → overview 页面,而不是所有 dashboard 页面,而不会影响 URL 路径结构。

创建多个根布局

要创建多个根布局,删除顶级 layout.js 文件,并在每个路由组内添加 layout.js 文件。这对于将应用程序分区为具有完全不同 UI 或体验的部分很有用。<html><body> 标签需要添加到每个根布局中。

具有多个根布局的路由组具有多个根布局的路由组

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