Skip to content

@tank/nextjs

2.1.0

Next.js 14/15 App Router patterns. Covers Server vs Client Components, data fetching (server actions, route handlers), caching hierarchy, streaming SSR, parallel/intercepting routes, middleware, and deployment. Triggers: nextjs, next.js, app router, server component, client component, server action, route handler, middleware, SSR, SSG, ISR, caching, revalidation, streaming, suspense, parallel routes, intercepting routes, next/image, metadata, layout.


name: "@tank/nextjs" description: "Expert Next.js App Router execution guide for server-first rendering, caching, routing, and deployment. Triggers: nextjs, next.js, app router, server component, client component, server action, route handler, middleware, SSR, SSG, ISR, caching, revalidation, streaming, suspense, parallel routes, intercepting routes, next/image, metadata, layout." triggers:

  • nextjs
  • next.js
  • app router
  • server component
  • client component
  • server action
  • route handler
  • middleware
  • ssr
  • ssg
  • isr
  • caching
  • revalidation
  • streaming
  • suspense
  • parallel routes
  • intercepting routes
  • route groups
  • next/image
  • metadata
  • layout
  • route segment config
  • use client
  • rsc
  • loading.tsx
  • error.tsx
  • not-found.tsx

Core Philosophy

  • Server-first rendering: prefer Server Components and server actions, push interactivity to leaves.
  • Cache everything by default: assume cached, then opt out with intent and explicit scope.
  • Colocation over convention: keep data, UI, and constraints next to the segment that owns them.

Operating Model

  • Start with the route segment: choose static or dynamic behavior before writing code.
  • Draw the data flow: read in Server Components, mutate in Server Actions or Route Handlers.
  • Place streaming boundaries where partial UI is acceptable.
  • Treat middleware as routing, not business logic.

Server vs Client Component Decision Tree

NeedUseWhy
Access to browser APIs, stateful UI, event handlersClient ComponentRuns in browser, can use hooks and effects
Fetch data, read cookies/headers, call server actionsServer ComponentRuns on server, no bundle cost
Render large content tree with minimal JSServer ComponentStreams HTML with zero client JS
Interactive widget inside mostly static pageServer Component wrapping Client ComponentKeep JS at the leaf
Use third-party client-only libraryClient ComponentRequires window/document
Share data across multiple client widgetsServer Component + context boundaryFetch once on server
Need to keep secrets or tokens off the clientServer ComponentNever serialize secrets

Data Fetching Decision Tree

GoalUsePlacement
Read data for UI, can be cachedRSC async fetchServer Component
Mutate data from a form or buttonServer ActionServer Component or Client Component form
Expose API for external clients or webhooksRoute Handlerapp/api/.../route.ts
Client needs incremental updates or pollingClient fetchClient Component
Reuse data across pagesShared RSC fetch + cache tagsServer Component
Need edge runtimeRoute Handler or Middlewareapp/api or middleware.ts

Caching Quick Reference

LayerCached By DefaultRevalidateOpt Out
Request memoizationYes (per request)N/Acache: "no-store"
Data CacheYesnext.revalidate, revalidateTagcache: "no-store"
Full Route CacheYes (static)revalidatePath, segment revalidateexport const dynamic = "force-dynamic"
Router CacheYes (client)router.refresh()router.refresh() after mutations

Route Conventions

FilePurposeNotes
page.tsxRoute entryRenders UI for a segment
layout.tsxShared UIPersists across segments
template.tsxPer-navigation layoutRemounts on navigation
loading.tsxSuspense fallbackShows while streaming
error.tsxSegment error boundaryClient Component with use client
not-found.tsx404 UICalled via notFound()
route.tsRoute HandlerHTTP methods for APIs
middleware.tsEdge routingRuns before route

Segment Configuration Defaults

OptionDefaultUse Case
dynamic"auto"Let Next decide static vs dynamic
revalidatefalseOpt into ISR per segment
fetchCache"auto"Control caching for fetch in segment
runtime"nodejs"Use edge only when needed

Server Action Rules

  • Declare "use server" at the function or file scope.
  • Return serializable values only.
  • Validate input on the server, never trust client state.
  • Use revalidatePath or revalidateTag after mutations.
  • Prefer form actions for simple submits, startTransition for client triggers.

Middleware Rules

  • Keep middleware fast and deterministic.
  • Avoid data fetching; redirect or rewrite instead.
  • Use matcher config to limit execution scope.
  • Put auth gating in middleware, not data enrichment.

Rendering Defaults

  • RSC fetch is cached by default; opt out with cache: "no-store".
  • Static rendering is default when no dynamic APIs are used.
  • Dynamic rendering triggers on cookies, headers, or no-store fetch.
  • Streaming is automatic with Suspense boundaries.

Anti-Patterns

Anti-PatternReplace With
Marking everything use clientServer Components + leaf clients
Fetching in Client Components without needRSC async fetch
Mutations via client fetch to app APIsServer Actions for same-origin UI
Using middleware for data fetchingRoute Handlers or Server Actions
Forcing dynamic on static pagesrevalidate or tag-based ISR
Coupling layouts to data fetchingMove reads to page or nested components
Serializing secrets to propsRead secrets in Server Components
One global loading stateSegment loading.tsx + nested Suspense
Overusing route handlers for UIPrefer RSC for UI data

Workflow

  1. Pick static or dynamic per segment using dynamic and revalidate.
  2. Fetch in Server Components; memoize with tags and revalidate on writes.
  3. Add Server Actions for mutations; invalidate with revalidatePath or revalidateTag.
  4. Insert loading.tsx and inline Suspense for gradual streaming.
  5. Add error.tsx and not-found.tsx for resilience.
  6. Validate middleware for routing-only responsibilities.
  7. Optimize bundles: keep Client Components small and isolated.

Quality Checklist

  • Every client component has a server parent.
  • Every mutation has a cache invalidation step.
  • Every slow segment has a loading boundary.
  • Every external API has a route handler.
  • Every metadata dependency is explicit.

Output Expectations

  • Provide concrete code with file paths.
  • Explain cache effects explicitly.
  • Show where each component runs.
  • Keep client JS minimal.

Reference Files

  • references/server-components.md
  • references/caching-and-data.md
  • references/routing-patterns.md

Command Palette

Search skills, docs, and navigate Tank