Next.jsプロジェクト用CLAUDE.mdテンプレート
なぜNext.js専用のCLAUDE.mdが必要か
Section titled “なぜNext.js専用のCLAUDE.mdが必要か”Next.jsはApp RouterとPages Routerという2つのパラダイムが混在し、サーバーコンポーネントとクライアントコンポーネントの区別、use clientの付け忘れによるバグなど、フレームワーク固有の落とし穴が多くあります。
Claude Codeにこれらのルールを事前に伝えておくことで、生成されるコードの品質が大幅に向上します。「App Routerで書いて」と毎回指示しなくても、プロジェクトのルールに従ったコードを生成してくれます。
※TypeScript: JavaScriptに型定義を追加した言語。型チェックによりバグを事前に発見しやすくなる。※CLAUDE.md: プロジェクトのルートに置くClaude Code専用の設定ファイル。プロジェクト固有のルールやコンテキストを記述する。
テンプレート本体
Section titled “テンプレート本体”# プロジェクト概要
このプロジェクトは Next.js 14 (App Router) + TypeScript + Tailwind CSS + Prisma で構築された [プロジェクト名] です。
## 技術スタック
- **フレームワーク**: Next.js 14 (App Router)- **言語**: TypeScript 5.x(`strict: true`)- **スタイリング**: Tailwind CSS 3.x- **ORM**: Prisma 5.x- **データベース**: PostgreSQL (Supabase)- **認証**: NextAuth.js v5- **テスト**: Vitest + React Testing Library- **デプロイ**: Vercel
## ディレクトリ構造src/ ├── app/ # App Router ページ・レイアウト │ ├── (auth)/ # ルートグループ(認証済みページ) │ ├── api/ # API Routes │ └── layout.tsx # ルートレイアウト ├── components/ │ ├── ui/ # 汎用UIコンポーネント │ └── features/ # 機能単位のコンポーネント ├── lib/ │ ├── db.ts # Prismaクライアント │ └── auth.ts # 認証設定 ├── hooks/ # カスタムフック ├── types/ # 型定義 └── utils/ # ユーティリティ関数
## コーディング規約
### サーバーコンポーネント vs クライアントコンポーネント
**デフォルトはサーバーコンポーネント**。以下の場合のみ `'use client'` を追加する:- `useState`、`useEffect` 等のReactフックを使用する場合- ブラウザAPIを使用する場合(`window`、`document`等)- イベントハンドラを直接使用する場合(`onClick` 等)
```typescript// サーバーコンポーネント(デフォルト)export default async function ProductList() { const products = await db.product.findMany(); return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;}
// クライアントコンポーネント(必要な場合のみ)'use client';import { useState } from 'react';
export function SearchInput() { const [query, setQuery] = useState(''); return <input value={query} onChange={e => setQuery(e.target.value)} />;}データフェッチング
Section titled “データフェッチング”- サーバーコンポーネントでは直接
async/awaitを使う - クライアント側では
useSWRまたは React Query を使う - API Routesは
src/app/api/以下に配置する
// ✅ 推奨: サーバーコンポーネントでの直接フェッチexport default async function Page() { const data = await fetch('https://api.example.com/data', { next: { revalidate: 60 } // 60秒キャッシュ }); return <div>{data.title}</div>;}
// ❌ 非推奨: サーバーコンポーネントでのuseEffectexport default function Page() { useEffect(() => { fetch(...) }, []); // サーバーコンポーネントではNG}any型の使用は禁止(eslint: @typescript-eslint/no-explicit-any)- Prismaが生成した型を積極的に使う
- APIレスポンスの型は
src/types/api.tsに集約する
// ✅ 推奨import type { User, Post } from '@prisma/client';
type PostWithAuthor = Post & { author: Pick<User, 'id' | 'name' | 'image'>;};
// ❌ 非推奨const data: any = await fetchData();エラーハンドリング
Section titled “エラーハンドリング”- サーバーアクションでは Result 型パターンを使う
- ユーザー向けエラーは
error.tsxで処理する
// サーバーアクションexport async function createPost(data: CreatePostInput) { try { const post = await db.post.create({ data }); return { success: true, data: post }; } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError) { return { success: false, error: 'データベースエラーが発生しました' }; } return { success: false, error: '予期しないエラーが発生しました' }; }}Tailwind CSS
Section titled “Tailwind CSS”- クラスの並び順は公式推奨順(Tailwind CSS IntelliSense が自動整列)
cn()ユーティリティを使って条件付きクラスを管理する
import { clsx, type ClassValue } from 'clsx';import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs));}
// 使用例<button className={cn( 'px-4 py-2 rounded-md font-medium', isPrimary && 'bg-blue-500 text-white', isDisabled && 'opacity-50 cursor-not-allowed')} />※キャッシュ: 一度取得したデータを一時的に保存しておき、同じリクエストへの応答を速くする仕組み。※デプロイ: 開発したコードを本番サーバーに公開・適用すること。※API: Application Programming Interface の略。外部サービスとプログラム間でデータをやりとりするための接続口。※ORM: Object-Relational Mapping の略。データベースのテーブルをプログラムのオブジェクトとして扱えるようにするライブラリ。PrismaやActiveRecordが代表例。
データベース操作
Section titled “データベース操作”Prismaの使い方
Section titled “Prismaの使い方”// lib/db.ts - シングルトンパターンimport { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined;};
export const db = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') { globalForPrisma.prisma = db;}- マイグレーションは
npx prisma migrate devで実行 - スキーマ変更後は必ず
npx prisma generateを実行する - 本番では
npx prisma migrate deploy
※マイグレーション: データベースのスキーマ(テーブル構造)を安全に変更するための手順書。※スキーマ: データベースのテーブル構造や型定義のこと。
DATABASE_URL="postgresql://..."NEXTAUTH_SECRET="..."NEXTAUTH_URL="http://localhost:3000"- 環境変数は必ず
.env.localに記述(.envはバージョン管理対象) - クライアント側で使う変数は
NEXT_PUBLIC_プレフィックスをつける - 型安全な環境変数管理には
@t3-oss/env-nextjsを使う
※環境変数: APIキーやデータベース接続情報など、コードに直接書きたくない値をOSやサーバーに設定する仕組み。※型安全: 変数や関数の型をコンパイル時にチェックし、型の不一致によるバグを防ぐ設計方針。
# ユニットテストnpx vitest run
# ウォッチモードnpx vitest
# カバレッジnpx vitest run --coverage- コンポーネントテストは
src/components/__tests__/に配置 - APIテストは
src/app/api/__tests__/に配置 - テストファイルは
*.test.tsxまたは*.spec.tsx
よく使うコマンド
Section titled “よく使うコマンド”# 開発サーバー起動npm run dev
# ビルドnpm run build
# リントnpm run lint
# 型チェックnpx tsc --noEmit
# Prismaマイグレーションnpx prisma migrate dev --name <migration-name>
# Prisma Studio(データ閲覧)npx prisma studio※npm: Node.jsのパッケージ管理ツール。`npm install` でライブラリをインストールする。
src/app/以下にpage.tsxを作成する際は必ずメタデータを設定する- 画像は
next/imageを使う(<img>タグは使わない) - リンクは
next/linkを使う(<a>タグは使わない) - フォント最適化には
next/fontを使う
## 各セクションの説明
**技術スタック**: 使用しているライブラリのバージョンを明記します。Claudeがバージョン固有のAPIを使うかどうかの判断材料になります。
**ディレクトリ構造**: ファイルをどこに置くかをClaudeに伝えます。これがないと、コンポーネントが `components/` に作られたり `app/` に直接置かれたりと、バラバラになります。
**サーバーコンポーネント vs クライアントコンポーネント**: Next.jsで最もよくあるミス。`use client` を付けすぎると SSR のメリットが失われます。
**エラーハンドリング**: プロジェクト全体で一貫したパターンを使うために明記します。
## カスタマイズのポイント
1. **技術スタックのバージョン番号**: 実際のバージョンに更新してください。Claudeはバージョンによって使えるAPIが変わることを理解しています。
2. **ディレクトリ構造**: 実際の `src/` ディレクトリ構造に合わせて更新してください。`tree` コマンドの出力をそのまま貼り付けるのが最速です。
3. **使用していない技術は削除**: Prismaを使っていない場合は該当セクションを削除します。ClaudeはCLAUDE.mdの内容を真剣に読むので、不要な情報は混乱のもとになります。
4. **コーディング規約**: チームで決めたルール(命名規則、ファイル分割の粒度など)を追加してください。
:::noteCLAUDE.mdはプロジェクトルートに置くほか、サブディレクトリにも配置できます。例えば `src/app/` に配置すると、そのディレクトリ以下でのみ有効なルールを設定できます。:::※SSR: Server-Side Rendering の略。HTMLをサーバー側で生成してブラウザに送る方式。SEOや初期表示速度に優れる。