ScreenshotNeo

BlogEngineering

Next.js Architecture Diagram: App Router, Rendering, and Deployment

A version-aware Next.js architecture diagram covering App Router boundaries, RSC payloads, caching, navigation, and deployment decisions.

By the ScreenshotNeo team1 October 20269 min read

Direct answer: the diagram below describes a current Next.js App Router application. It shows the browser, the Server and Client Component boundary, build-time and request-time rendering, the RSC Payload and HTML response, navigation and prefetching, caching and revalidation, and the deployment runtime. Next.js also supports the older Pages Router, so label any diagram with the router, installed version, and cache configuration it represents.

Next.js is a React framework for full-stack web applications. The App Router uses newer React capabilities; the Pages Router remains supported. The architecture is not one fixed stack: a route can be statically rendered, dynamically rendered, or composed from cached and deferred parts depending on its components, APIs, configuration, and deployment topology. See the Next.js documentation for version-specific behavior.

1. The complete App Router architecture diagram

                         ┌──────────────────────────────┐
                         │          Browser               │
                         │  HTML + hydrated Client       │
                         │  Components + router cache    │
                         └──────────────┬───────────────┘
                                        │ initial request
                                        │ navigations / RSC Payload
                                        ▼
┌────────────────────────────────────────────────────────────────────┐
│                         Next.js application                         │
│                                                                    │
│  ┌──────────────────────┐       ┌───────────────────────────────┐  │
│  │ App Router route tree │       │ Rendering paths                │  │
│  │ layouts / pages       │──────▶│ • build or revalidation time   │  │
│  │ Server Components     │       │ • request-time dynamic render  │  │
│  │ Client boundaries     │       │ • streaming and transitions    │  │
│  └──────────────────────┘       └───────────────┬───────────────┘  │
│                                                │                  │
│                 ┌──────────────────────────────┴───────────────┐  │
│                 │ Server Component render                       │  │
│                 │ RSC Payload + HTML pre-render for first load  │  │
│                 └──────────────────────────────┬───────────────┘  │
│                                                │                  │
│  ┌──────────────────────┐       ┌─────────────┴───────────────┐  │
│  │ Cache / revalidation  │◀──────│ Data sources and server code │  │
│  │ static, cached,       │       │ databases, APIs, files       │  │
│  │ uncached, tagged       │       └─────────────────────────────┘  │
│  └──────────────────────┘                                          │
└────────────────────────────────────────────────────────────────────┘
                                        │
                                        ▼
                  ┌─────────────────────────────────────┐
                  │ Deployment runtime                   │
                  │ Node.js server / platform adapter   │
                  │ reverse proxy, shared cache, CDN     │
                  └─────────────────────────────────────┘

Read the two initial-load outputs separately:

Output Purpose
HTML Lets the browser display the initial page before all client JavaScript is ready.
RSC Payload Describes the rendered Server Component tree, Client Component references, and serializable props so React can reconcile the tree.

2. App Router versus Pages Router

Question App Router Pages Router
Route location app/ directory with layouts and pages pages/ directory
Default component model Layouts and pages are Server Components by default Uses the Pages Router data-fetching and rendering model
Client interactivity Add a use client boundary where state, events, lifecycle behavior, or browser APIs are needed Client-side React behavior is organized through the page model
Diagram label Show RSC Payload, Server/Client boundaries, and App Router navigation Do not imply App Router internals apply unchanged

Pages Router applications remain supported. Before documenting an existing project, inspect its directory structure and installed Next.js version instead of copying an App Router diagram onto it.

3. Server Components and Client Components

In the App Router, layouts and pages are Server Components unless a module enters a client boundary. Server Components can fetch data and produce the RSC Payload without sending their implementation to the browser. Use Client Components for state, event handlers, lifecycle behavior, and browser APIs.

// app/products/page.tsx — Server Component by default
import AddToCart from './AddToCart'

export default async function ProductsPage() {
  const products = await fetch('https://example.com/api/products').then(r => r.json())
  return (
    <main>
      {products.map((product: { id: string; name: string }) => (
        <AddToCart key={product.id} product={product} />
      ))}
    </main>
  )
}
// app/products/AddToCart.tsx — Client Component
'use client'

import { useState } from 'react'

export default function AddToCart({ product }: { product: { id: string; name: string } }) {
  const [added, setAdded] = useState(false)
  return (
    <button onClick={() => setAdded(true)}>
      {added ? 'Added' : `Add ${product.name}`}
    </button>
  )
}

The use client directive creates a client module-graph boundary. Imports and descendants below that boundary contribute to the client bundle. Keep the boundary as deep as practical so interactive code does not pull unrelated server-rendered code into the browser.

4. Initial request and hydration flow

  1. The browser requests a route.
  2. Next.js renders the Server Component tree into an RSC Payload.
  3. Next.js uses that payload and Client Component references to pre-render HTML for the initial visit.
  4. The browser displays the HTML.
  5. React reconciles the HTML with the RSC Payload and hydrates Client Components, attaching event handlers and browser behavior.

These are related but distinct stages. A diagram that labels everything as a single “page response” hides the reason Server Components can send less client JavaScript while still supporting interactive islands.

5. Navigation, prefetching, and streaming

Later navigation is different from the first visit. A client-side transition can request a prefetched or newly rendered RSC Payload, update the route tree, and preserve layouts that do not need to change. By default, Link can prefetch routes when links enter the viewport. Streaming allows parts of a response to arrive progressively when relevant features and the deployment path support it. These mechanisms improve perceived responsiveness, but they are not universal speed guarantees.

// app/page.tsx
import Link from 'next/link'

export default function Home() {
  return (
    <nav>
      <Link href="/dashboard">Dashboard</Link>
    </nav>
  )
}

6. Rendering modes and the cache boundary

Next.js can prerender a route at build time or during revalidation, or render it at request time. Static rendering and caching are common defaults, but dynamic APIs and explicit configuration can change the result.

Path When it runs Typical reason
Build-time prerender During production build Content is known ahead of time.
Revalidation After a configured interval or invalidation Refresh data without rebuilding the whole application.
Request-time dynamic rendering For an incoming request Output depends on cookies, search parameters, headers, or other request data.
Streaming While a response is being produced Send available UI progressively when the runtime supports it.

Dynamic APIs such as cookies and request-dependent search parameters can opt rendering into dynamic behavior. Cache Components are documented as an opt-in feature that can combine a static shell with cached or deferred dynamic content. Confirm the installed Next.js version and configuration before drawing Cache Components or Partial Prerendering as a guaranteed part of a project.

Next.js documentation describes the static/dynamic boundary at the component level rather than the route level. Therefore, a route diagram should show which components are cached, uncached, deferred, or request-dependent instead of coloring an entire route only “static” or “dynamic.”

7. Data fetching and server boundaries

Server Components can fetch directly from data sources. Do not assume every application contains a separate backend service, and do not add a Route Handler hop solely because the code runs on the server. A Route Handler is appropriate when an external client needs an HTTP endpoint; a Server Component can generally call its data source directly.

// app/reports/page.tsx
export default async function ReportsPage() {
  const response = await fetch('https://example.com/api/reports', {
    next: { revalidate: 300 },
  })
  if (!response.ok) throw new Error('Unable to load reports')
  const reports = await response.json()
  return <pre>{JSON.stringify(reports, null, 2)}</pre>
}

The exact cache behavior depends on the installed version, fetch options, dynamic APIs, and project configuration. Treat the snippet as a shape for the data path, not as a promise that every fetch is cached.

8. Deployment topology

The current deployment guide lists a Node.js server as the minimum platform requirement for the described Next.js features. A single next start process can handle the application, while production deployments may add a reverse proxy, CDN, and shared cache.

# production build and start
npm run build
npm run start

For self-hosting:

  • Put a reverse proxy in front of the Next.js server, as recommended by the self-hosting guide.
  • Ensure the deployment path supports streaming when you depend on progressive Server Component delivery.
  • Use shared cache and tag coordination for multi-instance consistency.
  • Remember that a tag invalidation on one instance does not automatically invalidate other instances unless the instances share invalidation state.
  • Draw edge stitching or platform adapters only when your chosen platform documents support for the features you use.

A useful deployment diagram separates the Next.js runtime from infrastructure concerns: reverse proxy, CDN, cache, process replicas, and data sources. Do not label a generic edge runtime as interchangeable with a Node.js server without checking the platform feature matrix.

9. How to make your own architecture diagram

  1. Write “App Router” or “Pages Router” and the Next.js version in the title.
  2. Draw the browser and label initial HTML, RSC Payload, hydration, and later client transitions.
  3. Draw layouts and pages inside the Next.js runtime.
  4. Mark Server Components as the default and place explicit Client Component boundaries around interactive code.
  5. Split rendering into build/revalidation and request-time paths.
  6. Connect server code to databases, APIs, and files without inventing a mandatory backend tier.
  7. Add cache and revalidation behavior beside the components or data reads it affects.
  8. Add the deployment runtime, reverse proxy, and shared cache only when they exist in the target topology.
  9. Annotate version-sensitive features such as Cache Components, adapters, and streaming support.

Or skip the browser setup

If you need a rendered image of a documentation page or diagram, ScreenshotNeo provides a single-call screenshot API. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the page verdict and billing result.

See the ScreenshotNeo API docs for all options. This cURL request returns a WebP screenshot:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. It includes full-page capture, element selection, dark mode, device presets, custom CSS and JavaScript, waits, request blocking, cookies and headers, geolocation, caching, signed links, asynchronous jobs, bulk capture, and a usage API. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

10. Troubleshooting an architecture diagram

Symptom Likely cause Fix
Interactive code fails during build A Server Component uses browser-only APIs or event handlers. Move the interactive portion behind a use client boundary.
The client bundle is unexpectedly large A high-level client boundary imports many descendants. Move use client deeper and keep data-heavy UI on the server.
Personalized output is cached The diagram assumes static rendering despite request-dependent data. Review cookies, headers, search parameters, fetch options, and explicit cache configuration.
Data is stale on one replica Instances do not share cache or tag invalidation state. Configure shared cache and coordinated invalidation, or reduce the topology.
Streaming does not appear A proxy or hosting adapter buffers responses, or the feature is unsupported. Check the deployment feature matrix and proxy buffering configuration.
A Pages Router diagram does not match the code The project was documented as App Router. Inspect whether routes live under app/ or pages/, then redraw with the matching model.
A screenshot contains a consent banner The capture tool loaded the page exactly as a fresh browser session. Use ScreenshotNeo’s consent and popup removal options, or handle the banner in your own browser automation.

11. Performance, reliability, and cost considerations

  • Performance: Keep client boundaries narrow, use prefetching and client transitions where appropriate, and stream only through infrastructure that supports it. Avoid treating static rendering or prefetching as a universal latency guarantee.
  • Reliability: Version the diagram, document dynamic APIs and cache invalidation, and test the actual deployment topology. Multi-instance cache behavior needs coordination.
  • Operational cost: Build-time and cached work can reduce repeated origin computation, while request-time rendering consumes runtime capacity. The right split depends on freshness, personalization, and infrastructure.
  • Screenshot cost: ScreenshotNeo bills only clean shots. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response includes X-Page-Verdict and X-Billed headers.

12. FAQ

Is every Next.js page a Server Component?

In the App Router, layouts and pages are Server Components by default. A use client directive creates a client boundary for the module graph below it.

Does the browser receive the RSC Payload on the first request?

Yes. The server renders the Server Component tree into an RSC Payload and also pre-renders HTML for the initial visit. The browser uses both during reconciliation and hydration.

Should an architecture diagram always include a database?

Only if the application uses one. Next.js Server Components can fetch from APIs, databases, files, or other data sources; no separate backend service is mandatory.

When should I draw a CDN or edge runtime?

When the selected deployment platform and application actually use it. Confirm support for streaming, caching, and adapters before adding those paths to a version-specific diagram.

Can I capture the diagram as a PDF?

Yes. ScreenshotNeo includes PDF capture through its API and MCP server, with controls for paper size, margins, landscape mode, and page ranges.

Sources: Server and Client Components, Linking and Navigating, Production Checklist, Cache Components, Deploying to Platforms, and Self-Hosting.