コンテンツにスキップ

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 には、レイアウトがラップしているルートセグメントが設定されます。これらは主に子レイアウト(存在する場合)またはページのコンポーネントになりますが、該当する場合はLoadingErrorなどの他の特別なファイルになる場合もあります。

params (オプション)

ルートセグメントのルートからそのレイアウトまでの動的ルートパラメーターオブジェクトを含むオブジェクトに解決されるプロミス。

app/dashboard/[team]/layout.tsx
export default async function Layout({
  params,
}: {
  params: Promise<{ team: string }>
}) {
  const team = (await params).team
}
ルートの例URLparams
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 プロパティはプロミスなので、値にアクセスするには async/await または React のuse関数を使用する必要があります。
    • バージョン 14 以前では、params は同期的な prop でした。後方互換性を保つため、Next.js 15 では引き続き同期的にアクセスできますが、この動作は将来的に非推奨となる予定です。

ルートレイアウト

app ディレクトリには、ルートとなる app/layout.js を **必ず** 含める必要があります。

app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>{children}</body>
    </html>
  )
}
  • ルートレイアウトは、<html><body> タグを **必ず** 定義する必要があります。
    • ルートレイアウトに <title><meta> などの <head> タグを手動で追加するべきでは **ありません**。代わりに、Metadata API を使用する必要があります。これは、ストリーミングや <head> 要素の重複排除などの高度な要件を自動的に処理します。
  • 複数のルートレイアウトを作成するには、ルートグループを使用できます。
    • **複数のルートレイアウト間** をナビゲートすると、(クライアントサイドナビゲーションではなく) **ページ全体のリロード** が発生します。たとえば、app/(shop)/layout.js を使用する /cart から、app/(marketing)/layout.js を使用する /blog へナビゲートすると、ページ全体のリロードが発生します。これは、**複数のルートレイアウト** にのみ適用されます。

注意点

レイアウトは searchParams を受け取りません

ページとは異なり、レイアウトコンポーネントは searchParams prop を **受け取りません**。これは、共有レイアウトが ナビゲーション中に再レンダリングされない ため、ナビゲーション間で searchParams が古くなる可能性があるためです。

クライアントサイドナビゲーションを使用する場合、Next.js は自動的に、2 つのルート間で共通のレイアウトの下にあるページの部分のみをレンダリングします。

たとえば、次のディレクトリ構造では、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/analyticspage.tsx はサーバー上で再レンダリングされますが、dashboard/layout.tsx は、2 つのルート間で共有される共通の UI であるため、**再レンダリングされません**。

このパフォーマンス最適化により、レイアウトを共有するページ間のナビゲーションが高速になります。これは、共有レイアウトが独自のデータをフェッチする可能性があるルート全体ではなく、ページのデータフェッチとレンダリングのみを実行する必要があるためです。

dashboard/layout.tsx は再レンダリングされないため、レイアウトサーバーコンポーネントの searchParams prop は、ナビゲーション後に **古くなる** 可能性があります。

代わりに、ページ searchParams prop、またはレイアウト内のクライアントコンポーネントの useSearchParams フックを使用してください。これは、最新の searchParams でクライアント上で再レンダリングされます。

レイアウトは pathname にアクセスできません

レイアウトは pathname にアクセスできません。これは、レイアウトがデフォルトでサーバーコンポーネントであり、クライアントサイドナビゲーション中に再レンダリングされないため、ナビゲーション間で pathname が古くなる可能性があるためです。古くなることを防ぐために、Next.js はルートのすべてのセグメントを再フェッチする必要があり、キャッシュの利点が失われ、ナビゲーション時の RSC ペイロードサイズが増加します。

代わりに、pathname に依存するロジックをクライアントコンポーネントに抽出し、レイアウトにインポートできます。クライアントコンポーネントはナビゲーション中に再レンダリングされる (ただし、再フェッチはされない) ため、usePathname などの Next.js フックを使用して現在の 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 prop で実装することもできます。

詳細については、セクションを参照してください。

params に基づいてコンテンツを表示する

動的ルートセグメントを使用すると、params prop に基づいて特定のコンテンツを表示またはフェッチできます。

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 になりました。codemod が利用可能です。
v13.0.0layout が導入されました。