layout.js

レイアウト (layout) とは、複数のルート間で共有される UI です。

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

ルートレイアウト (root layout) は、ルート app ディレクトリの最上位レイアウトです。<html> タグや <body> タグ、その他のグローバルに共有される UI を定義するために使用されます。

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

Props

children (必須)

レイアウトコンポーネントは children prop を受け取り、使用する必要があります。レンダリング時、children にはレイアウトがラップしているルートセグメントが含まれます。これには主に子の レイアウト コンポーネント(存在する場合)や ページ コンポーネントが含まれますが、状況に応じて ローディングエラー などの特別なファイルも含まれる可能性があります。

params (オプション)

ルートセグメントからそのレイアウトまでの 動的ルートパラメータ オブジェクトです。

URLparams
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'] }

例:

export default function ShopLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: {
    tag: string
    item: string
  }
}) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}
export default function ShopLayout({ children, params }) {
  // URL -> /shop/shoes/nike-air-max-97
  // `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
  return <section>{children}</section>
}

知っておくと便利な情報

レイアウトは searchParams を受け取らない

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

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

例えば、以下のディレクトリ構造では、dashboard/layout.tsx/dashboard/settings/dashboard/analytics の両方の共通レイアウトになります:

ダッシュボードフォルダ内に配置された layout.tsx ファイルと、settings および analytics フォルダ内のページを示すファイル構造

/dashboard/settings から /dashboard/analytics にナビゲートする場合、/dashboard/analyticspage.tsx はサーバー上で再レンダリングされますが、dashboard/layout.tsx は再レンダリングされません。これは両ルート間で共有される共通 UI だからです。

このパフォーマンス最適化により、レイアウトを共有するページ間のナビゲーションが高速化されます。ページのデータ取得とレンダリングのみが実行され、独自のデータを取得する可能性のある共有レイアウトを含むルート全体が実行されることはありません。

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

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

ルートレイアウト

  • app ディレクトリには必ずルート app/layout.js を含める必要があります。
  • ルートレイアウトには必ず <html> タグと <body> タグを定義する必要があります。
    • ルートレイアウトに <title><meta> などの <head> タグを手動で追加するべきではありません。代わりに、ストリーミングや <head> 要素の重複排除などの高度な要件を自動的に処理する メタデータ API を使用してください。
  • ルートグループ を使用して複数のルートレイアウトを作成できます。
    • 複数のルートレイアウト間をナビゲート すると、ページ全体の再読み込み が発生します(クライアントサイドナビゲーションとは異なります)。例えば、app/(shop)/layout.js を使用する /cart から app/(marketing)/layout.js を使用する /blog にナビゲートすると、ページ全体が再読み込みされます。これは 複数のルートレイアウト にのみ適用されます。

バージョン履歴

バージョン変更点
v13.0.0layout が導入されました。