Next.js ベストプラクティス
Next.js App Router 開発の原則です。
1. サーバーコンポーネントとクライアントコンポーネント
判断ツリー
Does it need...?
│
├── useState, useEffect, event handlers
│ └── Client Component ('use client')
│
├── Direct data fetching, no interactivity
│ └── Server Component (default)
│
└── Both?
└── Split: Server parent + Client child
デフォルトの方針
| 種類 | 用途 |
|---|
| サーバー | データ取得、レイアウト、静的コンテンツ |
| クライアント | フォーム、ボタン、インタラクティブな UI |
2. データ取得パターン
フェッチ戦略
| パターン | 用途 |
|---|
| デフォルト | 静的(ビルド時にキャッシュ) |
| Revalidate | ISR(時間ベースの再生成) |
| No-store | 動的(リクエストごと) |
データフロー
| ソース | パターン |
|---|
| データベース | サーバーコンポーネントでのフェッチ |
| API | キャッシュ付き fetch |
| ユーザー入力 | クライアントの状態 + サーバーアクション |
3. ルーティングの原則
ファイル規則
| ファイル | 用途 |
|---|
page.tsx | ルートの UI |
layout.tsx | 共有レイアウト |
loading.tsx | ローディング状態 |
error.tsx | エラーバウンダリ |
not-found.tsx | 404 ページ |
ルートの構成
| パターン | 用途 |
|---|
ルートグループ (name) | URL に影響させずに整理 |
パラレルルート @slot | 同じ階層の複数ページ |
インターセプト (.) | モーダルオーバーレイ |
4. API ルート
ルートハンドラー
| メソッド | 用途 |
|---|
| GET | データの読み取り |
| POST | データの作成 |
| PUT/PATCH | データの更新 |
| DELETE | データの削除 |
ベストプラクティス
- Zod で入力を検証する
- 適切なステータスコードを返す
- エラーを適切に処理する
- 可能な場合は Edge ランタイムを使用する
5. パフォーマンスの原則
画像の最適化
- next/image コンポーネントを使用する
- ファーストビュー内の画像には priority を設定する
- ぼかしのプレースホルダーを用意する
- レスポンシブな sizes を使用する
バンドルの最適化
- 重いコンポーネントは動的インポートにする
- ルート単位のコード分割を利用する(自動)
- バンドルアナライザーで分析する
6. メタデータ
静的と動的
| 種類 | 用途 |
|---|
| 静的エクスポート | 固定のメタデータ |
| generateMetadata | ルートごとの動的なメタデータ |
必須のタグ
- title(50〜60 文字)
- description(150〜160 文字)
- Open Graph 画像
- Canonical URL
7. キャッシュ戦略
キャッシュのレイヤー
| レイヤー | 制御 |
|---|
| リクエスト | fetch のオプション |
| データ | revalidate/tags |
| ルート全体 | ルートの設定 |
再検証
| 方法 | 用途 |
|---|
| 時間ベース | revalidate: 60 |
| オンデマンド | revalidatePath/Tag |
| キャッシュなし | no-store |
8. サーバーアクション
ユースケース
ベストプラクティス
- 'use server' を付けてマークする
- すべての入力を検証する
- 型付きのレスポンスを返す
- エラーを処理する
9. アンチパターン
| ❌ 避けるべき例 | ✅ 推奨 |
|---|
| どこにでも 'use client' | デフォルトはサーバー |
| クライアントコンポーネントでフェッチ | サーバーでフェッチ |
| ローディング状態を省略 | loading.tsx を使用する |
| エラーバウンダリを無視 | error.tsx を使用する |
| 大きなクライアントバンドル | 動的インポート |
10. プロジェクト構成
app/
├── (marketing)/ # Route group
│ └── page.tsx
├── (dashboard)/
│ ├── layout.tsx # Dashboard layout
│ └── page.tsx
├── api/
│ └── [resource]/
│ └── route.ts
└── components/
└── ui/
覚えておくこと: サーバーコンポーネントがデフォルトなのには理由があります。まずはそれを使い、必要な場合にのみクライアントを追加してください。