コンテンツへスキップ
ドキュメント
Next.js SSG と SSR

Next.js での使用

App Router

サーバーコンポーネント

Next.js App Router では、すべてのコンポーネントがデフォルトで React サーバーコンポーネント (RSC) です。 **RSC では SWR からキーのシリアライズ API のみをインポートできます。**

app/page.tsx
import { unstable_serialize } from 'swr' // ✅ Available in server components
import { unstable_serialize as infinite_unstable_serialize } from 'swr/infinite' // ✅ Available in server components
🚫

RSC では利用できないため、SWR から他の API をインポートすることはできません。

app/page.tsx
import useSWR from 'swr' // ❌ This is not available in server components

クライアントコンポーネント

コンポーネントを 'use client' ディレクティブでマークするか、クライアントコンポーネントから SWR をインポートすると、両方の方法で SWR クライアントデータフェッチフックを使用できます。

app/page.tsx
'use client'
import useSWR from 'swr'
export default Page() {
  const { data } = useSWR('/api/user', fetcher)
  return <h1>{data.name}</h1>
}

サーバーコンポーネント layout または page でグローバル設定を構成するために SWRConfig を使用する必要がある場合は、プロバイダーと設定をセットアップする別のプロバイダークライアントコンポーネントを作成し、それをサーバーコンポーネントページで使用してください。

app/swr-provider.tsx
'use client';
import { SWRConfig } from 'swr'
export const SWRProvider = ({ children }) => {
  return <SWRConfig>{children}</SWRConfig>
};
app/page.tsx
// This is still a server component
import { SWRProvider } from './swr-provider'
export default Page() {
  return (
    <SWRProvider>
      <h1>hello SWR</h1>
    </SWRProvider>
  )
}

クライアント側データフェッチ

ページに頻繁に更新されるデータが含まれており、データを事前にレンダリングする必要がない場合、SWR は最適であり、特別な設定は必要ありません。必要なのは、useSWR をインポートして、データを使用するコンポーネント内でフックを使用するだけです。

仕組みは次のとおりです。

  • まず、データなしでページをすぐに表示します。欠落しているデータに対してローディング状態を表示できます。
  • 次に、クライアント側でデータをフェッチし、準備ができたら表示します。

このアプローチは、たとえば、ユーザーダッシュボードページに適しています。ダッシュボードはプライベートなユーザー固有のページであるため、SEO は関係がなく、ページを事前にレンダリングする必要はありません。データは頻繁に更新されるため、リクエスト時のデータフェッチが必要です。

デフォルトデータによるプリレンダリング

ページを事前にレンダリングする必要がある場合、Next.js は 2 つの形式のプリレンダリング (新しいタブで開く) をサポートしています。**静的生成 (SSG)** と **サーバーサイドレンダリング (SSR)** です。

SWR と共に、SEO のためにページを事前にレンダリングし、クライアント側でキャッシュ、再検証、フォーカストラッキング、インターバルでの再フェッチなどの機能を利用することもできます。

SWRConfigfallback オプションを使用すると、プリフェッチされたデータをすべての SWR フックの初期値として渡すことができます。

たとえば、getStaticProps を使用する場合

 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>
  )
}

ページは引き続き事前にレンダリングされます。SEO に対応し、高速な応答が可能ですが、クライアント側では SWR によって完全に機能します。データは動的であり、時間の経過とともに自己更新できます。

💡

Article コンポーネントは、最初に事前生成されたデータをレンダリングし、ページがハイドレートされた後、最新のデータを再度フェッチして、鮮度を維持します。

複合キー

useSWR は、array 型および function 型であるキーで使用できます。この種のキーを使用してプリフェッチされたデータを利用するには、fallback キーを unstable_serialize でシリアライズする必要があります。

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>
  )
}