Nextjs
Measured, opinionated Claude Code rules for frontend work (React / Next.js / Vite / Astro) — skills, path rules, review agents, sign-off hooks, installer & plugin. Every claim backed by committed eval reports.
npx -y skills add Syo-M/fable-frontend-skills --skill nextjsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Next.js App Router conventions — routing and adding pages, Server/Client Components, data fetching, caching, Server Actions, route handlers, metadata, env vars. Use for any work inside a Next.js app. 日本語の依頼例:「Next.jsで〜」「ページを追加/新規作成して」「ルーティング」「Server Action」「ルートハンドラ」「RSC/サーバーコンポーネント」「キャッシュ」。
SKILL.md
4.1 KB, as published. Nobody here has run it
Next.js (App Router)
Check the installed Next.js major version (package.json) before using version-specific APIs — caching semantics changed significantly across 14 → 15 → 16.
Server vs Client Components
- Server Components are the default. Add
'use client'only at interaction leaves (event handlers, state, browser APIs) — never on layouts/pages wholesale. - Push client boundaries down: pass Server Component output as
childreninto client wrappers instead of converting whole trees. - Never import server-only modules (DB clients, secrets) into client files. Add
import 'server-only'to modules that must never reach the client.
Data fetching
- Fetch in Server Components, close to where data is used. React deduplicates identical
fetchcalls per request; wrap non-fetch data access incache()if called from multiple components. - Parallelize independent fetches (
Promise.allor separate components + Suspense). Sequential awaits are the #1 RSC perf bug. - Use
loading.tsx/<Suspense>for streaming;error.tsxper route segment;notFound()for missing resources.
Caching
- Be explicit, never rely on remembered defaults (they changed between versions). Always state the intended behavior: static, revalidated (
revalidate/cacheLife), or dynamic. - Never cache per-user or personalized responses (
Cache-Control: no-store/ dynamic rendering) — a cached per-user response is a data leak, not a perf win. - Tag cached data (
cacheTag/ fetch tags) and invalidate after mutations — do not sprinklerouter.refresh()as a fix. Pick deliberately:updateTag(Server Actions only, read-your-writes for the acting user) vsrevalidateTag(SWR-style; accepts a cacheLife profile in Next 16).
Server Actions — treat as public HTTP endpoints
Every action, no exceptions:
- Authenticate: verify the session inside the action (middleware is not sufficient — actions are directly invokable).
- Authorize: check the user may act on this resource (IDOR check on every ID argument).
- Validate: parse all arguments with zod before use.
FormDatafields areunknown, notstring. - Return typed results (
{ ok: true, data } | { ok: false, error }); never throw raw DB/internal errors to the client. - After mutation:
revalidateTag/revalidatePath, thenredirect()if needed (note:redirectthrows — call it outside try/catch).
Route Handlers
Same auth/validation rules as Server Actions, plus: route handlers get NO built-in CSRF protection (the Origin check covers Server Actions only) — cookie-authenticated mutations need explicit Origin validation or a CSRF token, and webhook endpoints need signature verification (see frontend-security). Use route handlers only for genuine API needs (webhooks, third-party callbacks, non-React clients) — prefer Server Components for reads and Actions for mutations.
Env vars
NEXT_PUBLIC_*is compiled into the client bundle — public by definition. Everything secret: no prefix, read only in server code.- Never pass secret-bearing objects as props to client components. Consider
experimental_taintObjectReferencefor sensitive models.
Routing & misc
- Use
<Link>for internal route navigation,next/imagefor images,next/fontfor fonts. Plain<a>is CORRECT for external links, downloads, and same-page hash anchors — never wrap those in<Link>. No<img>, no CSS@importof font CDNs. - Metadata via the
metadataexport /generateMetadata— not manual<head>tags. useSearchParamsrequires a Suspense boundary; forgetting it de-optimizes the whole page.- Dynamic route params: validate (zod) before use — they are user input.