コンテンツの更新時にNext.js (App Router) でOn-demand Revalidationを実行する
Table of contents
Next.js (App Router) ではデータのキャッシュを無効化する revalidation機能 として、時間単位で自動的に無効化する「Time-based Revalidation」と、手動で無効化する「On-demand Revalidation」の2種類が用意されています。
ここでは On-demand Revalidation と、Newtの Webhook を利用することで、コンテンツ情報の更新をトリガーに、該当のページのみ、キャッシュを無効化する方法を紹介します。
記事内で使用している主なソフトウェアのバージョン
- Next.js(
next
): 13.5.1
前提条件
- Next.jsのApp Routerを利用していること
- Next.jsの
v13.5.1
以上を利用していること(以前のバージョンでもOn-demand Revalidationは可能ですが、ファイル単位での指定となり、URL単位での指定ができません) - Next.jsの Route Handlers について理解していること
概要
以下の流れで処理を行うものとします。
- コンテンツの更新
- Webhookでリクエストを送信(更新するページを特定する情報を含める)
- Next.jsに実装したrevalidate用のAPIが呼び出され、Webhookのbodyからどのページを更新するべきか読み取る
- 該当ページのキャッシュを無効化する
1. 実装前の準備
実装を始める前に、以下のことを決めましょう。
- コンテンツの更新時に、どのページを更新するか
- 更新するページのパスを取得するために、コンテンツのどのフィールドの情報が必要か
- リクエストが有効なものかどうやって検証するか(そもそも検証は必要か)
ここでは以下の想定で進めます。
- ある記事が更新された場合に、記事の詳細ページ
/articles/${slug}
を更新する - slugの情報は、各コンテンツのslugというフィールドに設定されている
- リクエストが有効か、クエリパラメータのsecretの値で検証する
2. Revalidation処理を実装する
Next.jsの Route Handlers と revalidatePath を利用して、Revalidation処理を実装します。
この処理では、以下のことを行います。
- リクエストが有効なものか、クエリパラメータのsecretの値で検証する(
MY_SECRET_TOKEN
という環境変数を利用する) - Webhookのbodyからslugの値を取り出す
/articles/${slug}
のページを更新する
1import { revalidatePath } from 'next/cache'
2import { NextRequest, NextResponse } from 'next/server'
3
4export async function POST(request: NextRequest) {
5 const secret = request.nextUrl.searchParams.get('secret')
6 if (secret !== process.env.MY_SECRET_TOKEN) {
7 return NextResponse.json({ message: 'Invalid secret' }, { status: 401 })
8 }
9
10 const { slug } = await request.json()
11 revalidatePath(`/articles/${slug}`)
12
13 return NextResponse.json({ revalidated: true, now: Date.now() })
14}
3. 環境変数を登録する
2でリクエストの検証を行うために、MY_SECRET_TOKEN
という環境変数を利用しました。
Vercelを利用する場合、Settings > Environment Variables のページから環境変数を登録できます。Vercelでの環境変数の登録について、詳細はVercelの Environment Variables のドキュメントをご確認ください。
4. Webhookを作成する
次にWebhookを作成し、2で作成したRevalidation処理を呼び出せるようにします。
1で決めた内容をもとに、このWebhookは以下の要件を満たすように作成します。
- URLには、Revalidation処理を呼び出すURLを指定する
- クエリパラメータにsecretの値を設定し、3で登録した値と一致させる
- slug情報を持たせる
Newtの管理画面に入り、スペース設定 > Webhook のページから「作成」を押します。
4-1. URLの指定
クエリパラメータにsecretの値を含め、また2で作成したRevalidation処理を呼び出すために、以下のようなURLを指定します。
https://<your-site.com>/api/revalidate?secret=<token>
例えば、ドメインが「revalidate-sample-aaa-bbb.vercel.app」で、secretが「hogehoge」の場合、https://revalidate-sample-aaa-bbb.vercel.app/api/revalidate?secret=hogehoge
となります。
4-2. ペイロードの設定
ペイロードにはslugの情報を持たせる必要があります。
以下のように {"slug": "{ content.slug }"}
と指定します。
ペイロードには変更後のコンテンツ情報を持たせることができます。コンテンツ情報全体を指定することも、今回のように特定のフィールドに絞ることも可能です。
4-3. その他の設定
最後にステータスを「有効」にして、Webhookを作成します。
ヘッダーの設定は不要です。
5. 処理を確認する
最後に、コンテンツを更新した時、該当ページのキャッシュが無効化されることを確認しましょう。
もし、うまくいかない場合は、Webhookのアクティビティログを確認して 200
が返ってきているか、Revalidation処理で指定しているパスが正しいか確認してみてください。
以上で設定は終了です。
これで、対象のコンテンツが更新された時、該当ページのみ、キャッシュを無効化できます。