Contents
App Routerとpagesディレクトリ構造の選択
Next.js 13以降では、App Routerが推奨されるため、pagesディレクトリ構造は非公式にサポートされており、将来的な廃止リスクがあります。
App Router vs pagesディレクトリ比較表
| 項目 | App Router | pagesディレクトリ |
|---|---|---|
| 推奨状況 | ✅ 推奨(Next.js 13以降) | ❌ 非推奨(2023年現在) |
| ルーティング仕様 | ファイル構造に従う(app/以下) |
pages/内での動的セグメント記法([id].tsxなど) |
| データフェッチのサポート | fetch APIやカスタムフックで柔軟対応可能 |
getStaticProps・getServerSidePropsが中心 |
| SSG/SSRの実装 | デフォルトでサポート(Next.js 13以降) | 明示的な設定が必要 |
注意:
App Routerでは動的セグメントを記述する際、app/[id]/page.tsxなどとファイル構造に沿った方法が必須です。pagesディレクトリ構造は今後も使用可能ですが、新しいプロジェクトではApp Routerの採用を強く推奨します。
動的セグメントの記法とURL設計のベストプラクティス
Next.js 13では動的ルーティングを実装するには、pagesディレクトリ内に[id].tsxなどの形式でファイルを作成します。しかし、動的セグメントをネストさせた場合(例:/users/[userId]/posts/[postId])は、パラメータの順序や語彙の統一が重要です。
動的セグメント記法のルール
- パラメータ名には意味のある単語を使う(例:
[userId],[postId]ではなく[id]と限定すると特定性が低くなる) - 組み合わせたURLは、人間にとって読みやすく、SEO対策にもつながる(例:
/blog/[year]/[month]/[slug].tsx)
パラメータの順序とネスト設計
| ケース | URL構造 | 説明 |
|---|---|---|
| ブログ記事詳細ページ | /posts/[id] |
意味が明確で、SEOにも最適。IDは一意の識別子として扱える。 |
| ユーザー投稿一覧ページ | /users/[userId]/posts |
ユーザーIDを固定し、下位セグメントに投稿情報を並べる構造。 |
| カテゴリ・スラッグによる動的ルーティング | /[category]/[id] |
カテゴリ名とIDの組み合わせで柔軟なURL設計が可能。 |
注意:
パラメータ順序を逆にすることで、セマンティックな構造を破壊する可能性があるため、一貫性を持たせることを最優先してください。
[id].tsxファイルの実装例とデータフェッチロジック
動的セグメントでは、[id].tsxなどのファイルを作成することで自動的にルートが生成されます。以下に、データフェッチロジックやエラーハンドリングを含めた実践的なコード例を示します。
サンプルコード: posts/[id]/page.tsx
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; export default function Post() { const router = useRouter(); const [post, setPost] = useState(null); const [error, setError] = useState(null); const { id } = router.query; // データフェッチロジック useEffect(() => { if (!id) return; fetch(`/api/posts/${id}`) .then((res) => res.json()) .then((data) => setPost(data)) .catch((err) => setError('データの取得に失敗しました。')); }, [id]); if (error) { return <div>{error}</div>; } if (!post) { return <div>読み込み中...</div>; } return ( <div> <h1>ID: {post.id}</h1> <p>{post.title}</p> <p>{post.content}</p> </div> ); } |
パラメータ取得時の処理のポイント
router.queryでパラメータを取得する際、初期値のチェックが必須(例:idがundefinedなケース)- API呼び出しは非同期で実行し、エラーハンドリングを明示的に記述
- エラー表示や読み込み中のUIも用意し、ユーザー体験向上
getStaticProps・getServerSidePropsの活用とデータフェッチ手順
Next.jsでは、動的ルーティングと静的生成(SSG)やサーバーサイドレンダリング(SSR)を組み合わせるためにgetStaticProps・getServerSidePropsを使います。以下に各関数の使い分け方と手順を解説します。
getStaticPropsの活用手順
app/[id]/page.tsxにgetStaticPropsを定義する- パラメータ(例:
context.params.id)からAPIにリクエストを送る - 取得したデータを
propsとして返す - ビルド時に全動的ルートが静的に生成される
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
export async function getStaticProps(context) { const { id } = context.params; try { const res = await fetch(`/api/posts/${id}`); const data = await res.json(); return { props: { post: data, }, revalidate: 60, // 1時間ごとに再生成 }; } catch (err) { console.error(err); return { notFound: true }; // 該当するデータがない場合 } } |
getServerSidePropsの活用手順
app/[id]/page.tsxにgetServerSidePropsを定義- リクエストごとにAPIから最新の情報を取得
- ユーザーに対してリアルタイムなデータを表示
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
export async function getServerSideProps(context) { const { id } = context.params; try { const res = await fetch(`/api/posts/${id}`); const data = await res.json(); return { props: { post: data, }, }; } catch (err) { console.error(err); return { notFound: true }; // 該当するデータがない場合 } } |
SSGとSSRの比較
| 項目 | getStaticProps(SSG) | getServerSideProps(SSR) |
|---|---|---|
| 生成タイミング | ビルド時に静的に生成 | 各リクエストごとに生成 |
| パフォーマンス | 高速(キャッシュ可能) | リアルタイムで生成されるため、速度は遅い |
| SEO対策 | 動的ルートも含めて最適化されやすい | 純粋なSSRではURLが動的でもインデックスされる可能性あり |
クエリパラメータと動的セグメントの組み合わせ
Next.jsでは、動的セグメント([id]など)とクエリパラメータ(例:/posts/[id]?sort=asc)を同時に使用可能です。以下にその仕組みと具体的なコード例を示します。
クエリパラメータの取得方法
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { useRouter } from 'next/router'; export default function Page() { const router = useRouter(); const { id, slug } = router.query; const { sort } = router.query; return ( <div> <p>ID: {id}</p> <p>Slug: {slug}</p> <p>Sort: {sort}</p> </div> ); } |
URL設計の例
| ケース | URL | 説明 |
|---|---|---|
| 動的セグメントとクエリパラメータの両方 | /posts/[id]?sort=desc |
IDで絞り込み、並び順を指定する構造が柔軟性がある |
| ネストされた動的セグメント | users/[userId]/posts/[postId] |
ユーザーIDと投稿IDの組み合わせで詳細情報を取得 |
実装手順: 動的ルーティングの導入
Next.js 13における動的ルーティングをプロジェクトに導入するには、以下のような手順を行います。
手順
- App Routerを採用し、
app/ディレクトリを作成 app/[id]/page.tsxという形式でファイルを作成- 動的セグメントのパラメータ(例:
[id])を取得する処理を記述 - データフェッチロジックとエラーハンドリングを追加
getStaticPropsまたはgetServerSidePropsでデータを静的にもしくはリアルタイムに取得
サンプルディレクトリ構成(App Router)
|
1 2 3 4 |
app/ [id]/ page.tsx |
結論と今後の展望
Next.jsの動的ルーティング機能により、柔軟なURL構造やデータフェッチが簡潔に実装可能となりました。特にApp Routerの導入により、将来的にも安定した開発環境を構築できます。ただし、pagesディレクトリ構造は非推奨であるため、新しいプロジェクトでは必ずApp Routerを使用することを推奨します。
今後は、動的セグメントにおけるSEO対策やURL設計の最適化がさらに重要になってきます。そのためにも、今回の記事で紹介したベストプラクティスを参考に、実際のプロジェクトに導入してください。