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) を使っていくぞー!