Sponsor
ChatHubChatHub Use GPT-4, Gemini, Claude 3.5 and more chatbots side-by-side
ここをクリック
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>
  )
}

リファレンス

Props

children (必須)

レイアウトコンポーネントは children プロパティを受け取り、使用する必要があります。レンダリング中、children にはレイアウトがラップしているルートセグメントが入ります。これらは主に子レイアウト(存在する場合)またはページのコンポーネントですが、LoadingErrorなどの特殊ファイルが該当する場合もあります。

params (オプション)

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

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 プロパティはプロミスであるため、値にアクセスするには 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 の両方の共通レイアウトです:

dashboard フォルダにlayout.tsxファイルがあり、settingsとanalyticsフォルダにそれぞれページがある構造を示すファイル図

/dashboard/settings から /dashboard/analytics に移動する場合、/dashboard/analyticspage.tsx はサーバー上で再レンダリングされますが、dashboard/layout.tsx は2つのルート間で共有されるUI要素であるため再レンダリングされません

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

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

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

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

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

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

ClientComponentsで params を読み取る

ClientComponent(async にできない)で params を使用するには、Reactのuse関数を使用してプロミスを読み取ることができます:

app/page.tsx
TypeScript
'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 が導入されました。