Lesson 7
動的なルーティングの実装方法
Lesson 7
Chapter 1
基礎知識
動的なルーティング(ダイナミックルーティンング)とは
本レッスンではNext.jsの動的なルーティングについて学んでいきます。
Next.js では、pages/books/[id].jsx のようなファイル名でページを作成すると、1 つのファイルで、
・/books/001
・/books/002
・/books/003
のようなパス (URL) によるアクセスを制御できます。
これを ダイナミックルーティング (Dynamic Routes) 機能と呼びます。
Next.js のページコンポーネント (/pages/xxx.jsx) は、そのページのルートコンポーネントとなるため、
通常の React コンポーネントとは違って、上位のコンポーネントから props 情報を渡すことができません。
そこで Next.js では、ページコンポーネントの実装ファイル内で getStaticProps 関数を定義することで、
ページコンポーネントに渡す props 情報を生成できるようにしています。
getStaticProps 内では、上記のような URL パラメータ情報(/books/[id] の id の部分の値)を取り出して、それを元に props 情報を生成できます。
この仕組みによって、Next.js のページコンポーネントは、1 つの .jsx ファイルで、複数のページ (.html) を生成できるようになっています。
getStaticPathsとは
SSGを用いてダイナミックルーティングを行う場合、あらかじめどのようなパラメーター(上記の例では id)でのアクセスが行われるかを把握した上で、各ページの内容を生成する必要があります。
これを実現するには、ページコンポーネントの実装ファイル (pages/*.jsx) で、getStaticPaths関数と前レッスンで学習したgetStaticPropsを実装して export します。
getStaticPaths関数
URL のパラメーター部分(上記の例では id)で指定可能な値を返すように設定します。
この関数は通常、Web サイトのビルド時にだけ実行されます。
次の例ではgetStaticPaths関数で/books/001、/books/002、/books/003 といった URL でアクセス可能な books/[id] ページを定義しています。
pages/books/[id].jsx
const getStaticPaths = async () => {
return {
paths: [
{
id: '001',
id: '002',
id: '003'
}
],
fallback: false // 上記以外のパスでアクセスした場合は 404 ページにする
}
}
上記の様にあらかじめアクセスが想定されるパラメータを定義し、それ以外はfallbackプロパティでfalseを設定し404を返却する使用方法が一般的です。
またブログ等の記事更新等でパラメータのリストが動的に変わっていく場合、そのパラメータリストをfetch関数を使用して他APIサーバから取得することも可能です。
次のチャプターではgetStaticPaths関数と前レッスンで学習したgetStaticProps関数を使用して実際に動的なルーティングを実装していきましょう。

Lesson 7
Chapter 2
動的なルーティングの実装
getStaticPathsの実装
それでは実際に動的なルーティングを実装していきましょう。
データの取得先については前レッスン同様「JSONPlaceholder」を利用します。
取得したデータのID別にページをビルドし、内容としてタイトルと本文を表示させます。
Next.jsでは、pages内でファイル名に[]を使用することで自動的にダイナミックルーティングの対象となるので
ファイル名はpages/dynamic/[id].jsx
とし新規作成します。
ここでもう一度おさらいです。
ダイナミックルーティング用のファイルでは、getStaticPathsとgetStaticPropsの関数が必要です。
※ これらの関数は前レッスンのSSGにあたり、クライアント側での実行でなく、必ずサーバーサイドで実行されます。
それではgetStaticPathsから実装していきます。
pages/dynamic/[id].jsx
const Dynamic = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
};
export const getStaticPaths = async () => {
// JSONPlaceholderAPIと接続しデータ取得
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
const paths = posts.map((post) => ({
params: {
id: post.id.toString(),
},
}));
return { paths, fallback: false };
};
export default Dynamic;
上記でビルドする対象のリストパラメータ「paths」が作成できました。 pathsは事前ビルドするパス対象を指定する専用のパラメータです。データ取得先と型を揃えることに注意しましょう。 又、fallbackをfalseで事前ビルドしたパス以外にアクセスしたとき 404pageを表示をするようにgetStaticProps関数に渡していきます。
getStaticPropsの実装
それでは作成したpathsをgetStaticProps関数に渡してページをビルドするように実装していきます。
pages/dynamic/[id].jsx
const Dynamic = ({ post }) => {
return (
<div>
<h1>{post.title}</h1>
<p>{post.body}</p>
</div>
);
};
export const getStaticPaths = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts = await res.json();
const paths = posts.map((post) => ({
params: {
id: post.id.toString(),
},
}));
return { paths, fallback: false };
};
export const getStaticProps = async ({ params }) => {
const res = await fetch(
`https://jsonplaceholder.typicode.com/posts/${params.id}`
);
const post = await res.json();
return {
props: {
post,
},
};
};
export default Dynamic;
画面表示までの流れ
・getStaticPathsで、レンダリングする必要のあるパスのリストを生成する
・getStaticPropsで、1で生成したパスのリストから1postずつAPIを呼び出しデータを取得する
・ページコンポーネントがgetStaticPropsからデータを受け取り、画面に表示される
上記の様な流れになります。
動作確認
それでは動作確認していきます。
ターミナルでnpm run buildを実行します。
上記のコマンドでビルドが実行され、sample-app/.next/server/pages/dynamic配下に
以下の画像の様に1.html,1.json,2.html,2.json...
100.jsonまでファイルが生成されていることを確認しましょう。

上記の様になっていれば、SSGのファイルの生成は問題ありません。 実際にページの中身もみていきます。 生成されたファイルの1.htmlをブラウザで開いてみてください。 下記のようにタイトルと本文の内容が、JSONPlaceHolderのid:1の内容と同じであれば動的なルーティングの実装が完了です。


