---
title: prefetch
description: Defer runtime work until a per-link prefetch or navigation with the prefetch function.
url: "https://nextjs.org/docs/app/api-reference/functions/prefetch"
docs_index: /docs/llms.txt
lastUpdated: 2026-10-15
navTitle: "prefetch"
prerequisites:
  - "API Reference: /docs/app/api-reference"
  - "Functions: /docs/app/api-reference/functions"
related:
  - /docs/app/guides/optimizing-prefetching
  - /docs/app/guides/keeping-pages-static
  - /docs/app/api-reference/functions/navigation
  - /docs/app/api-reference/functions/connection
  - /docs/app/api-reference/config/next-config-js/partialPrefetching
---

> For an index of all documentation, see [/docs/llms.txt](/docs/llms.txt).

Calling `await prefetch()` keeps runtime work below it out of the route's [App Shell](/docs/app/glossary#app-shell). The work can run during a per-link prefetch or navigation, while the fallback of the nearest [`<Suspense>`](https://react.dev/reference/react/Suspense) boundary renders in the shell.

Use `prefetch()` for content that the App Shell would otherwise render but that is expensive to generate. Static prerenders still include the content in their output.

## Usage

The function requires [Cache Components](/docs/app/api-reference/config/next-config-js/cacheComponents) and throws an error if not enabled. Without [Partial Prefetching](/docs/app/api-reference/config/next-config-js/partialPrefetching) a route has no App Shell, so the function has no effect. Enable Partial Prefetching globally, or one route at a time, by [adopting Partial Prefetching](/docs/app/guides/adopting-partial-prefetching).

```ts highlight={4,5} title="next.config.ts"
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
  partialPrefetching: true,
}

export default nextConfig
```

With Partial Prefetching enabled, Next.js loads server-rendered output in stages, before and during a client navigation. These are the route's [navigation stages](/docs/app/glossary#navigation-stages):

1. A default `<Link>` loads the App Shell, which holds the part of the route that does not depend on the URL.
2. An optional [`<Link prefetch={true}>`](/docs/app/api-reference/components/link#prefetch) can also load content that depends on the link's URL.
3. When the user follows the link, the navigation renders the rest of the route.

During runtime rendering, awaiting `prefetch()` keeps content out of the App Shell, so it renders during a per-link prefetch or navigation. Static prerenders can still include the content.

To keep content out of per-link prefetches as well, so it renders only on the navigation, use [`navigation()`](/docs/app/api-reference/functions/navigation).

> **Good to know:**
>
> `prefetch()` defers one subtree. To require a static App Shell across the route, use [`ensureStatic = 'shell'`](/docs/app/api-reference/file-conventions/route-segment-config/ensureStatic#shell). See [Keeping pages static](/docs/app/guides/keeping-pages-static) for a worked example.

Everything above `prefetch()` renders in the App Shell, and everything below renders on a per-link prefetch or on the navigation. Deferral is scoped to the component that awaits it and the tree below: sibling branches render in the shell as usual. Place it above the work to defer, and wrap the component in [`<Suspense>`](https://react.dev/reference/react/Suspense):

**TypeScript**

```tsx highlight={25} title="app/dashboard/page.tsx" 
import { Suspense } from 'react'
import { cookies } from 'next/headers'
import { cacheLife, prefetch } from 'next/cache'

export default function Page() {
  return (
    <>
      <Suspense fallback={<p>Loading greeting...</p>}>
        <Greeting /> {/* in the App Shell */}
      </Suspense>
      <Suspense fallback={<p>Loading recommendations...</p>}>
        {/* the fallback is in the App Shell, the recommendations are not */}
        <Recommendations />
      </Suspense>
    </>
  )
}

async function Greeting() {
  const session = (await cookies()).get('session')?.value
  return <p>{session ? 'Welcome back' : 'Welcome'}</p>
}

async function Recommendations() {
  await prefetch() // runtime work below renders on a per-link prefetch or navigation
  const items = await getRecommendations()
  return <List items={items} />
}

async function getRecommendations() {
  'use cache: private'
  cacheLife('hours')
  const session = (await cookies()).get('session')?.value
  return db.recommendations.rank({ session })
}
```

**JavaScript**

```jsx highlight={25} title="app/dashboard/page.js" 
import { Suspense } from 'react'
import { cookies } from 'next/headers'
import { cacheLife, prefetch } from 'next/cache'

export default function Page() {
  return (
    <>
      <Suspense fallback={<p>Loading greeting...</p>}>
        <Greeting /> {/* in the App Shell */}
      </Suspense>
      <Suspense fallback={<p>Loading recommendations...</p>}>
        {/* the fallback is in the App Shell, the recommendations are not */}
        <Recommendations />
      </Suspense>
    </>
  )
}

async function Greeting() {
  const session = (await cookies()).get('session')?.value
  return <p>{session ? 'Welcome back' : 'Welcome'}</p>
}

async function Recommendations() {
  await prefetch() // runtime work below renders on a per-link prefetch or navigation
  const items = await getRecommendations()
  return <List items={items} />
}

async function getRecommendations() {
  'use cache: private'
  cacheLife('hours')
  const session = (await cookies()).get('session')?.value
  return db.recommendations.rank({ session })
}
```

The greeting reads the session and stays in the App Shell. The recommendations read it too, inside `getRecommendations`, so that read is deferred along with the ranking. Remove `prefetch()` and they become part of the App Shell that every link into the route loads.

Put the directive on a function called below it, as `getRecommendations` does here. Awaiting `prefetch()` inside a cached scope, such as [`use cache`](/docs/app/api-reference/directives/use-cache) or [`use cache: private`](/docs/app/api-reference/directives/use-cache-private), is not allowed.

## How `prefetch()` differs from `connection()`

The [`connection()`](/docs/app/api-reference/functions/connection) function waits for a real request. It excludes the code that follows from prerendering and prefetching, making that work request-dependent.

Awaiting `prefetch()` excludes the code that follows from the App Shell. It can resolve during a per-link prefetch without making that work request-dependent. A function called after `await prefetch()` can therefore use [`"use cache"`](/docs/app/api-reference/directives/use-cache) and keep its cache lifetime without generating its result for every link into the route.

Use `connection()` when the work must run for a real request. Use `prefetch()` when the work is reusable but should only run for a selected per-link prefetch or a navigation.

## When to use it

Use `prefetch()` when the content below it is expensive to produce and should not be generated in the App Shell that every `<Link>` into the route loads.

Producing the App Shell does not run that code, so its upstream requests are not issued until a per-link prefetch or the navigation.

Leaving content uncached also keeps it out of the shell, but gives up its cache lifetime and cannot make it available during a per-link prefetch. With `prefetch()`, the content can be cached with [`use cache`](/docs/app/api-reference/directives/use-cache) or [`use cache: private`](/docs/app/api-reference/directives/use-cache-private), given a lifetime, and deferred to a per-link prefetch or navigation.

Uncached reads, values with a short [`stale`](/docs/app/api-reference/functions/cacheLife#stale) time, and anything behind `params` or `searchParams` are already left out of the shell on their own.

### Keeping the App Shell static

When every read of [`cookies()`](/docs/app/api-reference/functions/cookies) and [`headers()`](/docs/app/api-reference/functions/headers) sits below `prefetch()`, the prerender a shell prefetch would trigger cannot produce more than the static output the build already generated, so the shell is served from that output instead. Shaping a route this way is an optional optimization: a static response can be cached in a CDN, so a default `<Link>` into the route costs no server CPU at all. A route that resolves `params` or `searchParams` gets that prerender instead, and so does the example above: its greeting reads the session in the shell, so the shell renders once per visitor and only the recommendations are deferred.

## Good to know

- The function has no effect on the initial load of a page.
- Unlike [`connection()`](/docs/app/api-reference/functions/connection), it does not mark the subtree as request-dependent. Content below `await prefetch()` stays fully cacheable and can be wrapped in [`use cache`](/docs/app/api-reference/directives/use-cache).
- A call outside a `<Suspense>` boundary surfaces an [Instant Insight](/docs/messages/instant-navigation-stage) in development. A fully prerendered route is unaffected, but the insight identifies that the call would defer content without a fallback if the route later requires runtime rendering.
- Calling it inside `use cache`, `use cache: private`, [`unstable_cache()`](/docs/app/api-reference/functions/unstable_cache), [`after()`](/docs/app/api-reference/functions/after), [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params), or a Client Component throws.
- In a `page` or `layout` that sets the [`prefetch` route segment config](/docs/app/api-reference/file-conventions/route-segment-config/prefetch), import the function under another name, for example `import { prefetch as prefetchStage } from 'next/cache'`, since both are named `prefetch`.

## Reference

### Type

```ts
function prefetch(): Promise<void>
```

### Parameters

- The function does not accept any parameters.

### Returns

A `Promise<void>`. It is not meant to be consumed.

## Version History

| Version   | Changes                                                                                        |
| --------- | ---------------------------------------------------------------------------------------------- |
| `v16.4.0` | `prefetch` introduced, replacing the `unstable_prefetch` name used in earlier canary releases. |

- [Optimizing prefetching](/docs/app/guides/optimizing-prefetching): Resolve per-link URL data, include session data in the App Shell, or defer expensive work to a later navigation stage.
- [Keeping pages static](/docs/app/guides/keeping-pages-static): Keep selected route output static as your app changes.
- [navigation](/docs/app/api-reference/functions/navigation): Defer runtime work until the user navigates with the navigation function.
- [connection](/docs/app/api-reference/functions/connection): API Reference for the connection function.
- [partialPrefetching](/docs/app/api-reference/config/next-config-js/partialPrefetching): Configure the default link prefetch behavior to fetch only the static parts of each route.

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/docs/llms.txt](/docs/llms.txt)