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

レイアウトとページの作成方法

Next.jsはファイルシステムベースのルーティングを使用しており、フォルダとファイルを使ってルートを定義できます。このページでは、レイアウトとページの作成方法、およびそれらをリンクする方法を案内します。

ページの作成

ページは特定のルートでレンダリングされるUIです。ページを作成するには、appディレクトリ内にpageファイルを追加し、Reactコンポーネントをデフォルトエクスポートします。たとえば、インデックスページ(/)を作成するには以下のようにします:

page.js 特殊ファイルpage.js 特殊ファイル
app/page.tsx
export default function Page() {
return <h1>Hello Next.js!</h1>
}

レイアウトの作成

レイアウトは複数のページ間で共有されるUIです。ナビゲーション時にレイアウトは状態を保持し、インタラクティブなままで、再レンダリングされません。

レイアウトを定義するには、layoutファイルからReactコンポーネントをデフォルトエクスポートします。このコンポーネントは、ページまたは別のレイアウトとなるchildren propを受け取る必要があります。

たとえば、インデックスページを子として受け入れるレイアウトを作成するには、appディレクトリ内にlayoutファイルを追加します:

layout.js 特殊ファイルlayout.js 特殊ファイル
app/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* レイアウトUI */}
{/* ページまたはネストされたレイアウトをレンダリングしたい場所にchildrenを配置 */}
<main>{children}</main>
</body>
</html>
)
}

上記のレイアウトは、appディレクトリのrootに定義されているため、root レイアウトと呼ばれます。root レイアウトは必須であり、htmlおよびbodyタグを含める必要があります。

ネストされたルートの作成

ネストされたルートは、複数のURLセグメントで構成されるルートです。たとえば、/blog/[slug]ルートは3つのセグメントで構成されています:

  • / (Root Segment)
  • blog (Segment)
  • [slug] (Leaf Segment)

Next.jsでは:

  • フォルダは、URLセグメントにマップされるルートセグメントを定義するために使用されます。
  • ファイルpagelayoutなど)は、セグメントに表示されるUIを作成するために使用されます。

ネストされたルートを作成するには、フォルダを互いにネストできます。たとえば、/blogのルートを追加するには、appディレクトリにblogというフォルダを作成します。次に、/blogを公開アクセス可能にするために、page.tsxファイルを追加します:

blogフォルダとpage.jsファイルを示すファイル階層blogフォルダとpage.jsファイルを示すファイル階層
app/blog/page.tsx
// ダミーインポート
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'

export default async function Page() {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}
app/blog/[slug]/page.js
// ダミーインポート
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'

export default async function Page() {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}

フォルダをさらにネストして、ネストされたルートを作成し続けることができます。たとえば、特定のブログ投稿のルートを作成するには、blog内に新しい[slug]フォルダを作成し、pageファイルを追加します:

blogフォルダにネストされたslugフォルダとpage.jsファイルを示すファイル階層blogフォルダにネストされたslugフォルダとpage.jsファイルを示すファイル階層
app/blog/[slug]/page.tsx
function generateStaticParams() {}

export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}

フォルダ名を角括弧で囲む(例:[slug])と、dynamic route segmentが作成され、データから複数のページを生成するために使用されます。例:ブログ投稿、商品ページなど。

レイアウトのネスト

デフォルトでは、フォルダ階層内のレイアウトもネストされており、children propを介して子レイアウトをラップします。特定のルートセグメント(フォルダ)内にlayoutを追加することで、レイアウトをネストできます。

たとえば、/blogルートのレイアウトを作成するには、blogフォルダ内に新しいlayoutファイルを追加します。

rootレイアウトがblogレイアウトをラップしているファイル階層rootレイアウトがblogレイアウトをラップしているファイル階層
app/blog/layout.tsx
export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}

上記の2つのレイアウトを組み合わせると、root レイアウト(app/layout.js)がブログレイアウト(app/blog/layout.js)をラップし、ブログ(app/blog/page.js)およびブログ投稿ページ(app/blog/[slug]/page.js)をラップします。

ページ間のリンク

ルート間をナビゲートするには、<Link>コンポーネントを使用できます。<Link>は、HTMLの<a>タグを拡張してプリフェッチクライアントサイドナビゲーションを提供する、Next.jsの組み込みコンポーネントです。

たとえば、ブログ投稿のリストを生成するには、next/linkから<Link>をインポートし、コンポーネントにhref propを渡します:

app/ui/post.tsx
import Link from 'next/link'

export default async function Post({ post }) {
const posts = await getPosts()

return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}

<Link>は、Next.jsアプリケーション内でルート間をナビゲートするための主要で推奨される方法です。ただし、より高度なナビゲーションにはuseRouterフックを使用することもできます。