Data & analysis

NextJS

Try it

Build and debug Next.js App Router apps — server/client boundaries, caching, Server Actions, auth, and deployment.

What it does

Guides App Router development: server-by-default component boundaries, parallel data fetching, Suspense streaming, Server Actions with revalidation, and version-specific behavior across Next 14–16. Handles real bug patterns — hydration mismatches, poisoned dynamic reads, stale cache, auth hardening around CVE-2025-29927 — and routes you to Vercel, Docker, standalone, or static export based on your target. Adapts to your stack via recorded preferences for package manager, styling, ORM, naming, and folder conventions.

When to use it

  • Diagnosing "useState only works in Client Components" or hydration mismatch errors
  • Tracking down stale pages, broken ISR, or missing revalidation after a write
  • Wiring login sessions, protected routes, and Server Action auth checks
  • Picking Vercel, Docker, standalone, or static export and configuring the build

The skill document

Setup

All persistent data for this skill lives in ~/Clawic/data/nextjs/. On first use, read setup.md for project integration.

Configuration

User-dependent variables. Defaults apply until the user states a preference; store them in ~/Clawic/data/nextjs/config.yaml.

VariableTypeDefaultEffect
package_managernpm | pnpm | yarn | bunnpmSelects install/run command syntax, lockfile references, and Docker corepack/cache-mount advice
deployment_targetvercel | docker | standalone | static-exportvercelDrives build config (output mode), env-var handling, and which parts of deployment.md apply; static-export disables SSR/ISR/Server Actions guidance
stylingtailwind | css-modules | styled-components | vanilla-extracttailwindShapes styling examples and the RSC-compatibility caveats (styled-components needs a client boundary/registry)
component_namingPascalCase | kebab-casePascalCaseSets filenames used in generated components and import examples
folder_conventionfeature-folders | type-foldersfeature-foldersGoverns where new routes, components, and colocated files are placed

Preference areas to record as the user reveals them:

  • conventions — component/file naming, folder organization, barrel-file usage
  • stack — TypeScript, ORM (Prisma/Drizzle), auth library, state management
  • proactivity — how eagerly to flag caching/boundary/performance issues vs only on request
  • safety posture — how proactively to surface auth hardening (data-access layer, CVE-2025-29927) vs only when asked

When To Use

  • Building or debugging a Next.js App Router application — routing, rendering, data, deploy
  • Boundary errors: "useState only works in Client Components", hydration mismatch, "functions cannot be passed to Client Components"
  • Cache surprises: stale pages, data not updating, ISR behaving "randomly"
  • Wiring auth: sessions, protected routes, role checks
  • Shipping: Vercel, Docker, standalone server, static export
  • Not for plain React questions (see react skill) or Pages Router deep-dives — App Router is assumed throughout

Architecture

~/Clawic/data/nextjs/
├── memory.md          # Project conventions, patterns
└── projects/          # Per-project learnings

See memory-template.md for the file formats. If you have data at an old location (~/nextjs/ or ~/clawic/nextjs/), move it to ~/Clawic/data/nextjs/.

Quick Reference

SituationGo to
First session with a user or projectsetup.md, then memory-template.md
Page slow, sequential awaits, streaming, Server Actionsdata-fetching.md
Stale or over-fresh data, revalidate, ISR, cache debuggingcaching.md
Login, sessions, protected routes, rolesauth.md
Modals over pages, parallel routes, layouts, navigationrouting.md
Docker, self-hosting, env vars, static exportdeployment.md
Anything else Next.jsApply Core Rules below; open the closest file only if they don't settle it

Core Rules

1. Server by Default, Client at the Leaves

'use client' marks a boundary, not one component: everything imported below it ships to the browser. Put interactivity in leaf components; a 'use client' layout de-RSCs its whole subtree.

2. Parallel Fetches or You Pay the Sum

Sequential awaits cost sum(t1..tn); Promise.all costs max(). Three 300ms fetches: 900ms sequential, 300ms parallel. Chain awaits only when one call genuinely needs the other's result.

3. One Dynamic Read Poisons the Whole Route

cookies(), headers(), or an uncached fetch anywhere in the tree — layouts included — forces the entire route to render per-request. Read them in the leaf that needs them, behind ``.

4. Dev Lies About Caching

next dev renders everything dynamically. Verify cache behavior only with next build && next start; debug headers and build-output symbols are in caching.md.

5. Middleware Redirects, the Data Layer Enforces

Middleware does optimistic cookie checks for UX; every Server Action, route handler, and query re-verifies the session. CVE-2025-29927 let a spoofed request header skip middleware entirely — patched versions and the data-access-layer pattern in auth.md.

6. Server Actions Are Public Endpoints

Anyone can POST to an action with its id; a hidden button protects nothing. First lines of every action: session check, then input validation.

7. Write, Revalidate, Then Redirect

Every mutating action ends with revalidatePath/revalidateTag, or the UI keeps serving stale cache. redirect() throws — call it after the try/catch, never inside one.

8. NEXT_PUBLIC_ Is Baked at Build Time

Inlined into the bundle during next build; changing it at runtime does nothing. Unprefixed vars stay server-only — and any differing public var means one Docker image per environment (deployment.md).

9. Suspense Converts Blocking Into Streaming

TTFB = the slowest await chain outside any Suspense boundary. Wrap each independent slow fetch in its own `` so the shell paints immediately.

Server vs Client

Server ComponentClient Component
Default in App RouterRequires 'use client'
Can be asyncCannot be async
Access backend, env varsAccess hooks, browser APIs
Zero JS shippedJS shipped to browser

Decision: Start Server. Add 'use client' only for: useState, useEffect, event handlers, browser APIs.

The boundary is a serialization boundary. Props crossing server→client must serialize: plain objects, arrays, Date, Map, Set — yes; functions and class instances — no (exceptions: Server Actions passed as props, and Promises, which the client unwraps with use()). A Server Component can't be imported into a Client Component — pass it as children.

Version Gates

  • next >=13.4 — App Router stable; everything here assumes it
  • next 14 — fetch cached by default (the version where the default flips)
  • next >=15 — fetch and GET route handlers uncached by default; params/searchParams are Promises, await them; React 19 (useActionState)
  • next >=16 — Turbopack is the default bundler; synchronous params access removed; middleware.ts renamed proxy.ts (old name deprecated)

Traps

TrapWhy it failsDo instead
try/catch around redirect()it throws NEXT_REDIRECT; your catch swallows itredirect after the try, or rethrow
Fetching your own API route from a Server Componentextra HTTP round-trip, lost typescall the DB/function directly
useEffect for initial datadouble round-trip (HTML, then JSON), no streamingfetch in a Server Component
cookies() in root layoutwhole app goes dynamic (Rule 3)read in the consuming leaf
new PrismaClient() at module top leveldev hot-reload piles up connections until the DB refusesglobalThis singleton
Date.now()/Math.random() in renderserver and client HTML differ → hydration errorcompute in useEffect, or pass from server as prop
Secrets imported into client codebundled into public JSimport 'server-only' in server modules — build fails on misuse
next/image with fill but no sizessrcset assumes 100vw; phones download desktop-size imagesset sizes to the actual rendered width
Heavy work or DB calls in middlewareruns on every matched request, before any cacheoptimistic checks only; real work in the route
router.push in a Server Componentno client router on the serverredirect()

Where Experts Disagree

QuestionCampsThe boundary
Server Actions vs route handlers for mutationsactions-everywhere vs RESTActions for your own app's forms (progressive enhancement, typed); handlers for webhooks, external clients, explicit status codes
Edge vs Node runtimeedge-first vs Node-defaultNode unless the route is latency-critical AND every dependency runs on edge; a single native module decides it for you
Still need SWR/React Query?server-only vs client cacheServer fetch for read-mostly pages; reach for a client library only for polling, optimistic UI, or infinite scroll
Vercel vs self-hostDX vs cost/controlVercel to validate; revisit when ISR/image bills grow or compliance demands your infra — the move is covered in deployment.md

More Clawic skills, get them at https://clawic.com/skills/nextjs (install if the user confirms):

  • react — React fundamentals and patterns
  • typescript — Type safety for better DX
  • prisma — Database ORM for Next.js apps
  • tailwindcss — Styling with utility classes
  • nodejs — Server runtime knowledge

Feedback

Part of Clawic, the verified skill library. Get this skill: https://clawic.com/skills/nextjs.

Questions people ask

Does this cover the Pages Router?
No. It assumes the App Router (Next 13.4+) throughout and points Pages Router questions elsewhere.
Will it pick up my project's conventions?
Yes. Package manager, styling, component naming, folder layout, ORM, auth library, and a configurable proactivity level are stored and reused across sessions.
Are Next 15 and 16 changes covered?
Yes — async params, default-uncached fetch and GET route handlers in 15, plus Turbopack default and the `middleware.ts` → `proxy.ts` rename in 16 are noted.

Related skills

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai21 installs8 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván556 installs18 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Run Git operations — commits, branches, merges, rebases, conflict resolution, and recovery — with safety rules enforced.

by Iván533 installs31 stars

More from ivangdavila

Browse all skills

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Run Git operations — commits, branches, merges, rebases, conflict resolution, and recovery — with safety rules enforced.

by Iván533 installs31 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván556 installs18 stars

Diagnoses Java and JVM issues from exception messages to container OOM-kills, and writes Java code matching the configured JDK.

by Iván131 installs9 stars