Skip to content

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専用の設定ファイル。プロジェクト固有のルールやコンテキストを記述する。
# プロジェクト概要
このプロジェクトは 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)} />;
}
  • サーバーコンポーネントでは直接 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>;
}
// ❌ 非推奨: サーバーコンポーネントでのuseEffect
export 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();
  • サーバーアクションでは 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 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が代表例。
// 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
マイグレーション: データベースのスキーマ(テーブル構造)を安全に変更するための手順書。スキーマ: データベースのテーブル構造や型定義のこと。
.env.local
DATABASE_URL="postgresql://..."
NEXTAUTH_SECRET="..."
NEXTAUTH_URL="http://localhost:3000"
  • 環境変数は必ず .env.local に記述(.env はバージョン管理対象)
  • クライアント側で使う変数は NEXT_PUBLIC_ プレフィックスをつける
  • 型安全な環境変数管理には @t3-oss/env-nextjs を使う
環境変数: APIキーやデータベース接続情報など、コードに直接書きたくない値をOSやサーバーに設定する仕組み。型安全: 変数や関数の型をコンパイル時にチェックし、型の不一致によるバグを防ぐ設計方針。
Terminal window
# ユニットテスト
npx vitest run
# ウォッチモード
npx vitest
# カバレッジ
npx vitest run --coverage
  • コンポーネントテストは src/components/__tests__/ に配置
  • APIテストは src/app/api/__tests__/ に配置
  • テストファイルは *.test.tsx または *.spec.tsx
Terminal window
# 開発サーバー起動
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. **コーディング規約**: チームで決めたルール(命名規則、ファイル分割の粒度など)を追加してください。
:::note
CLAUDE.mdはプロジェクトルートに置くほか、サブディレクトリにも配置できます。例えば `src/app/` に配置すると、そのディレクトリ以下でのみ有効なルールを設定できます。
:::
SSR: Server-Side Rendering の略。HTMLをサーバー側で生成してブラウザに送る方式。SEOや初期表示速度に優れる。