layout.js
layout
檔案用於在你的 Next.js 應用程式中定義版面配置。
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
根版面配置 是根目錄 app
目錄中最頂層的版面配置。它用於定義 <html>
和 <body>
標籤以及其他全域共用的 UI。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
參考
Props
children
(必填)
版面配置元件應接受並使用 children
prop。在渲染期間,children
將會被版面配置所包裝的路由區段填入。這些主要會是子層 版面配置(如果存在)或 頁面 的元件,但也可能是其他特殊檔案,例如 載入中 或 錯誤(在適用的情況下)。
params
(選填)
一個 Promise,解析為一個物件,其中包含從根區段到該版面配置的 動態路由參數 物件。
export default async function Layout({
params,
}: {
params: Promise<{ team: string }>
}) {
const team = (await params).team
}
路由範例 | 網址 | params |
---|---|---|
app/dashboard/[team]/layout.js | /dashboard/1 | Promise<{ team: '1' }> |
app/shop/[tag]/[item]/layout.js | /shop/1/2 | Promise<{ tag: '1', item: '2' }> |
app/blog/[...slug]/layout.js | /blog/1/2 | Promise<{ slug: ['1', '2'] }> |
- 由於
params
prop 是一個 promise。你必須使用async/await
或 React 的use
函式來存取這些值。- 在版本 14 及更早版本中,
params
是一個同步 prop。為了協助向後相容性,你仍然可以在 Next.js 15 中同步存取它,但此行為在未來將會被棄用。
- 在版本 14 及更早版本中,
根版面配置
app
目錄必須包含一個根目錄 app/layout.js
。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>{children}</body>
</html>
)
}
- 根版面配置必須定義
<html>
和<body>
標籤。- 你不應手動將
<head>
標籤(例如<title>
和<meta>
)新增至根版面配置。相反地,你應該使用 Metadata API,它會自動處理進階需求,例如串流和重複資料刪除<head>
元素。
- 你不應手動將
- 你可以使用 路由群組 來建立多個根版面配置。
- 在多個根版面配置之間導航將會導致完整頁面載入(而不是用戶端導航)。例如,從使用
app/(shop)/layout.js
的/cart
導航到使用app/(marketing)/layout.js
的/blog
將會導致完整頁面載入。這僅適用於多個根版面配置。
- 在多個根版面配置之間導航將會導致完整頁面載入(而不是用戶端導航)。例如,從使用
注意事項
版面配置不接收 searchParams
與 頁面 不同,版面配置元件不接收 searchParams
prop。這是因為共用版面配置在 導航期間不會重新渲染,這可能會導致導航之間 searchParams
過時。
當使用用戶端導航時,Next.js 會自動僅渲染兩個路由之間共用版面配置下方的頁面部分。
例如,在以下目錄結構中,dashboard/layout.tsx
是 /dashboard/settings
和 /dashboard/analytics
的共用版面配置


當從 /dashboard/settings
導航到 /dashboard/analytics
時,/dashboard/analytics
中的 page.tsx
將會在伺服器上重新渲染,而 dashboard/layout.tsx
將不會重新渲染,因為它是兩個路由之間共用的 UI。
這種效能最佳化允許共享版面配置的頁面之間的導航速度更快,因為只需要執行頁面的資料抓取和渲染,而不是可能包含抓取自身資料的共用版面配置的整個路由。
由於 dashboard/layout.tsx
不會重新渲染,因此版面配置伺服器元件中的 searchParams
prop 在導航後可能會變得過時。
相反地,在版面配置中使用頁面 searchParams
prop 或用戶端元件中的 useSearchParams
hook,它們會在用戶端使用最新的 searchParams
重新渲染。
版面配置無法存取 pathname
版面配置無法存取 pathname
。這是因為版面配置預設為伺服器元件,且 在用戶端導航期間不會重新渲染,這可能會導致導航之間 pathname
過時。為了防止過時,Next.js 需要重新抓取路由的所有區段,從而失去快取的優勢並增加導航時的 RSC payload 大小。
相反地,你可以將依賴 pathname 的邏輯提取到用戶端元件中,並將其匯入到你的版面配置中。由於用戶端元件在導航期間會重新渲染(但不會重新抓取),因此你可以使用 Next.js hook,例如 usePathname
來存取目前的 pathname 並防止過時。
import { ClientComponent } from '@/app/ui/ClientComponent'
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<ClientComponent />
{/* Other Layout UI */}
<main>{children}</main>
</>
)
}
常見的 pathname
模式也可以使用 params
prop 來實作。
請參閱 範例 章節以取得更多資訊。
範例
根據 params
顯示內容
使用 動態路由區段,你可以根據 params
prop 顯示或抓取特定內容。
export default async function DashboardLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ team: string }>
}) {
const { team } = await params
return (
<section>
<header>
<h1>Welcome to {team}'s Dashboard</h1>
</header>
<main>{children}</main>
</section>
)
}
在用戶端元件中讀取 params
若要在用戶端元件中使用 params
(不能是 async
),你可以使用 React 的 use
函式來讀取 promise
'use client'
import { use } from 'react'
export default function Page({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = use(params)
}
版本歷史
版本 | 變更 |
---|---|
v15.0.0-RC | params 現在是一個 promise。有一個 codemod 可用。 |
v13.0.0 | 引入 layout 。 |
這有幫助嗎?