---
title: Usage with Next.js
type: integration
summary: Integrate SWR with Next.js for server-side rendering and static generation.
prerequisites:
  - /docs/getting-started
related:
  - /docs/prefetching
  - /docs/advanced/cache
---

# Usage with Next.js



## App Router

### Server Components

<Callout type="default" emoji="✅">
  In Next.js App Router, all components are React Server Components (RSC) by default. **You can import SWRConfig and the key serialization APIs from SWR in RSC.**
</Callout>

```tsx filename="app/page.tsx" copy
import { unstable_serialize } from 'swr' // ✅ Available in server components
import { unstable_serialize as infinite_unstable_serialize } from 'swr/infinite' // ✅ Available in server components

import { SWRConfig } from 'swr' // ✅ Available in server components
```

<Callout type="error">
  You could not import hook APIs from SWR since they are not available in RSC.
</Callout>

```tsx filename="app/page.tsx" highlight={1}
import useSWR from 'swr' // ❌ This is not available in server components
import useSWRInfinite from 'swr/infinite' // ❌ This is not available in server components
import usesSWRMutation from 'swr/mutation' // ❌ This is not available in server components
```

### Client Components

You can mark your components with `'use client'` directive or import SWR from client components, both ways will allow you to use the SWR client data fetching hooks.

```tsx filename="app/page.tsx" highlight={1} copy
'use client'

import useSWR from 'swr'

export default function Page() {
  const { data } = useSWR('/api/user', fetcher)
  return <h1>{data.name}</h1>
}
```

### Prefetch Data in Server Components

Similar to the [pre-rendering with default data](#pre-rendering-with-default-data) pattern, with React Server Components (RSC) you can go even further.

You can **initiate** the data prefetching on the server side and pass the **promise** to client component tree via the `<SWRConfig>` provider's `fallback` option:

```tsx filename="app/layout.tsx" copy
import { SWRConfig } from 'swr'

export default async function Layout({ children }: { children: React.ReactNode }) {
  // Initiate the data fetching on the server side.
  const userPromise = fetchUserFromAPI()
  const postsPromise = fetchPostsFromAPI()

  return (
    <SWRConfig
      value={{
        fallback: {
          // Pass the promises to client components.
          '/api/user': userPromise,
          '/api/posts': postsPromise,
        },
      }}
    >
      {children}
    </SWRConfig>
  )
}
```

<Callout emoji="💡">
  The two data fetching function calls `fetchUserFromAPI()` and `fetchPostsFromAPI()` will be executed in parallel on the server side because we don't await them immediately.
</Callout>

In React Server Components, you can pass promises across the `"use client"` boundary, and SWR will resolve them automatically during Server-Side Rendering:

```tsx filename="app/page.tsx" copy
'use client'

import useSWR from 'swr'

export default function Page() {
  // SWR will resolve the promise passed from server components.
  // Both `user` and `posts` are ready during SSR and client hydration.
  const { data: user } = useSWR('/api/user', fetcher)
  const { data: posts } = useSWR('/api/posts', fetcher)

  return (
    <div>
      <h1>{user.name}'s Posts</h1>
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  )
}
```

Then, on the client-side SWR will take over and keep the behavior as usual.

By passing promises from Server Components to Client Components, the data fetching can be initiated as early as possible on the server side. And only the UI boundaries (closest `Suspense` boundary or Next.js layout) that actually consume the data will be blocked during streaming SSR.

<Callout type="default">
  To incrementally adopt this prefetch pattern in your application, you can enable the `strictServerPrefetchWarning` option. This will show a warning message in the console when a key has no pre-filled data provided, helping you identify which data fetching calls could benefit from server-side prefetching.
</Callout>

## Client Side Data Fetching

If your page contains frequently updating data, and you don’t need to pre-render the data, SWR is a perfect fit and no special setup is needed: just import `useSWR` and use the hook inside any components that use the data.

Here’s how it works:

* First, immediately show the page without data. You can show loading states for missing data.
* Then, fetch the data on the client side and display it when ready.

This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching.

## Pre-rendering with Default Data

If the page must be pre-rendered, Next.js supports [2 forms of pre-rendering](https://nextjs.org/docs/basic-features/data-fetching):
**Static Generation (SSG)** and **Server-side Rendering (SSR)**.

Together with SWR, you can pre-render the page for SEO, and also have features such as caching, revalidation, focus tracking, refetching on interval on the client side.

You can use the `fallback` option of [`SWRConfig`](/docs/global-configuration) to pass the pre-fetched data as the initial value of all SWR hooks.

For example with `getStaticProps`:

```jsx
 export async function getStaticProps () {
  // `getStaticProps` is executed on the server side.
  const article = await getArticleFromAPI()
  return {
    props: {
      fallback: {
        '/api/article': article
      }
    }
  }
}

function Article() {
  // `data` will always be available as it's in `fallback`.
  const { data } = useSWR('/api/article', fetcher)
  return <h1>{data.title}</h1>
}

export default function Page({ fallback }) {
  // SWR hooks inside the `SWRConfig` boundary will use those values.
  return (
    <SWRConfig value={{ fallback }}>
      <Article />
    </SWRConfig>
  )
}
```

The page is still pre-rendered. It's SEO friendly, fast to response, but also fully powered by SWR on the client side. The data can be dynamic and self-updated over time.

<Callout emoji="💡">
  The `Article` component will render the pre-generated data first, and after the page is hydrated, it will fetch the latest data again to keep it fresh.
</Callout>

### Complex Keys

`useSWR` can be used with keys that are `array` and `function` types. Utilizing pre-fetched data with these kinds of keys requires serializing the `fallback` keys with `unstable_serialize`.

```jsx
import useSWR, { unstable_serialize } from 'swr'

export async function getStaticProps () {
  const article = await getArticleFromAPI(1)
  return {
    props: {
      fallback: {
        // unstable_serialize() array style key
        [unstable_serialize(['api', 'article', 1])]: article,
      }
    }
  }
}

function Article() {
  // using an array style key.
  const { data } = useSWR(['api', 'article', 1], fetcher)
  return <h1>{data.title}</h1>
}

export default function Page({ fallback }) {
  return (
    <SWRConfig value={{ fallback }}>
      <Article />
    </SWRConfig>
  )
}
```
