Menu

layout.js

layoutファイルは、Next.jsアプリケーションでレイアウトを定義するために使用されます。

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

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

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

リファレンス

プロップ

children(必須)

レイアウトコンポーネントはchildrenプロップを受け取り、使用する必要があります。レンダリング時、childrenにはレイアウトがラップするルートセグメントが設定されます。これは主に子のレイアウト(存在する場合)またはページのコンポーネントになりますが、該当する場合はローディングエラーなどの特殊なファイルも含まれます。

params(オプション)

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

app/dashboard/[team]/layout.tsx
TypeScript
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プロップはPromiseであるため、値にアクセスするにはasync/awaitまたはReactのuse関数を使用する必要があります。
    • バージョン14以前では、paramsは同期的なプロップでした。下位互換性のため、Next.js 15では引き続き同期的にアクセスできますが、この動作は将来非推奨になります。

ルートレイアウト

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

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

注意事項

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

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

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

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

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

代わりに、pathnameに依存するロジックをクライアントコンポーネントに抽出し、それをレイアウトにインポートできます。クライアントコンポーネントはナビゲーション中に再レンダリングされる(ただし再フェッチはされない)ため、Next.jsのusePathnameなどのフックを使用して現在のpathnameにアクセスし、陳腐化を防ぐことができます。

app/dashboard/layout.tsx
TypeScript
import { ClientComponent } from '@/app/ui/ClientComponent'
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <ClientComponent />
      {/* その他のレイアウトUI */}
      <main>{children}</main>
    </>
  )
}

一般的なpathnameパターンは、paramsプロップを使用して実装することもできます。

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

paramsに基づいたコンテンツの表示

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

app/dashboard/layout.tsx
TypeScript
export default async function DashboardLayout({
  children,
  params,
}: {
  children: React.ReactNode
  params: Promise<{ team: string }>
}) {
  const { team } = await params
 
  return (
    <section>
      <header>
        <h1>{team}のダッシュボードへようこそ</h1>
      </header>
      <main>{children}</main>
    </section>
  )
}

クライアントコンポーネントでの params の読み取り

async ではない)クライアントコンポーネントで params を使用するには、Reactのuse関数を使用してプロミスを読み取ることができます:

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

バージョン履歴

バージョン変更点
v15.0.0-RCparams が現在プロミスです。コードモッドが利用可能です。
v13.0.0layout が導入されました。