跳到主內容

【Next.js】Layout

太好了!以下是為「Next.js 初學者」量身打造的教學文章,主題為:

🔍 Next.js App Router 中 layout.tsxpage.tsxchildren 的邏輯與實作


🧠 為什麼要了解這三個東西?

在 Next.js 的 App Router 架構中,整個畫面的內容是由許多層「外殼(layout)」與「內頁(page)」所組合而成。而這個組合的核心,就是這三個角色:

  • layout.tsx:整體框架的「容器」

  • page.tsx:實際對應到網址的「頁面內容」

  • children:layout 內部接收的下一層內容(可能是 page,也可能是下一層 layout)


🔧 這三者的關係是什麼?

你可以想像畫面組成就像是便當盒:

  • layout.tsx 就是便當盒(框架)

  • page.tsx 是便當裡的菜色(內容)

  • children 是 layout.tsx 中的佔位符,用來「放內容的地方」

👉 換句話說:

page.tsx 的畫面內容,會自動傳給上層 layout.tsx 中的 children 來顯示


🧱 結構範例

app/
├── layout.tsx          ← 全站框架 Layout
├── page.tsx            ← 首頁 `/`
├── about/
│   └── page.tsx        ← `/about` 頁面

📦 layout.tsx 實際程式碼

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <header>這是全站共用的 Header</header>
        <main>{children}</main> {/* 這裡會被 page.tsx 的內容填進來 */}
        <footer>這是共用的 Footer</footer>
      </body>
    </html>
  );
}

📦 page.tsx 實際程式碼

export default function HomePage() {
  return <div>這是首頁的內容</div>;
}

💡 瀏覽 / 時會發生什麼事?

  1. Next.js 根據 URL / 找到 app/page.tsx

  2. 找到對應的 layout.tsx 作為頁面外框

  3. page.tsx 的內容當作 children 傳給 layout.tsx

  4. 畫面最終呈現:

<html lang="en">
  <body>
    <header>這是全站共用的 Header</header>
    <main>
      <div>這是首頁的內容</div>
    </main>
    <footer>這是共用的 Footer</footer>
  </body>
</html>

🔁 多層 layout 怎麼辦?

可以有巢狀 layout 結構,例如:

app/
├── layout.tsx                  ← 全站 layout
├── (admin)/
│   ├── layout.tsx              ← admin 專區 layout
│   └── dashboard/
│       └── page.tsx            ← `/dashboard` 頁面

流程如下:

  1. dashboard/page.tsx 被載入

  2. 它被傳給 admin/layout.tsxchildren

  3. 然後再傳到最外層 app/layout.tsxchildren

  4. 最終包成一整頁畫面


✅ 重點整理

元素 說明
layout.tsx 定義頁面外框、接收 children
page.tsx 對應 URL 的實際頁面內容
children layout.tsx 的佔位符,用來顯示下層內容
傳遞邏輯順序 page.tsx → 傳給 → layout.tsx → 再往上層

📌 初學者常見疑問

❓ Q1: children 是誰傳給 layout.tsx 的?

A: 是 Next.js 自動傳進來的,不需要自己傳。


❓ Q2: 可以有多個 layout.tsx 嗎?

A: 可以。每一層目錄都可以定義自己的 layout.tsx,形成巢狀包裝結構。


❓ Q3: 如果我不寫 layout.tsx 會怎樣?

A: 畫面會照樣顯示,但你就無法包共用的元件(像是 Header、Footer、Provider)。


✅ 建議實作順序

  1. 建立 app/layout.tsx:放 header/footer

  2. 建立 app/page.tsx:顯示首頁

  3. 建立 app/about/page.tsx:新增新頁面

  4. 觀察 children 如何把 page 內容塞進 layout


以下是這篇教學的視覺化圖解,讓初學者更清楚了解 layout.tsxpage.tsxchildren 在 Next.js App Router 中是如何串接的。


🖼️ 圖解:layout.tsx 如何包住 page.tsx

          Next.js 組合畫面邏輯流程
┌─────────────────────────────┐
│         app/layout.tsx      │
│ ┌─────────────────────────┐ │
│ │       <html>            │ │
│ │       <body>            │ │
│ │   ┌───────────────┐     │ │
│ │   │  <Header />   │     │ │
│ │   └───────────────┘     │ │
│ │   ┌───────────────┐     │ │
│ │   │  {children}   │◄────┼─┐ ← 自動注入
│ │   └───────────────┘     │ │
│ │   ┌───────────────┐     │ │
│ │   │  <Footer />   │     │ │
│ │   └───────────────┘     │ │
│ │       </body>           │ │
│ │       </html>           │ │
│ └─────────────────────────┘ │
└─────────────────────────────┘
             ▲
             │
      ┌───────────────┐
      │ app/page.tsx  │
      └───────────────┘
      內容例如:
      export default function Page() {
        return <div>Hello</div>;
      }

🧠 圖解說明:

  • layout.tsx 是整個頁面的外框(包含 <html>, <body>, Header, Footer)

  • {children} 是一個「插槽」,Next.js 會自動把 page.tsx 的內容放進去

  • 你不需要自己寫 props 傳入 children,Next.js 幫你處理好

  • 如果你有巢狀 layout,每一層都是這樣一層一層包下去