Receber por email
← Voltar para o catálogo

nextjs-architect

Next.js 16 standards — App Router only, server components by default with explicit `"use client"` boundaries, server actions for mutations, streaming Suspense, edge vs node runtime, Image/Font/Metadata APIs. Pairs with react-architect. Use when scaffolding or reviewing a Next.js app or auditing server/client boundaries.

2estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: GPL-3.0

Como adicionar

/plugin marketplace add ralvarezdev/ralvaskills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/nextjs-architect/svg)](https://www.skillteca.com.br/skills/nextjs-architect)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Next.js Architecture

Targets Next.js 16 with React 19, TypeScript strict, App Router only. Builds on [react-architect](../react-architect/SKILL.md) for client-side patterns; this skill covers the Next-specific layers — server components, server actions, routing, data fetching, edge vs node, deployment. Concrete skeletons in [RECIPES.md](RECIPES.md); pinned dependencies in [STACK.md](STACK.md).

1. App Router only

The Pages Router is legacy. New code lives in app/; if you inherit a Pages Router app, don't mix unless mid-migration. Folder layout reference in [RECIPES § App Router folder layout](RECIPES.md#app-router-folder-layout).

Key conventions:

  • page.tsx = the route's UI. layout.tsx wraps it. Both default to server components.
  • loading.tsx wraps the route in Suspense automatically.
  • error.tsx is a client component that wraps the route in an ErrorBoundary.
  • Route groups ((name)) organize without adding URL segments.
  • @slot is a parallel route — independent loading/error states, rendered into named slots in the parent layout.

2. Server components by default, client when needed

Every component is a server component unless you opt out with "use client". The choice belongs to the leaf component that needs the client behavior — not the root.

When to stay server

  • Pure rendering — no state, no effects, no event handlers.
  • Data fetching — await db.query(...), await fetch(...).
  • Secrets / server-only logic — process.env.STRIPE_SECRET_KEY only loaded in server components.
  • Markdown rendering, syntax highlighting, large dependencies you don't want shipped to the browser.

When to flip to "use client"

  • useState, useEffect, useReducer, any other hook.
  • Browser-only APIs (window, localStorage, IntersectionObserver).
  • Event handlers (onClick, onChange, etc.) — must be in a client boundary.
  • Third-party libraries that use any of the above (most chart libraries, animation libraries).

The boundary rule

  • Server passes data to client as props — props must be JSON-serializable. Pass IDs, not class instances; pass plain objects, not Date (use ISO strings).
  • One "use client" directive at the top of a file makes that file and everything imported into it run client-side. Hoist the directive to the smallest leaf.
  • Don't nest client → server. Server components can be rendered inside client trees only as children props (slot pattern).

Skeleton: [RECIPES § Server / client boundary](RECIPES.md#server--client-boundary).

3. Data fetching

Reads — direct from server components (hybrid default)

Per the project choice: direct DB access from RSC for reads, API routes for writes. Cleaner UX (single round-trip), type-safe end-to-end.

  • getUser lives in a server-only module (@/lib/users.server.ts or marked with the "server-only" import). Prevents accidental bundling of DB code into the client.
  • Use [sql-architect](../../databases/sql-architect/SKILL.md)'s psycopg + .sql pattern when the project's backend convention matches; otherwise use the project's existing data layer.
  • notFound() triggers the closest not-found.tsx — proper 404 with the right HTTP status.

When to flip to API routes for reads: any of the following — and document the choice per project:

  • You want a separate microservice topology (Next is the frontend BFF, backend is its own service).
  • The same data is consumed by mobile clients or other web frontends; one HTTP API beats two implementations.
  • Auth requirements force the boundary (e.g. backend has access controls direct DB calls can't replicate).

Skeleton: [RECIPES § Read directly from a server component](RECIPES.md#read-directly-from-a-server-component).

Writes — server actions

Server actions are the canonical mutation pattern. No client-side fetch, no manual JSON handling.

  • "use server" at the top of a file marks every export as a server action — accessible from client components via import.
  • Always re-authenticate inside the action. Don't trust the calling context; verify the session.
  • Validate with Zod at the boundary — same discipline as REST handlers per [rest-api-architect §7](../../protocols/rest-api-architect/SKILL.md#7-error-contracts--rfc-7807-problem-details).
  • revalidatePath / revalidateTag to refresh server-rendered data after a mutation. Without this, the user sees stale state.
  • Return discriminated unions ({ok: true, ...} | {ok: false, ...}) so the client renders success vs. errors based on the field.

Skeleton: [RECIPES § Server action with Zod validation + form binding](RECIPES.md#server-action-with-zod-validation--form-binding).

TanStack Query — when?

The [react-architect §5](../react-architect/SKILL.md#5-state-management--three-layers) recommendation stands inside client components — but in Next.js the trade-off shifts:

  • Server components fetch on the server. TanStack Query's "server state cache" benefits don't apply when the page is server-rendered fresh.
  • TanStack Query earns its place in Next when: there's substantial client-side data fetching (autocomplete, real-time updates, infinite scroll, polling), or you want optimistic UI for mutations beyond what server actions give.

4. Streaming with Suspense

Next App Router streams the HTML as RSC chunks resolve. Pair with <Suspense> for granular per-region loading.

  • loading.tsx is a route-level Suspense. Per-region Suspense gives finer-grained streaming.
  • error.tsx is a route-level ErrorBoundary. Inline <ErrorBoundary> (from next/error-boundary or a custom one) for finer scoping.
  • Don't over-stream. A page with 12 Suspense boundaries appears janky as chunks fill in. Target the genuinely slow regions.

Skeleton: [RECIPES § Per-region streaming with Suspense](RECIPES.md#per-region-streaming-with-suspense).

5. Edge vs Node runtime

Each route can declare its runtime via export const runtime = "edge" | "node". Defaults to node.

  • Default node — full Node API, npm packages with native modules, deepest compatibility.
  • runtime = "edge" for low-latency, geographic-edge routes — auth verification, redirects, feature flags, A/B routing.
  • Edge restrictions: no Node-only modules, no native bindings, smaller bundle limit. DB drivers vary — standard Postgres drivers don't work on edge.

Declaration + edge-compatible driver notes in [RECIPES § Edge runtime declaration](RECIPES.md#edge-runtime-declaration).

6. Metadata, Images, Fonts

Metadata

  • Per-route generateMetadata — async, runs on the server, has access to params.
  • Root metadata export in app/layout.tsx for defaults (title template, OG defaults).
  • Don't hand-write <head> — Next manages it for SEO + social embed correctness.

Example in [RECIPES § Metadata via generateMetadata](RECIPES.md#metadata-via-generatemetadata).

next/image

  • Always next/image, never <img> in App Router code. Handles responsive sizes, modern formats (AVIF/WebP), lazy loading, no layout shift.
  • Set width and height (or fill with a sized parent). Prevents CLS.
  • priority only on above-the-fold images. Every image marked priority defeats the optimization.
  • Remote images need remotePatterns in next.config.ts — strict allow-list for security.

next/font

  • next/font/google for Google Fonts; subsets + variable axes pinned at build time, no external request.
  • next/font/local for self-hosted fonts.
  • Both eliminate FOIT/FOUT. Don't use @import or <link rel="stylesheet"> for fonts.

7. API routes — when

Server actions cover most mutations. API routes (app/api/.../route.ts) earn their place for:

  • Webhooks — external services (Stripe, GitHub, etc.) POST to your API.
  • External clients — mobile, public API, partner integrations.
  • Streaming responses — server-sent
Compartilhar X LinkedIn