メインコンテンツまでスキップ

layout.js

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

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

root レイアウトは、root 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 propを受け入れ、使用する必要があります。レンダリング中に、childrenはレイアウトがラップしているルートセグメントで埋められます。これらは主に子Layout(存在する場合)またはPageのコンポーネントですが、適用される場合にはLoadingErrorなどの他の特別なファイルである可能性もあります。

params(オプション)

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

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 propはプロミスであるため、値にアクセスするにはasync/awaitまたはReactのuse関数を使用する必要があります。
    • バージョン14以前では、paramsは同期的なpropでした。後方互換性を助けるために、Next.js 15ではまだ同期的にアクセスできますが、この動作は将来的に廃止される予定です。

Root レイアウト

appディレクトリには、root app/layout.js必須です。

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

注意点

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

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

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

たとえば、次のディレクトリ構造では、dashboard/layout.tsx/dashboard/settings/dashboard/analyticsの両方の共通レイアウトです:

dashboardフォルダがlayout.tsxファイルをネストし、settingsとanalyticsフォルダがそれぞれのページを持つファイル構造dashboardフォルダがlayout.tsxファイルをネストし、settingsとanalyticsフォルダがそれぞれのページを持つファイル構造

/dashboard/settingsから/dashboard/analyticsにナビゲートすると、/dashboard/analyticspage.tsxはサーバーで再レンダリングされますが、dashboard/layout.tsxは2つのルート間で共有される共通UIであるため、再レンダリングされません。

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

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

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

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

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

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

app/dashboard/layout.tsx
import { ClientComponent } from '@/app/ui/ClientComponent'

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<ClientComponent />
{/* 他のレイアウト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}のダッシュボード</h1>
</header>
<main>{children}</main>
</section>
)
}

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