跳至內容

layout.js

layout 檔案用於在 Next.js 應用程式中定義佈局。

app/dashboard/layout.tsx
export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return <section>{children}</section>
}

根佈局是根目錄 app 中最頂層的佈局。它用於定義 <html><body> 標籤以及其他全域共用的 UI。

app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

參考

屬性 (Props)

children (必要)

佈局組件應該接受並使用 children 屬性。在渲染過程中,children 將會填入佈局所包裝的路由區段。這些主要會是子 佈局 (Layout)(如果有的話)或 頁面 (Page) 的組件,但也可能是其他特殊檔案,例如在適用的情況下,載入中 (Loading)錯誤 (Error)

params (選用)

一個 Promise,解析為包含從根區段到該佈局的 動態路由參數 物件。

app/dashboard/[team]/layout.tsx
export default async function Layout({
  params,
}: {
  params: Promise<{ team: string }>
}) {
  const team = (await params).team
}
路由範例網址參數 (params)
app/dashboard/[team]/layout.js/dashboard/1Promise<{ team: '1' }>
app/shop/[tag]/[item]/layout.js/shop/1/2Promise<{ tag: '1', item: '2' }>
app/blog/[...slug]/layout.js/blog/1/2Promise<{ slug: ['1', '2'] }>
  • 由於 params 屬性是一個 Promise,您必須使用 async/await 或 React 的 use 函式來存取值。
    • 在版本 14 和更早的版本中,params 是一個同步屬性。為了幫助向下相容,您仍然可以在 Next.js 15 中同步存取它,但此行為將在未來被棄用。

根佈局 (Root Layouts)
app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>{children}</body>
    </html>
  )
}

注意事項

佈局不會接收 searchParams

頁面不同,佈局組件不會接收 searchParams 屬性。這是因為共用佈局在導航期間不會重新渲染,這可能導致在導航之間 searchParams 過時。

使用客戶端導航時,Next.js 會自動僅渲染兩個路由之間共用佈局下方的頁面部分。

例如,在以下目錄結構中,dashboard/layout.tsx/dashboard/settings/dashboard/analytics 的共用佈局。

File structure showing a dashboard folder nesting a layout.tsx file, and settings and analytics folders with their own pages

/dashboard/settings 導航到 /dashboard/analytics 時,/dashboard/analytics 中的 page.tsx 將在伺服器上重新渲染,而 dashboard/layout.tsx不會重新渲染,因為它是兩個路由之間共用的 UI。

這種效能優化允許在共用佈局的頁面之間更快地導航,因為只需要執行頁面的資料提取和渲染,而不是可能包含提取自身資料的共用佈局的整個路由。

由於 dashboard/layout.tsx 不會重新渲染,佈局伺服器組件中的 searchParams 屬性在導航後可能會過時

請改用頁面searchParams 屬性或佈局內的客戶端組件中的useSearchParams hook,它會在客戶端使用最新的 searchParams 重新渲染。

佈局無法存取 pathname

佈局無法存取 pathname。這是因為佈局預設為伺服器元件,並且在客戶端導覽期間不會重新渲染,這可能導致 pathname 在導覽之間失效。為了防止失效,Next.js 需要重新提取路由的所有區段,失去快取的優勢,並增加導覽時的 RSC 有效負載 大小。

您可以改將依賴 pathname 的邏輯提取到客戶端元件,並將其導入您的佈局中。由於客戶端元件在導覽期間會重新渲染(但不會重新提取),因此您可以使用 Next.js hooks,例如 usePathname 來存取目前的 pathname 並防止失效。

app/dashboard/layout.tsx
import { ClientComponent } from '@/app/ui/ClientComponent'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <ClientComponent />
      {/* Other Layout UI */}
      <main>{children}</main>
    <>
  )
}

常見的 pathname 模式也可以使用 params 屬性來實現。

請參閱範例區段以取得更多資訊。

範例

根據 params 顯示內容

使用動態路由區段,您可以根據 params 屬性顯示或提取特定內容。

app/dashboard/layout.tsx
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

要在客戶端元件(不能是 async)中使用 params,您可以使用 React 的 use 函式來讀取 promise

app/page.tsx
'use client'
 
import { use } from 'react'
 
export function Page({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = use(params)
}

版本歷史

版本變更
v15.0.0-RCparams 現在是一個 Promise。我們提供了一個 程式碼修改工具
v13.0.0引進 layout