Back to Blog
Web Development10 min read

Next.js 15 App Router Deep Dive: Server Components, Caching, and Streaming

A production-focused guide to the Next.js App Router — how server components reduce client bundle size, how the new caching model works, and how streaming improves perceived performance for data-heavy pages.

By POINTNEXIS Team

MacBook with Next.js code open on a bright desk

Next.js 15 with the App Router is the most significant shift in React web development in years. Server Components move rendering to the server by default, dramatically reducing client-side JavaScript. The new caching semantics are more explicit, trading magic for predictability.

This guide covers what you need to understand to use the App Router confidently in production — not the happy path, but the tricky parts that catch teams off guard.

React Server Components: What They Can and Cannot Do

Server Components run on the server and send HTML to the client. They can directly access databases, file systems, and secrets without exposing them to the browser. They cannot use hooks, event handlers, or browser APIs — anything that requires client interaction must be a Client Component.

The mental model: components are Server by default in the App Router. Add `'use client'` at the top of a file to opt into client rendering. Keep Client Components as leaves of the tree — they can import Server Components' data as props, but a Client Component cannot import a Server Component.

The New Caching Model Explained

Next.js 15 made `fetch` uncached by default — a breaking change from v14 where all fetches were cached. Use `cache: 'force-cache'` explicitly when you want caching, and `next.revalidate` to set a TTL. This makes caching behavior visible in code rather than implicit.

Route handlers and Server Actions are also uncached by default. For data that updates rarely (CMS content, product catalog), explicit caching with `unstable_cache` or route segment `revalidate` settings gives you full control without surprises.

Streaming with Suspense

Streaming sends HTML in chunks as server work completes. Wrap slow data-fetching components in `<Suspense fallback={<Skeleton />}>` and users see the page shell instantly while slower data loads in progressively.

Loading UIs with `loading.tsx` files apply at the route level. Nested Suspense boundaries let you stream individual sections — the sidebar can load instantly while the main content fetches from a slow API.

Server Actions for Mutations

Server Actions let you write server-side functions called directly from Client Components — no API route needed. They handle form submissions, mutations, and revalidation in a unified model. Use `useFormState` and `useFormStatus` for progressive enhancement that works without JavaScript.

POINTNEXIS web projects default to the App Router for all new builds. The server-first model simplifies data security and dramatically reduces the JavaScript shipped to users — a win for performance, SEO, and Core Web Vitals scores.