Partial prefetching in Next.js is what makes a route feel instant even when part of it depends on live data. This article assumes a project has Cache Components enabled, since partial prefetching builds directly on the app shell that model produces for each route. Partial prefetching is a separate setting on top of that, controlling how much of a route a Link fetches before a reader clicks it.
Without it, a dynamic route with no cached content often prefetches little or nothing ahead of time, so a click still has to wait on a full server round trip. Partial prefetching changes what gets sent ahead by fetching the route's static shell instead of waiting for everything to be ready.
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
export default nextConfig;With both flags on, visiting a page and scrolling a link into view now prefetches that route's app shell, the static and cached parts of it, ahead of any click.
What the app shell actually contains
The app shell is a per-route prerender holding everything in a page that does not depend on request-specific data, such as the surrounding layout and any content covered by use cache. Whatever falls outside that, like data tied to the current user or a live value, renders later instead of blocking the shell.
// app/dashboard/page.tsx
import { Suspense } from "react";
import LiveStats from "./live-stats";
export default function DashboardPage() {
return (
<>
<h1>Dashboard</h1>
<Suspense fallback={<p>Loading stats…</p>}><LiveStats /></Suspense>
</>
);
}The heading and surrounding layout arrive instantly from the prefetched shell. LiveStats shows its fallback briefly and then streams in once the server finishes rendering it, since it sits outside what the shell already covered.
Why this is not the same as Partial Prerendering
Partial Prerendering describes how a route renders on the server: a static shell plus content that streams in behind Suspense. Partial prefetching is a separate concern, controlling how much of that same shell a link fetches into the browser ahead of a click. One is a rendering model, the other is a client-side fetching behavior built on top of it.
Adopting it in an existing project
Turning the flag on affects every link that currently prefetches in full. Review each one: a link to fully static content usually needs no changes, one pointing at data that is not yet cached should have that data wrapped in use cache, and a link to a live or per-user route may need prefetch={true} kept explicitly so it still fetches everything instead of only the shell.
For the base prefetching behavior this article builds on, see How Prefetching Works in Next.js and How to Control It. To show a pending indicator on a link while its streamed content is still loading, read useLinkStatus: Showing Pending State During Navigation.
Rune AI
Key Insights
- Partial prefetching requires Cache Components, plus its own separate config flag.
- A prefetched app shell contains the static and cached parts of a route.
- Dynamic, request-specific content streams in after navigation behind Suspense.
- Partial Prerendering is the rendering model, partial prefetching is what Link fetches ahead of time.
- A page can still feel instant even when part of it depends on live data.
Frequently Asked Questions
Do I need Cache Components enabled for this?
Is partial prefetching the same thing as Partial Prerendering?
Does a link still work if the dynamic part of the page is slow?
Conclusion
This article assumes a project has Cache Components enabled. Partial prefetching sends a route's static app shell ahead of a click instead of the whole page, so navigation shows real content immediately and streams in only the parts that depend on the request behind a Suspense boundary.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.