writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
nextjs-developerUse when building or reviewing a Next.js application on the App Router — routing, layouts and route groups, the rendering modes and where each is appropriate, Cache Components and the opt-in `use cache` model, data fetching and revalidation, Route Handlers and Server Actions, middleware, Turbopack, streaming and Partial Pre-Rendering, environment and secret…
Independent GitHub snapshot · Automated classification · Original documentation governs
use cache model, data fetching and revalidation, Route Handlers and Server Actions, middleware, Turbopack, streaming and Partial Pre-Rendering, environment and secret handling, and the deployment-target decision. Covers the caching inversion that makes most older Next.js advice wrong.
disambiguation: The NEXT.JS framework — routing, rendering modes, caching, server surface, build and deploy. React itself (components, hooks, the compiler, render behaviour) is react-developer; choosing between Next.js, a Vite SPA or Angular in the first place is modern-frontend; where a Next server surface should become a separate Node service is modern-frontend's boundary section.Verified 2026-07-29 against Next.js 16.2.7. This framework changes fast and has reversed a major default once already — re-check before relying on a version claim.
Next.js 16 made caching opt-in. The older App Router cached aggressively by default.
This is the single most important thing on this page, because it makes a large body of tutorials, blog posts and remembered advice wrong rather than merely dated:
| Old App Router | Next.js 16 | |
|---|---|---|
| Default | Cached aggressively | Many fetches and route handlers default to no-store |
| Opting in | Fighting the cache off | 'use cache' directive to opt IN |
| Model | Implicit and surprising | Cache Components — explicit |
The practical consequence in both directions:
When you see a caching claim about Next.js, check which major it applies to before acting on it.
| Mode | Renders | Use for |
|---|---|---|
| Static | Build time | Marketing, docs, anything not per-user |
| Dynamic (SSR) | Per request | Personalised or auth-dependent pages |
| ISR / revalidate | Build, then refreshed | Content that changes on a known cadence |
| Client | Browser | Highly interactive islands |
| PPR | Static shell + streamed dynamic holes | Mostly-static pages with a personal corner |
Partial Pre-Rendering is the one that resolves the usual dilemma — a static shell delivered instantly with dynamic parts streamed in, instead of choosing between a fast generic page and a slow personal one.
Choose per route. Making a whole app dynamic because one page needs personalisation is the commonest and most expensive Next.js mistake.
app/
layout.tsx root layout — persists across navigation, does NOT re-render
page.tsx route UI
loading.tsx Suspense fallback for this segment
error.tsx error boundary ('use client' required)
not-found.tsx
(group)/ route group — organisation without a URL segment
[id]/ dynamic segment
api/route.ts Route Handler
loading.tsx is a Suspense boundary, and it is how you stream rather than block.async components can await directly — no useEffect, no loading
state, no client bundle cost.Promise.all where
the calls are independent.'use cache' to opt in, with revalidation where the data has a known freshness.app/api/route.ts) for webhooks, third-party callbacks and non-React consumers
— not for your own components, which should reach data directly.Do not build an internal API route just for your own Server Component to call. It is a network hop to your own process.
A Server Action compiles to a callable endpoint. Whoever can reach your app can invoke it, with arguments of their choosing.
This is the most consequential security detail in the framework and the easiest to miss, because locally it looks like calling a function.
NEXT_PUBLIC_ is inlined into the client bundle. Anything with that prefix is public,
permanently, to anyone who views source. Never prefix a secret.~/.secrets/<project>.env, per
secret-scanning/references/storage-standard.md.matcher. Heavy
middleware taxes every route including static ones.next build output tells you the mode per route. Read it: a route you expected to be static
showing as dynamic is a bug you can see before deploying.Next.js runs beyond Vercel, but not every feature is equally available everywhere. Confirm that ISR,
PPR, image optimisation and middleware behave as expected on your target before committing — this
is modern-frontend's static-first default: if a project does not genuinely need a server surface,
static export removes a whole class of operational cost.
If the server surface is growing past rendering — queues, schedulers, heavy background work — that is the signal it should become a separate service rather than more Route Handlers.
NEXT_PUBLIC_ on a secret.'use client' in the root layout, forfeiting Server Components app-wide.