Pages and Layouts
続ける前に、Routing Fundamentals と Defining Routes のページを読むことをお勧めします。
特別なファイル layout.js、page.js、および template.js を使用すると、route の UI を作成できます。このページでは、これらの特別なファイルをいつどのように使用するかについてガイドします。
Pages
A page は、route に固有の UI です。 page.js
ファイルから component を default で export することにより、page を定義することができます。
例えば、index
ページを作成するには、app
ディレクトリ内にpage.js
ファイルを追加します:
// `app/page.tsx` is the UI for the `/` URL
export default function Page() {
return <h1>Hello, Home page!</h1>
}
// `app/page.js` is the UI for the `/` URL
export default function Page() {
return <h1>Hello, Home page!</h1>
}
次に、さらなるページを作成するために、新しいフォルダを作成し、そこにpage.js
ファイルを追加します。例えば、/dashboard
route のページを作成するためには、dashboard
という新しいフォルダを作成し、それにpage.js
ファイルを追加します:
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}
// `app/dashboard/page.js` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}
Good to know:
- ページには、
.js
、.jsx
、または.tsx
ファイル拡張子を使用することができます。- ページは常に route Subtree の Leaf です。
page.js
ファイルは route セグメントを公開でアクセス可能にするために必要です。- ページは default で Server Components ですが、Client Component に設定することもできます。
- ページは fetch データができます。詳しくは、データ取得 セクションをご覧ください。
Layouts
layout は、複数の routes 間で共有される UI です。ナビゲーションでは、レイアウトは状態を保持し、インタラクティブ性を維持し、再レンダリングされません。また、レイアウトはネストすることもできます。
layout.js
ファイルから React component を default で export することで、layout を定義することができます。component は、レンダリング時に children の layout (存在する場合)またはページで設定される children
prop を受け入れるべきです。
例えば、layout は/dashboard
や/dashboard/settings
のページと共有されます。
export default function DashboardLayout({
children, // will be a page or nested layout
}: {
children: React.ReactNode
}) {
return (
<section>
{/* Include shared UI here e.g. a header or sidebar */}
<nav></nav>
{children}
</section>
)
}
export default function DashboardLayout({
children, // will be a page or nested layout
}) {
return (
<section>
{/* Include shared UI here e.g. a header or sidebar */}
<nav></nav>
{children}
</section>
)
}
Root Layout (必須)
app
ディレクトリの最上位で定義される root layout は、すべての routes に適用されます。この layout は必須であり、html
とbody
タグを含む必要があります。これにより、 server から返される初期の HTML を変更することができます。
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* Layout UI */}
<main>{children}</main>
</body>
</html>
)
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{/* Layout UI */}
<main>{children}</main>
</body>
</html>
)
}
ネストする Layout
default により、フォルダ階層内の Layout は ネストされています。つまり、children
プロパティを介して子 Layout をラップします。特定の route セグメント(フォルダ)内にlayout.js
を追加することで、Layout をネストできます。
たとえば、/dashboard
の route に layout を作成するには、dashboard
フォルダ内に新しいlayout.js
ファイルを追加します。
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
export default function DashboardLayout({ children }) {
return <section>{children}</section>
}
上記の 2 つの Layout を組み合わせると、root layout(app/layout.js
)が dashboard layout(app/dashboard/layout.js
)をラップし、それがapp/dashboard/*
内の route のセグメントをラップします。
2 つの Layout は次のようにネストされるでしょう:
Good to know:
- Layout には、
.js
、.jsx
、または.tsx
のファイル拡張子を使用できます。- root layout のみが
<html>
および<body>
タグを含むことができます。- 同じフォルダ内で
layout.js
とpage.js
ファイルが定義されているとき、layout はページをラップします。- Layout は default では Server Components ですが、Client Component に設定することも可能です。
- Layouts は fetch することができます。詳しくは Data fetching セクションをご覧ください。
- 親の layout からその children へデータを渡すことはできません。ただし、同じデータを route で複数回 fetch することが可能で、React は自動的に重複 Request を除去します。これによりパフォーマンスに影響を与えることはありません。
- Layout は、それ自体の下の route セグメントにアクセスすることはできません。全ての route セグメントにアクセスするためには、Client Component 内で
useSelectedLayoutSegment
またはuseSelectedLayoutSegments
を使用できます。- あなたは Route Groups を使用して、特定の route セグメントを共有 Layout に含めたり除外したりすることができます。
- Route Groupsを使用して複数の rootLayout を作成することができます。こちら で例をご覧ください。
pages
ディレクトリからの移行: root layout は、_app.js
ファイルと_document.js
ファイルを置き換えます。移行ガイドを見る。
Templates
Templates は、各 children の layout や page をラップする点で layouts に似ています。Layouts が routes を通じて持続し状態を保持するのとは異なり、Templates はナビゲーションごとにその children に対して新しいインスタンスを作成します。これは、ユーザーが同じ template を共有する routes 間を移動するとき、 component の新しいインスタンスがマウントされ、DOM 要素が再作成され、状態は保持されず、効果は再同期されることを意味します。
特定の動作が必要な場合があり、そのような場合にはテンプレートの方が Layout よりも適しているかもしれません。例えば:
useEffect
に依存する機能(例:ページビューのログ取り)やuseState
に依存する機能(例:ページごとのフィードバックフォーム)- default のフレームワークの挙動を変更する。例えば、 Suspense バウンダリは、ページを切り替えるときではなく、 Layout が最初に読み込まれるときにだけ fallback を表示します。テンプレートについては、 fallback は各ナビゲーションで表示されます。
template は、template.js
ファイルから default React component を export することで定義できます。component は、children
プロップを受け入れるべきです。
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
export default function Template({ children }) {
return <div>{children}</div>
}
ネスティングに関して、template.js
は layout とその children の間でレンダリングされます。ここには簡略化した出力があります:
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
Metadata
app
ディレクトリでは、title
や meta
などの HTML の <head>
要素を Metadata APIs を使用して変更することができます。
Metadata は、Metadata
object または generateMetadata
function をエクスポートすることで定義できます。これは layout.js
ファイルや page.js
ファイルで行います。
import { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
export const metadata = {
title: 'Next.js',
}
export default function Page() {
return '...'
}
Good to know: あなたは手動で
<head>
タグ、例えば<title>
や<meta>
を root レイアウトに追加すべきではありません。代わりに、ストリーミングや<head>
要素の重複解除などの高度な要求を自動的に処理するMetadata API を使用するべきです。
API reference で利用可能な metadata options について詳しく学びましょう。