⚙️

Astro on VercelでオンデマンドISRする

に公開

Vercel上にAstroプロジェクトをデプロイしている環境下でオンデマンドISRをしたいと思ったが、以下のVercelの記事通りにやっても動かず、えらいハマったのでメモ。

https://vercel.com/blog/isr-a-flexible-way-to-cache-dynamic-content#on-demand-isr

検証した時点での各種ライブラリのバージョンは以下。

"@astrojs/vercel": "^8.2.7",
"astro": "^5.10.1",

結論としては以下のキャプチャの箇所が多分嘘で、Astro上でSSRするページでなければISRは動作しない。

実際に動作したコードを以下のリポジトリに置いておきました。

https://github.com/srkw/astro-ondemand-isr

このコードをVercel上にデプロイし、環境変数経由で設定した REVALIDATE_TOKEN を使って

curl -I -H "x-prerender-revalidate: {REVALIDATE_TOKEN}" \
  -H "origin: https://astro-ondemand-isr.vercel.app" \
  https://astro-ondemand-isr.vercel.app/isr-check

というHEADリクエストを送信すると、パスの再検証ができ、いわゆる「オンデマンドISR」を再現できます。初回アクセス時とISR実行時で、 /isr-check の画面上に表示されるタイムスタンプが変わるはず。
再検証が成功した場合は x-vercel-cache: REVALIDATED というレスポンスヘッダが含まれたレスポンスが返るので、この値をもって成功判定などをやれば良さげです。

Vercelのランタイムの実装が公開されていないっぽくコードを追えなかった(公開されていたら教えて欲しいです🙇)のですが、外形的に観測した感じだと、Astroを使ったVercelのon-demand ISRは

  • SSRした各種ページをCDNレイヤーでキャッシュ
  • x-prerender-revalidate リクエストヘッダを含むGET or HEADリクエストを受け取るとCDN上のキャッシュをパージしてアプリケーションレイヤーにリクエストをバイパス
  • Astro側で再度ページをSSRして返却
  • 新しいレスポンスをまたキャッシュする

という形で実現しているように見えました。
認識齟齬がある場合は、コメント等でご指摘いただけますと幸いです。

alias: vercel astro on-demand isr

Discussion