LoginSignup
7
5

More than 1 year has passed since last update.

[Next.js] Incremental Static Regeneration 時の getStaticPaths で渡すパスについて

Last updated at Posted at 2021-08-17

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 される

getStaticPropsrevalidate を設定したとしても、 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
こんなサンプルもあるので、それも読んどけば〜〜〜

っていうお話でした。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5