Fixing Claude Code's "use client" mistakes in the Next.js App Router

The most common App Router build and runtime errors come from the server/client split, and AI assistants hit them often. The good news is that they are mechanical enough to detect by reading the file after each edit.

The mistakes

These are the patterns that account for most of the breakage:

Why catching it at edit time helps

If you only find these at next build, you pay a round trip: build, read the error, ask Claude to fix it. A PostToolUse hook that runs right after an edit lets Claude see the problem in the same turn.

The mechanism is simple. Claude Code runs your script after a file edit and passes the tool call as JSON. If the script exits with code 2, its message goes back to Claude as feedback. The message should be specific: say what is wrong, in which file, and the fix ("add "use client" as the first line" or "move metadata to a Server Component layout").

What the check looks at

Keep it text-based and scoped:

// sketch of one rule
const usesClientFeatures = /\buse(State|Effect|Reducer)\(|\bon[A-Z]\w+=\{/.test(src);
const hasDirective = /^\s*["']use client["']/.test(src);
if (usesClientFeatures && !hasDirective) {
  console.error(`${file}: uses client-only features but has no "use client" at the top.`);
  process.exit(2);
}

Expect some false positives

Because the check is text-based, it can complain about a file that is fine, for example a Server Component that contains useState( inside a code sample string. Move the sample to a separate file or add that path to a skip list at the top of the loop. Files outside app/ are not checked at all, which is deliberate.

Prevent it at the source too

Hooks catch mistakes after the fact. Rules in CLAUDE.md reduce how often they happen. Short, checkable rules work better than general advice: when to add "use client", where metadata lives, how NEXT_PUBLIC_ variables are handled, and a requirement to state the caching choice, since caching defaults differ between Next.js major versions.

For larger work, a planning step helps. Deciding server versus client, data, caching, auth and error states before any code is written avoids the "write first, restructure later" cycle.

Going further

The Next.js Claude Code workflow pack includes this client-boundary hook, a route-planning subagent and a CLAUDE.md template written as short checkable rules.

This article was written with AI assistance.