layout.js
布局 (Layout) 是在多个路由间共享的用户界面。
根布局 (Root Layout) 是根目录 app
中最顶层的布局,用于定义 <html>
和 <body>
标签以及其他全局共享的用户界面。
属性
children
(必填)
布局组件应当接收并使用 children
属性。在渲染时,children
会被填充为该布局所包裹的路由片段。这些内容主要是子 布局 (Layout) 或 页面 (Page) 的组件(如果存在),但也可能是其他特殊文件如 加载状态 (Loading) 或 错误处理 (Error)(当适用时)。
params
(可选)
从根段到该布局的 动态路由参数 (dynamic route parameters) 对象。
示例 | URL | params |
---|---|---|
app/dashboard/[team]/layout.js | /dashboard/1 | { team: '1' } |
app/shop/[tag]/[item]/layout.js | /shop/1/2 | { tag: '1', item: '2' } |
app/blog/[...slug]/layout.js | /blog/1/2 | { slug: ['1', '2'] } |
示例:
须知
布局不会接收 searchParams
与 页面 (Pages) 不同,布局组件 不会 接收 searchParams
属性。这是因为共享布局在 导航时不会重新渲染,可能导致导航间的 searchParams
过时。
使用客户端导航时,Next.js 会自动仅渲染两个路由间公共布局下方的页面部分。
例如,在以下目录结构中,dashboard/layout.tsx
是 /dashboard/settings
和 /dashboard/analytics
的公共布局:

当从 /dashboard/settings
导航到 /dashboard/analytics
时,/dashboard/analytics
中的 page.tsx
会在服务器端重新渲染,而 dashboard/layout.tsx
不会 重新渲染,因为它是两个路由共享的用户界面。
这种性能优化使得共享布局的页面间导航更快,因为只需运行页面的数据获取和渲染,而不需要处理可能包含自身数据获取的整个路由。
由于 dashboard/layout.tsx
不会重新渲染,布局中的 searchParams
属性在导航后可能会 过时。
- 替代方案是使用页面的
searchParams
属性,或在客户端组件中使用useSearchParams
钩子,该钩子会在客户端重新渲染时获取最新的searchParams
。
根布局
app
目录 必须 包含一个根app/layout.js
。- 根布局 必须 定义
<html>
和<body>
标签。- 不应手动在根布局中添加
<head>
标签(如<title>
和<meta>
)。相反,应使用 元数据 API (Metadata API),它会自动处理高级需求,如流式传输和去重<head>
元素。
- 不应手动在根布局中添加
- 可以使用 路由组 (route groups) 创建多个根布局。
- 在 多个根布局间导航 会触发 整页加载(而非客户端导航)。例如,从使用
app/(shop)/layout.js
的/cart
导航到使用app/(marketing)/layout.js
的/blog
会触发整页加载。这 仅 适用于多个根布局的情况。
- 在 多个根布局间导航 会触发 整页加载(而非客户端导航)。例如,从使用
版本历史
版本 | 变更 |
---|---|
v13.0.0 | 引入 layout 功能。 |