Skip to content

Link prefetch default behavior change under Partial Prefetching: App Shell only #1820

@github-actions

Description

@github-actions

Next.js Change

Commit: 16b44a8
PR: #94510

What changed

When Partial Prefetching is enabled (partialPrefetching: true globally or unstable_prefetch = 'partial' per-segment, see #1819), this changes the default behavior of <Link>:

  • Before: <Link> without an explicit prefetch prop would prefetch in partial mode; <Link prefetch={true}> would prefetch the entire page (including dynamic data).
  • After: <Link> with no prefetch prop only prefetches the App Shell of the target page — not page data. Per-page data is only prefetched when prefetch={true} is explicitly set.

Behavior by route type (when Partial Prefetching is enabled)

  • Dynamic / partially static routes: Links never include page content unless prefetch={true} is set; only the App Shell defined by loading.tsx is prefetched. Roughly matches pre-Cache-Components behavior.
  • Fully static routes: Significant behavior change. Previously, the entire static page was prefetched regardless of prefetch prop. Now, content-heavy sites (blogs, docs) need to set prefetch={true} to retain the previous behavior.

Migration aid

A new unstable_prefetch = 'unstable_eager' segment opt-in (and partialPrefetching: 'unstable_eager' global mode) forces every <Link> to a given route to behave as if prefetch={true} was set. This restores the pre-Partial-Prefetching behavior for that route. Not recommended outside migration scenarios.

Files changed (non-test)

  • packages/next/src/build/segment-config/app/app-segment-config.ts
  • packages/next/src/client/components/segment-cache/scheduler.ts+52/-7, the core prefetch-mode decision
  • packages/next/src/server/app-render/create-flight-router-state-from-loader-tree.ts
  • packages/next/src/server/config-schema.ts, config-shared.ts
  • packages/next/src/shared/lib/app-router-types.ts

Impact on vinext

vinext's next/link shim and prefetch logic do not currently implement Partial Prefetching or the segment-cache scheduler (tracked in #1614). When/if vinext implements those, the default behavior of <Link> under Partial Prefetching must follow the new semantics:

  1. Implicit prefetch (no prefetch prop) under Partial Prefetching → App Shell only, not page data.
  2. prefetch={true} under Partial Prefetching → prefetch the full Cache Components payload (still excludes dynamic data; that is the existing Partial Prefetching definition).
  3. unstable_eager segments → treat every <Link> to that route as if prefetch={true} was set.
  4. Fully static routes under Partial Prefetching → no longer eagerly prefetched by default. Document this as a behavioral change in any vinext Partial Prefetching adoption guide.

This is also a documentation-impact change: anyone adopting partialPrefetching on a content-heavy site (blogs, docs — including the nextra-docs-template example) needs to know that link-following will feel slower unless they opt in to eager mode or set prefetch={true} explicitly.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    nextjs-trackingTracking issue for a Next.js canary change relevant to vinext

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions