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

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 groupを使用して、複数の root レイアウトを作成できます
    • 複数の root レイアウトをまたいでナビゲートすると、クライアントサイドのナビゲーションとは対照的にフルページロードが発生します。たとえば、/cartapp/(shop)/layout.jsを使用)から、/blogapp/(marketing)/layout.jsを使用)にナビゲートすると、フルページロードが発生します。これは、複数の root レイアウトにのみ該当します

注意事項

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

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

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

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

layout.tsx ファイルをネストするダッシュボードフォルダ、および独自のページを持つ設定と分析フォルダを示すファイル構造layout.tsx ファイルをネストするダッシュボードフォルダ、および独自のページを持つ設定と分析フォルダを示すファイル構造

/dashboard/settings から /dashboard/analytics へとナビゲートする際、page.tsx/dashboard/analytics 上でサーバーで再描画されますが、dashboard/layout.tsx は共通のUIであるため再描画されません

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

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

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

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

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

代わりに、pathname に依存するロジックをクライアントコンポーネントに抽出し、それをレイアウトにインポートすることができます。クライアントコンポーネントはナビゲーション時に再レンダリングされる(ただし再取得されるわけではない)ため、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 で実装できます。

詳細は examples セクションをご覧ください。

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}'s Dashboard</h1>
</header>
<main>{children}</main>
</section>
)
}

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

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

app/page.tsx
'use client'

import { use } from 'react'

export function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = use(params)
}

バージョン履歴

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