主题
项目结构
¥Project Structure
本页面概述了 Next.js 中所有文件夹和文件约定,以及组织项目的建议。
¥This page provides an overview of all the folder and file conventions in Next.js, and recommendations for organizing your project.
文件夹和文件约定
¥Folder and file conventions
顶层文件夹
¥Top-level folders
顶层文件夹用于组织应用的代码和静态资源。
¥Top-level folders are used to organize your application's code and static assets.

app | 应用路由 |
pages | 页面路由 |
public | 要提供的静态资源 |
src | 可选应用源文件夹 |
顶层文件
¥Top-level files
顶层文件用于配置应用、管理依赖、运行代理、集成监控工具以及定义环境变量。
¥Top-level files are used to configure your application, manage dependencies, run proxy, integrate monitoring tools, and define environment variables.
| 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 的配置文件 |
路由文件
¥Routing Files
添加 page 以公开路由,添加 layout 以公开共享 UI(例如页眉、导航或页脚),添加 loading 以公开框架,添加 error 以公开错误边界,添加 route 以公开 API。
¥Add page to expose a route, layout for shared UI such as header, nav, or footer, loading for skeletons, error for error boundaries, and route for APIs.
layout | .js .jsx .tsx | 布局 |
page | .js .jsx .tsx | 页面 |
loading | .js .jsx .tsx | 加载用户界面 |
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 | 并行路由回退页面 |
嵌套路由
¥Nested routes
文件夹定义 URL 段。嵌套文件夹嵌套段。任何级别的布局都会封装其子段。当存在 page 或 route 文件时,该路由将变为公开路由。
¥Folders define URL segments. Nesting folders nests segments. Layouts at any level wrap their child segments. A route becomes public when a page or route file exists.
| 路径 | URL 模式 | 注意 |
|---|---|---|
app/layout.tsx | — | 根布局包含所有路由 |
app/blog/layout.tsx | — | 封装 /blog 及其子类 |
app/page.tsx | / | 公共路由 |
app/blog/page.tsx | /blog | 公共路由 |
app/blog/authors/page.tsx | /blog/authors | 公共路由 |
动态路由
¥Dynamic routes
使用方括号对段进行参数化。对于单个参数,请使用 [segment];对于所有参数,请使用 [...segment];对于可选的所有参数,请使用 [[...segment]]。通过 params 属性访问值。
¥Parameterize segments with square brackets. Use [segment] for a single param, [...segment] for catch‑all, and [[...segment]] for optional catch‑all. Access values via the params prop.
| 路径 | URL 模式 |
|---|---|
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, /docs/layouts-and-pages, /docs/api-reference/use-router |
路由组和私有文件夹
¥Route groups and private folders
使用路由组 (group) 组织代码而无需更改 URL,并将不可路由的文件放在私有文件夹 _folder 中。
¥Organize code without changing URLs with route groups (group), and colocate non-routable files with private folders _folder.
| 路径 | URL 模式 | 注意 |
|---|---|---|
app/(marketing)/page.tsx | / | URL 中省略的组 |
app/(shop)/cart/page.tsx | /cart | 在 (shop) 内共享布局 |
app/blog/_components/Post.tsx | — | 不可路由;用于存放 UI 工具的安全位置 |
app/blog/_lib/data.ts | — | 不可路由;工具的安全位置 |
并行和拦截的路由
¥Parallel and Intercepted Routes
这些功能适用于特定的 UI 模式,例如基于槽的布局或模态路由。
¥These features fit specific UI patterns, such as slot-based layouts or modal routing.
对于由父布局渲染的命名插槽,请使用 @slot。使用拦截模式在当前布局中渲染另一个路由,而无需更改 URL,例如,在列表上方以模态框形式显示详细信息视图。
¥Use @slot for named slots rendered by a parent layout. Use intercept patterns to render another route inside the current layout without changing the URL, for example, to show a details view as a modal over a list.
| 模式(文档) | 含义 | 典型用例 |
|---|---|---|
@folder | 命名插槽 | 侧边栏 + 主内容 |
(.)folder | 拦截同一级别 | 在模态框中预览同级路由 |
(..)folder | 拦截父级 | 以覆盖层的形式打开父级的子级 |
(..)(..)folder | 拦截两级 | 深度嵌套覆盖层 |
(...)folder | 从根拦截 | 在当前视图中显示任意路由 |
元数据文件约定
¥Metadata file conventions
应用图标
¥App icons
favicon | .ico | Favicon 文件 |
icon | .ico .jpg .jpeg .png .svg | App Icon 文件 |
icon | .js .ts .tsx | 生成的应用图标 |
apple-icon | .jpg .jpeg, .png | Apple App Icon 文件 |
apple-icon | .js .ts .tsx | 生成的 Apple 应用图标 |
Open Graph 和 Twitter 图片
¥Open Graph and Twitter images
opengraph-image | .jpg .jpeg .png .gif | 打开 Graph 图片文件 |
opengraph-image | .js .ts .tsx | 生成的 Open Graph 图片 |
twitter-image | .jpg .jpeg .png .gif | Twitter 图片文件 |
twitter-image | .js .ts .tsx | 生成的 Twitter 图片 |
SEO
sitemap | .xml | 站点地图文件 |
sitemap | .js .ts | 生成的站点地图 |
robots | .txt | Robots 文件 |
robots | .js .ts | 生成的 Robots 文件 |
组织你的项目
¥Organizing your project
Next.js 对如何组织和共置项目文件没有意见。但它确实提供了一些功能来帮助你组织项目。
¥Next.js is unopinionated about how you organize and colocate your project files. But it does provide several features to help you organize your project.
组件层次结构
¥Component hierarchy
在特殊文件中定义的组件按特定层次结构渲染:
¥The components defined in special files are rendered in a specific hierarchy:
layout.jstemplate.jserror.js(反应误差边界)¥
error.js(React error boundary)loading.js(反应悬念边界)¥
loading.js(React suspense boundary)not-found.js("未找到" UI 的 React 错误边界)¥
not-found.js(React error boundary for "not found" UI)page.js或嵌套layout.js¥
page.jsor nestedlayout.js

组件在嵌套路由中递归渲染,这意味着路由段的组件将嵌套在其父段的组件中。
¥The components are rendered recursively in nested routes, meaning the components of a route segment will be nested inside the components of its parent segment.

主机托管
¥Colocation
在 app 目录中,嵌套文件夹定义路由结构。每个文件夹代表一个路由段,该路由段映射到 URL 路径中的相应段。
¥In the app directory, nested folders define route structure. Each folder represents a route segment that is mapped to a corresponding segment in a URL path.
但是,即使路由结构是通过文件夹定义的,在将 page.js 或 route.js 文件添加到路由段之前,路由也无法公开访问。
¥However, even though route structure is defined through folders, a route is not publicly accessible until a page.js or route.js file is added to a route segment.

而且,即使路由可公开访问,也只有 page.js 或 route.js 返回的内容会发送到客户端。
¥And, even when a route is made publicly accessible, only the content returned by page.js or route.js is sent to the client.

这意味着项目文件可以安全地共存于 app 目录中的路由段内,而不会意外地被路由。
¥This means that project files can be safely colocated inside route segments in the app directory without accidentally being routable.

需要了解:虽然你可以将项目文件放在
app中,但你不必这样做。如果你愿意,你可以 将它们保留在app目录之外。¥Good to know: While you can colocate your project files in
appyou don't have to. If you prefer, you can keep them outside theappdirectory.
私有文件夹
¥Private folders
可以通过在文件夹前添加下划线来创建私有文件夹:_folderName
¥Private folders can be created by prefixing a folder with an underscore: _folderName
这表明该文件夹是私有实现细节,路由系统不应考虑该文件夹,从而选择该文件夹及其所有子文件夹不进行路由。
¥This indicates the folder is a private implementation detail and should not be considered by the routing system, thereby opting the folder and all its subfolders out of routing.

由于 app 目录中的文件可以是 默认情况下安全地共置,因此共置不需要私有文件夹。然而,它们可用于:
¥Since files in the app directory can be safely colocated by default, private folders are not required for colocation. However, they can be useful for:
将 UI 逻辑与路由逻辑分离。
¥Separating UI logic from routing logic.
跨项目和 Next.js 生态系统一致地组织内部文件。
¥Consistently organizing internal files across a project and the Next.js ecosystem.
在代码编辑器中对文件进行排序和分组。
¥Sorting and grouping files in code editors.
避免与未来的 Next.js 文件约定发生潜在的命名冲突。
¥Avoiding potential naming conflicts with future Next.js file conventions.
需要了解:
¥Good to know:
虽然不是框架约定,但你也可以考虑使用相同的下划线模式将私有文件夹外部的文件标记为 "private"。
¥While not a framework convention, you might also consider marking files outside private folders as "private" using the same underscore pattern.
你可以通过在文件夹名称前添加
%5F(下划线的 URL 编码形式)作为前缀来创建以下划线开头的 URL 段:%5FfolderName。¥You can create URL segments that start with an underscore by prefixing the folder name with
%5F(the URL-encoded form of an underscore):%5FfolderName.如果你不使用私有文件夹,那么了解 Next.js 特殊文件约定 会很有帮助,以防止意外的命名冲突。
¥If you don't use private folders, it would be helpful to know Next.js special file conventions to prevent unexpected naming conflicts.
路由组
¥Route groups
可以通过将文件夹括在括号中来创建路由组:(folderName)
¥Route groups can be created by wrapping a folder in parenthesis: (folderName)
这表明该文件夹用于组织目的,不应包含在路由的 URL 路径中。
¥This indicates the folder is for organizational purposes and should not be included in the route's URL path.

路由组可用于:
¥Route groups are useful for:
按网站版块、意图或团队组织路由。例如,营销页面、管理页面等。
¥Organizing routes by site section, intent, or team. e.g. marketing pages, admin pages, etc.
在同一路由段级别中启用嵌套布局:
¥Enabling nested layouts in the same route segment level:
src 文件夹
¥src folder
Next.js 支持将应用代码(包括 app)存储在可选的 src 文件夹 内。这将应用代码与项目配置文件分开,项目配置文件主要位于项目的根目录中。
¥Next.js supports storing application code (including app) inside an optional src folder. This separates application code from project configuration files which mostly live in the root of a project.

示例
¥Examples
以下部分列出了常见策略的高度概述。最简单的要点是选择一种适合你和你的团队的策略,并在整个项目中保持一致。
¥The following section lists a very high-level overview of common strategies. The simplest takeaway is to choose a strategy that works for you and your team and be consistent across the project.
需要了解:在下面的示例中,我们使用
components和lib文件夹作为通用占位符,它们的命名没有特殊的框架意义,你的项目可能会使用其他文件夹,如ui、utils、hooks、styles等。¥Good to know: In our examples below, we're using
componentsandlibfolders as generalized placeholders, their naming has no special framework significance and your projects might use other folders likeui,utils,hooks,styles, etc.
将项目文件存储在 app 之外
¥Store project files outside of app
此策略将所有应用代码存储在项目根目录的共享文件夹中,并保留 app 目录纯粹用于路由目的。
¥This strategy stores all application code in shared folders in the root of your project and keeps the app directory purely for routing purposes.

将项目文件存储在 app 内的顶层文件夹中
¥Store project files in top-level folders inside of app
此策略将所有应用代码存储在 app 目录根目录的共享文件夹中。
¥This strategy stores all application code in shared folders in the root of the app directory.

按功能或路由拆分项目文件
¥Split project files by feature or route
该策略将全局共享的应用代码存储在根 app 目录中,并将更具体的应用代码拆分到使用它们的路由段中。
¥This strategy stores globally shared application code in the root app directory and splits more specific application code into the route segments that use them.

组织路由而不影响 URL 路径
¥Organize routes without affecting the URL path
要在不影响 URL 的情况下组织路由,请创建一个组以将相关路由保存在一起。括号中的文件夹将从 URL 中省略(例如 (marketing) 或 (shop))。
¥To organize routes without affecting the URL, create a group to keep related routes together. The folders in parenthesis will be omitted from the URL (e.g. (marketing) or (shop)).

即使 (marketing) 和 (shop) 内的路由共享相同的 URL 层次结构,你也可以通过在其文件夹内添加 layout.js 文件来为每个组创建不同的布局。
¥Even though routes inside (marketing) and (shop) share the same URL hierarchy, you can create a different layout for each group by adding a layout.js file inside their folders.

选择特定的部分到布局中
¥Opting specific segments into a layout
要将特定路由选择到布局中,请创建一个新的路由组(例如 (shop))并将共享相同布局的路由移到该组中(例如 account 和 cart)。组外的路由不会共享布局(例如 checkout)。
¥To opt specific routes into a layout, create a new route group (e.g. (shop)) and move the routes that share the same layout into the group (e.g. account and cart). The routes outside of the group will not share the layout (e.g. checkout).

选择在特定路由上加载骨架
¥Opting for loading skeletons on a specific route
要通过 loading.js 文件将 加载骨架 应用于特定路由,请创建一个新的路由组(例如 /(overview)),然后将 loading.tsx 移动到该路由组内。
¥To apply a loading skeleton via a loading.js file to a specific route, create a new route group (e.g., /(overview)) and then move your loading.tsx inside that route group.

现在,loading.tsx 文件将仅适用于你的仪表板 → 概览页面,而不是所有仪表板页面,而不会影响 URL 路径结构。
¥Now, the loading.tsx file will only apply to your dashboard → overview page instead of all your dashboard pages without affecting the URL path structure.
创建多个根布局
¥Creating multiple root layouts
要创建多个 根布局,请删除顶层 layout.js 文件,并在每个路由组内添加一个 layout.js 文件。这对于将应用划分为具有完全不同的 UI 或体验的部分非常有用。需要将 <html> 和 <body> 标签添加到每个根布局中。
¥To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route group. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html> and <body> tags need to be added to each root layout.

在上面的示例中,(marketing) 和 (shop) 都有自己的根布局。
¥In the example above, both (marketing) and (shop) have their own root layout.