コンテンツへスキップ

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のコンポーネントになりますが、適用可能な場合はLoadingErrorのような他の特殊なファイルであることもあります。

params (オプション)

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

app/dashboard/[team]/layout.tsx
export default async function Layout({
  params,
}: {
  params: Promise<{ team: string }>
}) {
  const { team } = await params
}
ルートの例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は同期プロップでした。下位互換性のため、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を受け取らない

ページとは異なり、Layoutコンポーネントは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/analytics内のpage.tsxはサーバーで再レンダリングされますが、dashboard/layout.tsxは両方のルート間で共有される共通UIであるため、再レンダリング**されません**。

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

dashboard/layout.tsxは再レンダリングされないため、レイアウトのServer Component内のsearchParamsプロップはナビゲーション後に**古くなる**可能性があります。

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

レイアウトはpathnameにアクセスできない

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

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

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の読み取り

Client Component(asyncにすることはできません)でparamsを使用するには、Reactのuse関数を使用してプロミスを読み取ることができます。

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

バージョン履歴

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