Adopting Partial Prefetching

Learn how to enable Partial Prefetching and what changes for `<Link>`.

Partial Prefetching changes what <Link> downloads for a Cache Components route. By default, a <Link> loads a per-route App Shell, and the page's cached content is downloaded only when the link sets prefetch={true}. This is the biggest change from the pre-Cache Components behavior, where fully static pages were always prefetched by default.

<Link prefetch={true}> also stops prefetching dynamic content. It now only prefetches the cached parts of the page, so the link no longer pulls cookies, headers, or other request-time data ahead of the navigation.

Good to know: Partial Prefetching only works when cacheComponents is enabled.

<Link> propBefore (Cache Components default)After Partial Prefetching
<Link href="/x">Prefetched the cached page render.Loads the App Shell for /x.
<Link href="/x" prefetch>Prefetched the cached page render and any dynamic content.Loads the App Shell and the cached page content.
<Link href="/x" prefetch={false}>Disabled prefetching for this link.Unchanged. Still disabled.

The App Shell is shared across every link to a given route, regardless of dynamic params, so rendering many <Link>s to the same destination doesn't multiply the work.

Adopting in a new project

Enable partialPrefetching in next.config.ts alongside Cache Components:

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  cacheComponents: true,
  partialPrefetching: true,
}
 
export default nextConfig

Add prefetch to any <Link> whose destination's cached content is worth shipping ahead of the navigation. Leave it off for the rest:

app/page.tsx
import Link from 'next/link'
 
export default function Page() {
  return (
    <nav>
      <Link href="/products">Products</Link>
      <Link href="/checkout" prefetch>
        Checkout
      </Link>
    </nav>
  )
}

Adopting incrementally in an existing project

If you can't enable partialPrefetching for the entire app at once, opt routes in one at a time with the prefetch route segment config:

app/products/[slug]/page.tsx
export const prefetch = 'partial'
 
export default function Page() {
  return <div>...</div>
}

A <Link> pointing at a route with prefetch = 'partial' loads the App Shell only, even when partialPrefetching is not set in next.config.ts.

Good to know: Adopting per-route first also preserves the dev-only <Link prefetch={true}> warning, which points at <Link prefetch={true}> calls whose destinations haven't adopted yet. Enabling the global flag first marks every route as adopted, which silences the warning and removes the signal for the audit below.

Once every route in scope has prefetch = 'partial', enable the config and remove the per-route exports:

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  cacheComponents: true,
  partialPrefetching: true,
}
 
export default nextConfig

When partialPrefetching is enabled, <Link prefetch={true}> now prefetches the App Shell plus cached content, but not dynamic data. Review each existing usage and decide whether the prop is still providing value. In next dev, the dev overlay surfaces a link-prefetch-partial insight for each call that points at a route without Partial Prefetching, so you can work through them one at a time.

Previously, <Link prefetch={true}> also prefetched dynamic data.

DestinationRecommendation
Fully static (no "use cache", no Suspense)Drop prefetch={true}. The default <Link> already loads the full page because the App Shell is the page.
Has cached content worth shipping ahead of the clickKeep prefetch={true}. The cached parts come with the App Shell.
Reads request data (cookies(), headers(), searchParams) the user will need on arrivalKeep prefetch={true}. Optionally enhance it with runtime prefetching (prefetch = 'allow-runtime') so the request data is prefetched too.

Good to know: prefetch = 'allow-runtime' is an enhancement that adds runtime prefetching of request data. It is not a way to silence the dev <Link prefetch={true}> warning. That warning means the link does a legacy full prefetch of a route that hasn't adopted Partial Prefetching. The per-route opt-in for Partial Prefetching is prefetch = 'partial', which is separate from 'allow-runtime'.

Before:

app/nav.tsx
<Link href="/about" prefetch={true}>About</Link>           {/* static page */}
<Link href="/products" prefetch={true}>Products</Link>      {/* cached list */}
<Link href="/dashboard" prefetch={true}>Dashboard</Link>    {/* reads cookies */}

After:

app/nav.tsx
<Link href="/about">About</Link>                            {/* default is enough */}
<Link href="/products" prefetch={true}>Products</Link>       {/* unchanged */}
<Link href="/dashboard" prefetch={true}>Dashboard</Link>     {/* and add `prefetch = 'allow-runtime'` to /dashboard */}

Next steps

On this page