# Nextjs Expert

> Next.js 14+ gotchas and decision criteria. Covers server/client boundary, caching strategy, and data fetching patterns Claude commonly gets wrong. Use when this capability is needed.

- Skill: `tomevault-io/nextjs-expert-4` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/nextjs-expert-4`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/nextjs-expert-4/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/nextjs-expert-4

---


> **AI-consumed reference.** Optimized for Claude to read during execution.
> Human-readable explanation: see [docs/architecture/HIERARCHICAL_PLANNING.md](../../../docs/architecture/HIERARCHICAL_PLANNING.md)
> or [docs/getting-started/](../../../docs/getting-started/) depending on topic.


# Next.js Expert — Gotchas & Decisions

Use Context7 for full Next.js docs.

## Key Decisions

```toon
decisions[4]{choice,use_when}:
  Server vs Client,"Server by default. 'use client' ONLY for interactivity (useState/onClick). Push boundary as low as possible"
  Cache strategy,"force-cache (static) | revalidate:N (time) | revalidateTag (on-demand) | no-store (always fresh)"
  Server Actions vs API routes,"Actions for form mutations. API routes for external consumers/webhooks"
  Streaming vs blocking,"Suspense wrap for slow data. Always Promise.all for parallel fetches"
```

## Gotchas

- Server Components can't use useState/useEffect — move interactive parts to a child Client Component
- `'use client'` makes ALL imports in that file client-side — keep it at leaf components
- `fetch()` in Server Components is auto-deduped but only within same render pass
- Server Actions: always validate with Zod — formData comes from untrusted client
- `error.tsx` MUST be a Client Component (`'use client'`). `global-error.tsx` must render `<html>` and `<body>`
- `loading.tsx` wraps page in Suspense — don't double-wrap with manual Suspense
- Dynamic routes `[slug]`: params are now a Promise in Next.js 15 — `await params`
- `revalidatePath('/')` revalidates ALL pages, not just home — use `revalidateTag` for precision
- Image: always provide `sizes` prop with `fill` — without it, Next.js sends full-size image
- Middleware runs on Edge: no Node.js APIs (fs, Buffer, etc.)

---
> Source: [nguyenthienthanh/aura-frog](https://github.com/nguyenthienthanh/aura-frog) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-05-28 -->

