2020年3月にリリースされた Next.js 9.3 から,アプリケーションをビルドする戦略として以下3種類の API が使えるようになった.Next.js Blog では「Next-gen Static Site Generation (SSG) Support」と紹介されていた.
getStaticProps- 「ビルド時」にデータを取得する
getStaticPaths- 「ビルド時」にデータを取得する(Dynamic Routing を作る)
getServerSideProps- 「リクエスト時」にデータを取得する
今までの getInitialProps は?
レンダリング時に API からデータを取得するなど,今まで使ってきた getInitialProps はどうなるの?と気になると思う.ドキュメントに書いてある通り,Next.js 9.3 以降は getInitialProps ではなく getStaticProps と getServerSideProps を使うことが推奨 (Recommended) になっている.とは言え,今までの getInitialProps も非推奨とまでは書いてなく,引き続き使える.今後実装するなら,getStaticProps と getServerSideProps を使っていくと良さそう.
なお,getStaticProps と getServerSideProps は Node.js コンテキスト(サーバサイド)で実行される.よって,今まではフロントエンドにも対応した fetch API として,例えば isomorphic-unfetch などを使っていたけど,サーバサイドだけなら node-fetch を使える.Next.js 9.3 に対応したサンプルコードも node-fetch を使うように更新されていたりする.
data-fetch テンプレート
実際に getStaticProps と getServerSideProps を試しながら理解を深めるため,create-next-app で使える data-fetch テンプレートの実装を参考に試した.既に getStaticProps を使った実装に更新されている.さらに今回は TypeScript を使うために with-typescript テンプレートをベースにした.create-next-app に関しては先週の記事にまとめた.
検証環境
今回は Next.js 9.3.5 を使う.
$ npm view next version 9.3.5
また,動作確認をするサンプルコードを pages 直下に実装した.
$ tree pages pages ├── get-server-side-props.tsx └── get-static-props.tsx
サンプルコード : get-static-props.tsx
まず,getStaticProps を使ったサンプルコード get-static-props.tsx を載せる.ビルド時に GitHub API から Next.js の Star⭐️ 件数を取得する.また Link コンポーネントを使って遷移できるように /get-server-side-props へのリンクも実装した.
import React from 'react' import Link from 'next/link' import fetch from 'node-fetch' type Props = { stars: number } function Index({ stars }: Props) { return ( <div> <p>Next.js has {stars} ⭐️</p> <Link href="/get-server-side-props"> <a>Go to getServerSideProps</a> </Link> </div> ) } export async function getStaticProps() { const res = await fetch('https://api.github.com/repos/zeit/next.js') const json = await res.json() return { props: { stars: json.stargazers_count, }, } } export default Index
サンプルコード : get-server-side-props.tsx
次に,getServerSideProps を使ったサンプルコード get-server-side-props.tsx を載せる.リクエスト時に GitHub API から Next.js の Star⭐️ 件数を取得する.また Link コンポーネントを使って遷移できるように /get-static-props へのリンクも実装した.
import React from 'react' import Link from 'next/link' import fetch from 'node-fetch' type Props = { stars: number } function Index({ stars }: Props) { return ( <div> <p>Next.js has {stars} ⭐️</p> <Link href="/get-static-props"> <a>Go to getStaticProps</a> </Link> </div> ) } export async function getServerSideProps() { const res = await fetch('https://api.github.com/repos/zeit/next.js') const json = await res.json() return { props: { stars: json.stargazers_count, }, } } export default Index
ビルド
yarn build を実行すると,実装された getStaticProps と getServerSideProps を参考に判定される./get-static-props は「● (SSG)」となり /get-server-side-props は「λ (Server)」となる.
$ yarn build (中略) Page Size First Load JS ┌ ○ / 1.8 kB 59.9 kB ├ ○ /404 2.61 kB 60.7 kB ├ λ /get-server-side-props 1.84 kB 59.9 kB └ ● /get-static-props 1.85 kB 59.9 kB (中略) λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps) ○ (Static) automatically rendered as static HTML (uses no initial props) ● (SSG) automatically generated as static HTML + JSON (uses getStaticProps) ✨ Done in 5.0s.
動作確認
実際に画面にアクセスして確認した.ビルド時の Star⭐️ 件数は 46914 だった(動作確認中にどんどん増えてて驚いた!).ビルド時と変化させるために Star⭐️ を付けたり消したりした.以下にイメージ画像を載せておく.

1. /get-static-props
getStaticProps の場合はビルド時にデータを取得しているため,素早く表示された.5ms ~ 10ms 程度.直接 http://localhost:3000/get-server-side-props にアクセスすると Content-Type は text/html で返ってきた.Link コンポーネントをクリックしてフロントエンド側で画面遷移をすると Content-Type は application/json で以下のように返ってきた.
{ "pageProps": { "stars": 46914 }, "__N_SSG": true }
2. /get-server-side-props
getServerSideProps の場合はリクエスト時にデータを取得しているため,少し時間がかかる.getStaticProps と同じく,直接 http://localhost:3000/get-server-side-props にアクセスすると Content-Type は text/html で返ってきた.Link コンポーネントをクリックしてフロントエンド側で画面遷移をすると Content-Type は application/json で以下のように返ってきた.
{ "pageProps": { "stars": 46918 }, "__N_SSP": true }
まとめ
Next.js 9.3 で使えるようになった getStaticProps と getServerSideProps の理解を整理するためにサンプルコードを実装しながら試した.getStaticProps はビルド時にデータを取得し,getServerSideProps はリクエスト時にデータを取得する.詳しくは Data fetching のドキュメントにも載っている.Static Site Generation (SSG) を使っていくぞー!