Next.js + Vercelの組み合わせで Incremental Static Regeneration(以後ISRとします) したら、なんか思ったとおりにいかなかったというお話。
完全にドキュメントを読んでいなかった自分の責任だけど、ハマったので他の人がはまらないように
Next.jsのISRとは?
Next.jsのISRについては
https://vercel.com/docs/next.js/incremental-static-regeneration
https://zenn.dev/ria/articles/b709ae94e919c76f814a
によくまとまってます
結論
結論から先に書きます。
getStaticPaths
を使って動的ルートを利用するページ( [id].tsx
みたいなページ)で ISR
をする場合は、
オンデマンドでビルドしたいページのパスを getStaticPaths
で返さないようにします。
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
};
};
export const getStaticProps: GetStaticProps = async ({ params }: PathParams) => {
const article = await getArticleById(params.id);
return {
props: {
article
},
revalidate: 1,
};
};
こんなかんじで、すべてのページをオンデマンドでビルドする場合は paths:[]
みたいに空の配列を返します。
ハマったこと
ISRしているハズなのに全ページビルドされている!!
ISRの特徴だと、「ページはアクセス時にオンデマンドでビルドされるよ」って書いてあります。
それなら、5000件の記事があってもビルドはめっちゃ短くなる! オーすげー
でどうやってやるかみてたら、 getStaticPropsで revalidate: 1
って書くだけと。
なーるほどじゃ、
export const getStaticPaths: GetStaticPaths = async () => {
const ids = await getArticleIds();
const params = ids.map(id => { return { params: {id} });
return {
paths: params, // 各記事のパスを渡したまま
fallback: 'blocking',
};
};
export const getStaticProps: GetStaticProps = async ({ params }: PathParams) => {
const article = await getArticleById(params.id);
return {
props: {
article
},
revalidate: 1, // ←ここにrevalidateだけ追記
};
};
こーですかね
記事はHeadlessCMSで管理していましたので、コンテンツ更新時にwebhookを設定して終わりです。
どうなった
ビルド時に毎回5000件すべての記事がビルドされてました。えーー。話が違います。
コンテンツ更新して保存したときもwebhook経由で全件ビルドされるんで、、、これじゃSSGじゃん。
ってことで、とりあえず、webhookの設定をはずします。
すると、CMSでコンテンツ更新のときは当然ビルドは走らない。
コンテンツ更新後ビルドしなくても、2回目にアクセスしたときにページは更新されるてました。
これがISRかぁ〜と妙な納得をしていました。
いや、違うぞ
ええ、完全な勘違いです。
ISR でも getStaticPaths で渡されたパスに対しては SSG される
getStaticProps
に revalidate
を設定したとしても、 getStaticPaths
で渡されたパスに対しては SSG されるので、ビルド時にページが生成されます。
冒頭でいったようにオンデマンドでビルドするページのパスを渡さないようにしましょう。
https://vercel.com/docs/next.js/incremental-static-regeneration
でも 「100,000件のプロダクトがあるような場合に、もっとも人気のある1000件分のプロダクトのパスをわたして、そこだけ事前にビルド。あとはオンデマンドでビルドする」みたいなケーススタディが書いてありました。
全然読んでませんでした(笑
まとめ
ドキュメントはよく読みましょう。
https://github.com/lfades/static-tweet/blob/master/pages/%5Btweet%5D.js
こんなサンプルもあるので、それも読んどけば〜〜〜
っていうお話でした。