`use client`を全部に付けてしまう問題を終わらせる──Claude Code × Next.js App RouterのCLAUDE.md設計完全ガイド

はじめに

「Claude CodeにNext.jsのコンポーネントを生成させると、なぜか全部にuse clientが付いてくる」という経験がある人は多いはずだ。App Routerが登場して以来、Server ComponentsとClient Componentsの使い分けは現代のNext.js開発における核心的な設計判断になった。ところがClaude Codeは指示がないと旧パターンを選びやすく、気づかずに使い続けるとパフォーマンスとセキュリティの両方に問題が出る。


App RouterでClaude Codeが間違えやすい3つのパターン

use clientの過剰追加

Claude Codeはデフォルトでuse clientを多用する。その結果、Server Componentで動かすべきデータ取得コンポーネントがクライアント側に移動し、不要なバンドルサイズとウォーターフォールが生まれる。

// Claude Codeが出しやすい旧パターン(use client + useEffectでfetch)
"use client"
import { useEffect, useState } from "react"

export default function ProductList() {
const [products, setProducts] = useState([])
useEffect(() => {
fetch("/api/products").then(r => r.json()).then(setProducts)
}, [])
return

    {products.map(p =>
  • {p.name}
  • )}

}

// 正しいパターン(Server Componentで直接DB取得)
import { db } from "@/lib/db"

export default async function ProductList() {
const products = await db.query.products.findMany()
return

    {products.map(p =>
  • {p.name}
  • )}

}

use clientもAPIルートも不要だ。CLAUDE.mdに「デフォルトはServer Component」「use clientは葉ノードのインタラクティブ要素のみ」と書くだけで、この誤りが出なくなる。

APIルートとServer Actionsの混用

フォーム送信や更新処理にServer Actionsを使うのがApp Routerの現代的なパターンだが、指示がなければClaude Codeは従来型の/api/route.tsを生成しやすい。

// 旧パターン(app/api/todos/route.ts)
export async function POST(req: Request) {
  const { title } = await req.json()
  await db.insert(todos).values({ title })
  return Response.json({ success: true })
}
// Server Actionsパターン(app/actions.ts)
"use server"
import { auth } from "@clerk/nextjs/server"

export async function createTodo(title: string) {
const { userId } = await auth()
if (!userId) throw new Error("Unauthorized")
await db.insert(todos).values({ title, userId })
}

Server ActionはUIコンポーネントのすぐそばにコロケーションできる。APIルートはWebhook受信や外部サービス連携だけに絞るとアーキテクチャが整理される。

キャッシング戦略の無指定

App Routerのデフォルトは静的レンダリングで、Claude Codeはキャッシング指定を省略しやすい。ユーザー固有データが静的キャッシュに載るとセキュリティリスクになるため、cache: 'no-store'を明示する。

const res = await fetch(/api/users/${userId}, { cache: 'no-store' })

CLAUDE.mdでApp Routerのルールを明文化する

# Next.js App Router プロジェクト

技術スタック

Next.js 15 / TypeScript / Tailwind CSS + shadcn/ui / Drizzle ORM + Neon / Clerk

コンポーネント設計

- デフォルト: Server Component(use clientなし) - use clientは useState/useEffect/onClick が必要な葉ノードのみ - データ取得はServer Componentで直接DBクエリを実行

データ取得 & キャッシング

- 静的コンテンツ: デフォルト(指定不要) - 定期更新コンテンツ: export const revalidate = 60 - ユーザー固有データ: cache: 'no-store' を必ず指定

サーバー処理

- ミューテーションはServer Actions(use server)を使う - APIルート(/api/)はWebhook・外部サービス連携のみ - Server Action冒頭では必ず auth() で認証・userId検証

禁止パターン

- Server Componentに use client を不要につける - Client Componentから直接DBアクセス - Server Actionで認証チェックを省略 - ユーザー固有データに cache: 'no-store' を付けない

このCLAUDE.mdをリポジトリにコミットすれば、チーム全員が同じルールでClaude Codeを使える。App RouterのServer/Client Componentは入門者が特に混乱しやすいので、CLAUDE.mdに書いておくとオンボーディングでもそのまま使える。


実践:2時間SaaS構築の内訳(指示1時間45分・実装15分)

Qiita(kawabe0201, 2026年)に、Next.js 15 + Clerk + Neon + DrizzleでメモアプリSaaSを2時間で構築した記録がある(単一の実践報告として参考にしてほしい)。

作業時間
CLAUDE.md作成・指示設計1時間45分
実際のコード実装15分

「コードを書く時間より指示を設計する時間のほうが長い」という逆転が起きている。この事例はClaude Code活用の「指示が9割」という感覚を数字で示している。

実際の作業で押さえておくと良いワークフローを紹介する。

  • /initコマンド: 既存コードを分析してCLAUDE.md草案を自動生成(公式確認済み)。ゼロから書かずに済む。
  • Planモード(Shift+Tab): 「UserDashboardをServer ComponentでDB取得し、Clientのチャートへpropsで渡す設計で」と伝えると、ファイル構成とコンポーネント分割計画を先に出してくれる。承認してから実装に入れる。
  • @ファイルパス参照: 「@app/todos/page.tsxと同じパターンでapp/notes/page.tsxを作って」と伝えると既存コードをベースに一貫したコードが出る。

EM視点──チームのApp Router開発を整える

Claude Codeが生成したコードのレビューは「アーキテクチャの選択が正しいか」を先に見ると効率的だ。

  • use clientが本当に必要な場所だけについているか
  • Server Actionの冒頭に認証チェックがあるか
  • ユーザー固有データにcache: 'no-store'が付いているか

CLAUDE.mdにこれらを明記しておけば、Claude Code自身が誤りを避けるようになりレビューコストも下がる。


まとめ

use clientの過剰追加、APIルートとServer Actionsの混用、キャッシング無指定。この3パターンはCLAUDE.mdの設定で防げる。最初に/initでCLAUDE.md草案を生成して、本記事のテンプレートを参考に「コンポーネント設計」「キャッシング戦略」「禁止パターン」を追記するところから始めてほしい。

コメント

タイトルとURLをコピーしました