agentleFS
motola10motola10/claude-code-base/.claude/skills/nextjs-standards/SKILL.md

nextjs-standards

Skill1 starsChanged 5 months agoMITView on GitHub

Best-practice coding standards for Next.js (App Router) apps (next.config, app/ dir). OVERLAY — load react-standards + typescript-standards FIRST. Covers Server/Client Components, data fetching & caching, Server Actions, security, server logging, metadata, testing. Used by the review agents on Next.js code. Do NOT use for non-Next React or backend code.

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. About 0 are common, 2 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    NEXT-ROUTE-5 (SHOULD): Use the typed navigation primitives — <Link> and the next/navigation hooks (useRouter, usePathname, useSearchParams) …

    line 79
  2. Very specific:

    NEXT-RSC-1 (MUST): Keep components as Server Components by default.

    line 87
  3. Distinctive:

    Don't mark a whole page/layout as client to make one button interactive — keep data-heavy parents on the server.

    line 91
  4. Very specific:

    NEXT-RSC-3 (MUST NOT): Import server-only modules (DB clients, secrets, server SDKs) into a Client Component.

    line 93
  5. Very specific:

    NEXT-RSC-5 (SHOULD): Keep async/await data fetching in Server Components.

    line 99
  6. Very specific:

    NEXT-ACT-1 (SHOULD): Use Server Actions ('use server') for internal form submissions and mutations triggered from your own UI, instead of …

    line 128
  7. Distinctive:

    NEXT-ACT-2 (MUST): Every Server Action is a public POST endpoint — it MUST perform its own

    line 133
  8. Very specific:

    NEXT-ACT-4 (SHOULD): After a successful mutation, call revalidatePath/revalidateTag and then redirect (from next/navigation) as needed.

    line 139
  9. Very specific:

    NEXT-SEC-4 (SHOULD): Use a vetted auth library — Auth.js (NextAuth) is the community default for the App Router (v5 integrates via the …

    line 179
  10. Very specific:

    NEXT-LOG-1 (MUST NOT): Use console.log for application logging in server code paths.

    line 197
  11. Very specific:

    NEXT-IMG-1 (SHOULD): Use next/image (<Image>) for images to get automatic optimization, lazy loading, and correct sizing.

    line 211
  12. Very specific:

    NEXT-CONF-1 (SHOULD): Keep next.config.ts minimal and typed.

    line 220
  13. Very specific:

    NEXT-TEST-2 (SHOULD): Follow the test pyramid (NODE-TEST-3 / PY-TEST-3): many fast unit tests for pure logic and the data layer, fewer …

    line 240
  14. Very specific:

    NEXT-TEST-4 (SHOULD): Test Route Handlers (route.ts) as integration tests — invoke the handler with a Request and assert on the Response …

    line 247

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Next.js Coding Standard (v1.0)

Status: Locked v1.0. Next.js is a full-stack React framework, so this is an overlay that sits on top of two standards and inherits all of their rules:

  • reactjs.md — component design, hooks, state, rendering, forms, client logging (REACT-*)
  • typescript.md — language/type rules (TS-*)

This document owns only what is Next.js-specific: the App Router, the Server/Client Component boundary, server-side data fetching & caching, Server Actions, routing/metadata, and the server-tier concerns (auth, server logging) that reactjs.md deliberately deferred to the host framework. On overlap, the stricter rule wins; where this document sets a server-tier rule that reactjs.md deferred (e.g. server logging, server data fetching), this document is authoritative.

On adoption this becomes .claude/skills/nextjs-standards/SKILL.md + references/*.md.

Toolchain verified current as of 2026-06-13 (via Context7 + npm): Next.js 16.2.x (App Router), React 19.2.x, Auth.js / NextAuth (v5 beta 5.0.0-beta.x; v4 4.24.x stable). Rules are written version-agnostically; these are reference points, not pins.


How to read this document

Constraint language (RFC 2119)

  • MUST / MUST NOT — hard requirement; a violation is a blocking issue.
  • SHOULD / SHOULD NOT — strong recommendation; deviate only with a written // Justification:.
  • MAY — optional.

Rule IDs

Stable NEXT-AREA-NUMBER (e.g. NEXT-RSC-2). The reviewer MUST cite the rule ID. Never renumber.

Severity mapping

This document says…Reviewer severityGate
MUST/MUST NOT affecting security / data exposureCriticalBlocks merge
MUST/MUST NOT elsewhereCritical / Warning (by impact)Blocks if it risks correctness
SHOULD without justificationWarningShould fix
MAY / stylisticSuggestionNice to have

Scope & Assumptions

  1. Target: Next.js applications on the App Router (app/ directory). The legacy Pages Router (pages/) is out of scope for new code — new routes MUST be built in the App Router. Existing pages/ code is governed by reactjs.md + typescript.md (and any custom-standards overlay); this document does not add Pages-Router rules.
  2. Inherits reactjs.md + typescript.md in full. This overlay adds and, on the server tier, overrides.
  3. Server Components are the default. A component is a Server Component unless it (or an ancestor in the module graph) carries 'use client'.
  4. Custom overrides: the project's custom-standards skill overrides this document on conflict.

1. App Router & Routing

  • NEXT-ROUTE-1 (MUST): New routing MUST use the App Router (app/), using the framework file conventions — page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx, route.ts.
  • NEXT-ROUTE-2 (MUST): Each route segment's error.tsx is a Client Component error boundary (it needs 'use client'). Provide one at meaningful boundaries — this is how REACT-ERR-1 is satisfied in the App Router.
  • NEXT-ROUTE-3 (SHOULD): Provide loading.tsx (or explicit <Suspense>) for segments that fetch data, so navigation streams a fallback instead of blocking.
  • NEXT-ROUTE-4 (MUST): Build public/external API surface — REST endpoints consumed by mobile/third-party clients, webhooks, and anything needing custom HTTP semantics — as Route Handlers (route.ts exporting GET, POST, …). Do not reach for a second HTTP server inside a Next.js app. (Internal form mutations go through Server Actions instead — see NEXT-ACT-1.)
  • NEXT-ROUTE-5 (SHOULD): Use the typed navigation primitives — <Link> and the next/navigation hooks (useRouter, usePathname, useSearchParams) — not raw <a>/window.location for internal navigation.

2. Server & Client Components

  • NEXT-RSC-1 (MUST): Keep components as Server Components by default. Add 'use client' only when the component needs browser-only APIs, state/effects, or event handlers. Treat 'use client' as a boundary, not a default.
  • NEXT-RSC-2 (SHOULD): Push 'use client' down the tree to the smallest interactive leaf. Don't mark a whole page/layout as client to make one button interactive — keep data-heavy parents on the server.
  • NEXT-RSC-3 (MUST NOT): Import server-only modules (DB clients, secrets, server SDKs) into a Client Component. Mark such modules with import 'server-only' so a stray client import becomes a build error.
  • NEXT-RSC-4 (MUST NOT): Pass non-serializable values (functions other than Server Actions, class instances) from a Server Component to a Client Component via props — only serializable props and Server Actions cross the boundary.
  • NEXT-RSC-5 (SHOULD): Keep async/await data fetching in Server Components; do not convert a component to a Client Component merely to fetch data.

3. Data Fetching & Caching

  • NEXT-DATA-1 (SHOULD): Fetch data in async Server Components with fetch/your data layer at the point of use — this is the App Router replacement for getServerSideProps/getStaticProps, which MUST NOT be used in app/.
  • NEXT-DATA-2 (MUST): Make the caching intent explicit on each server fetch. Choose deliberately:
    • cache: 'force-cache' — static, cached until invalidated (the default; state it when it matters)
    • cache: 'no-store' — always fresh, per-request
    • next: { revalidate: N } — time-based revalidation (ISR) A reviewer flags any data fetch where freshness vs. caching was clearly not considered.
  • NEXT-DATA-3 (SHOULD): Revalidate cached data after mutations with revalidatePath / revalidateTag (from next/cache) rather than disabling caching everywhere.
  • NEXT-DATA-4 (SHOULD): This overrides REACT-STATE-6 for server-rendered data: prefer Server-Component fetch over TanStack Query for data that can be fetched on the server. Reserve TanStack Query (or SWR) for client-fetched data — polling, infinite scroll, optimistic client caches.
  • NEXT-DATA-5 (SHOULD NOT): Fetch from your own Route Handler inside a Server Component just to get data — call the data layer directly. An internal HTTP round-trip adds latency for no benefit.

4. Server Actions & Mutations

  • NEXT-ACT-1 (SHOULD): Use Server Actions ('use server') for internal form submissions and mutations triggered from your own UI, instead of hand-wiring client fetch to a Route Handler. The division is deliberate: Server Actions own internal mutations; Route Handlers own the public/external API surface (NEXT-ROUTE-4). Use a Route Handler when the endpoint must be callable by clients you don't control.
  • NEXT-ACT-2 (MUST): Every Server Action is a public POST endpoint — it MUST perform its own authentication and authorization checks (e.g. verify the session) before mutating. Never assume the caller is trusted because the UI is gated.
  • NEXT-ACT-3 (MUST): Validate and treat all Server Action / Route Handler input as untrusted — parse it with a schema (Zod, per typescript.md TS-TYPE-2) before use. FormData values are strings/Files and MUST be coerced/validated.
  • NEXT-ACT-4 (SHOULD): After a successful mutation, call revalidatePath/revalidateTag and then redirect (from next/navigation) as needed. redirect() throws a control-flow signal — call it outside try/catch.
  • NEXT-ACT-5 (MUST NOT): Return secrets, internal errors, or full DB rows from a Server Action to the client. Return only what the client needs; map errors to safe messages.
// ✅ NEXT-ACT-2/3/4: authz + schema validation + revalidate + redirect
'use server';
import { auth } from '@/lib/auth';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { z } from 'zod';

const CreatePost = z.object({ title: z.string().min(1) });

export async function createPost(formData: FormData) {
  const session = await auth();
  if (!session?.user) throw new Error('Unauthorized'); // NEXT-ACT-2

  const { title } = CreatePost.parse({ title: formData.get('title') }); // NEXT-ACT-3
  // ...persist via data layer...

  revalidatePath('/posts'); // NEXT-ACT-4
  redirect('/posts');        // outside try/catch
}

5. Security & Secrets

  • NEXT-SEC-1 (MUST NOT): Expose server secrets to the client. Only NEXT_PUBLIC_-prefixed environment variables are sent to the browser bundle; everything else stays server-side. MUST NOT prefix a secret (API keys, DB URLs, tokens) with NEXT_PUBLIC_.
  • NEXT-SEC-2 (MUST): Guard server-only modules with import 'server-only' so private logic and credentials cannot be pulled into a client bundle (build-time enforcement of NEXT-RSC-3).
  • NEXT-SEC-3 (MUST): Enforce authentication/authorization at the data boundary — in Server Components, Server Actions, and Route Handlers — not only in middleware or the UI. Middleware is a coarse first gate, not the authorization mechanism.
  • NEXT-SEC-4 (SHOULD): Use a vetted auth library — Auth.js (NextAuth) is the community default for the App Router (v5 integrates via the auth() helper; v4 is the stable line). For a browser-first Next.js app, Auth.js's default httpOnly cookie session (JWT-encoded) is the right primitive — this is the browser-first cookie alternative explicitly sanctioned by NODE-NEST-14 / FASTAPI-SEC-1, not the raw bearer-token default. If the same app also exposes a public/external API via Route Handlers (NEXT-ROUTE-4) for mobile/third-party clients, protect those with the cross-platform stateless JWT bearer default instead. Either way, MUST check authorization (roles/scopes), not just authentication.
  • NEXT-SEC-5 (SHOULD): Set security headers (CSP, Strict-Transport-Security, X-Content-Type-Options) via next.config headers or middleware. Avoid dangerouslySetInnerHTML (see REACT-SEC-1).

6. Server Logging & Observability

This fulfills the server-tier handoff from reactjs.md §9: client logging stays under REACT-LOG-*, while server logging (Route Handlers, Server Actions, Server Components) is owned here.

  • NEXT-LOG-1 (MUST NOT): Use console.log for application logging in server code paths. Use a structured logger (pino) — mirrors NODE-LOG-1.
  • NEXT-LOG-2 (MUST): Log structured JSON with level + timestamp on the server, and MUST NOT log secrets, tokens, or PII (mirrors NODE-LOG-2 / REACT-LOG-3).
  • NEXT-LOG-3 (SHOULD): Send client and server errors to an observability/error-tracking service (e.g. Sentry's Next.js SDK, which instruments both tiers), satisfying REACT-LOG-2 on the client and capturing server exceptions.

7. Rendering Assets & Metadata

  • NEXT-META-1 (SHOULD): Define SEO metadata with the Metadata API — export metadata or generateMetadata from layout.tsx/page.tsx rather than hand-writing <head> tags.
  • NEXT-IMG-1 (SHOULD): Use next/image (<Image>) for images to get automatic optimization, lazy loading, and correct sizing; provide alt (ties to REACT-A11Y-3).
  • NEXT-FONT-1 (SHOULD): Load fonts via next/font to self-host and avoid layout shift, rather than external <link> font requests.

8. Configuration & Project Structure

  • NEXT-CONF-1 (SHOULD): Keep next.config.ts minimal and typed; document any non-default (rewrites, redirects, images.remotePatterns, headers) with a short comment.
  • NEXT-CONF-2 (SHOULD): Co-locate route-specific components, loaders, and tests with their route segment under app/; keep shared UI and the data layer in clearly separated top-level folders (e.g. components/, lib/).
  • NEXT-CONF-3 (MUST): TypeScript and ESLint MUST pass in CI (inherits TS-CONFIG-3, TS-LINT-1); the Next.js ESLint config is layered on top of the typescript-eslint base, not instead of it.

9. Testing

Component-level testing is owned by reactjs.md (REACT-TEST-* — RTL + Vitest/Jest). This section adds only the Next.js-specific layers: App-Router flows, Server Components, and Server Actions, which resist isolated unit testing and are best covered end-to-end.

  • NEXT-TEST-1 (MUST): Maintain ≥ 80% coverage on changed code (not whole-repo) — the same policy as every standard in this suite (REACT-TEST-2, NODE-TEST/PY-TEST). Flag assertion-free or truthiness-only tests as inadequate.
  • NEXT-TEST-2 (SHOULD): Follow the test pyramid (NODE-TEST-3 / PY-TEST-3): many fast unit tests for pure logic and the data layer, fewer integration tests, few end-to-end. Unit-test framework-agnostic logic (validators, server utilities) directly with Vitest/Jest.
  • NEXT-TEST-3 (SHOULD): Cover App-Router user flows, Server Components, and Server Actions with end-to-end tests using Playwright — exercise the rendered route in a real browser rather than trying to unit-test an async Server Component or a 'use server' action in isolation. (Playwright is already the project's browser-automation tool.)
  • NEXT-TEST-4 (SHOULD): Test Route Handlers (route.ts) as integration tests — invoke the handler with a Request and assert on the Response (status, body, headers), mocking the data layer at the boundary (REACT-TEST-5).
  • NEXT-TEST-5 (MUST): For Server Actions, an E2E or integration test MUST cover the authz rejection path (NEXT-ACT-2) — that an unauthenticated/unauthorized caller is refused — not only the happy path.

Resolved Decisions (v1.0)

#QuestionDecisionRule(s)
1Pages RouterApp-Router-only for new code; legacy pages/ governed by reactjs.md + typescript.md + custom-standards. Consistent with NODE-NEST-1 (one modern stack, Express scoped out)Scope §1, NEXT-ROUTE-1
2Auth libraryAuth.js / NextAuth (SHOULD). Browser-first → default httpOnly cookie (JWT-encoded) session = the sanctioned browser-first alternative in NODE-NEST-14/FASTAPI-SEC-1; public Route-Handler APIs use the bearer-JWT default. v4 stable / v5 beta both acceptableNEXT-SEC-4
3Server Actions vs Route HandlersDivision of responsibility: Server Actions own internal form mutations; Route Handlers own the public/external/REST/webhook surfaceNEXT-ACT-1, NEXT-ROUTE-4
4Testing depthAdded §9 — Playwright E2E for RSC/Server-Action flows; component tests stay in REACT-TEST-*; ≥80%-on-changed; authz-rejection path requiredNEXT-TEST-1..5

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.