⏲️

App Router のページ更新時間を設定

に公開

要約

Next.js の App Router を使っている場合、revalidateを設定するとページの再生成タイミングを制御できます。
設定しないとビルド時のみ生成、設定すると指定秒数ごとにバックグラウンドで再生成されます。

やりたかったこと

イベント確認アプリを作っています。
設定画面でDBから主催者一覧を取得していますが、主催者は頻繁に変わりません。

毎回DBにアクセスするのは無駄なので、30分毎の更新に抑えたいと思いました。

解決方法

ページにrevalidateを追加するだけで任意の更新頻度に抑えられるようです。
指定する時間がミリ秒ではなく秒で指定するというところは気をつけないといけません。

// app/settings/page.tsx
import { getSupabase } from "@/lib/supabase";

// 30分(1800秒)キャッシュ
export const revalidate = 1800;

async function getUsers() {
  const supabase = getSupabase();
  const { data } = await supabase.from("users").select("id, name");
  return data || [];
}

export default async function SettingsPage() {
  const users = await getUsers();
  return <div>{/* ... */}</div>;
}

revalidate の仕様

設定 動作
revalidateなし ビルド時のみ取得。再デプロイまで固定
revalidate = 1800 30分ごとにバックグラウンドで再取得
revalidate = 0 毎回DBにアクセス

検証

pnpm buildすると設定が反映されているか確認できます。

Route (app)                Revalidate
└ ○ /settings                     30m

30mと表示されていればOK。
実際にページを開いた後、DBを更新し、ページを定期的に更新したところ、設定した時間で値が変わることが確認できました。

注意点

  • 開発モード(pnpm dev)ではキャッシュが効かないので確認できない
  • 確認したい場合はpnpm build && pnpm startで本番モードで起動

おわりに

設定がとても簡単でした。
ちなみに、Pages Router(pages/ディレクトリ)の場合はgetStaticPropsで同じ様に設定できるみたいです。

// pages/settings.tsx
export async function getStaticProps() {
  const users = await getUsers();
  return {
    props: { users },
    revalidate: 1800, // 30分
  };
}

参考

https://nextjs.org/docs/app/guides/incremental-static-regeneration

GitHubで編集を提案

Discussion