8.動的ルート
変更前ソース
機能概要
ブログのようにコンテンツが動的に増えていく場合、一つ一つのコンテンツごとにページを作るのは非効率です。このように外部データの分だけページが増え、URLが増える場合、動的ルートが有効です。
機能詳細
「[id].js」のような「[」で始まり、「]」で終わるページが動的ルートになります。
実装方法
「lib/posts.js」に投稿したデータを読み込む次の関数を追加します。
// すべての投稿データのID一覧を取得する
export function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory);
// 次のような配列で返すことを想定
// [
// {
// params: {
// id: 'ssg-ssr'
// }
// },
// {
// params: {
// id: 'pre-rendering'
// }
// }
// ]
return fileNames.map((fileName) => {
return {
params: {
id: fileName.replace(/\.md$/, ''),
},
};
});
}
// 投稿データを取得する
export function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
// gray-matter を使って、投稿したデータからメタデータを読み込む
const matterResult = matter(fileContents);
// 読み取ったデータとIDを繋げて返却
return {
id,
...matterResult.data,
};
}
「pages/posts」ディレクトリに「[id].js」ファイルを作成します。
import Layout from '../../components/layout';
import { getAllPostIds, getPostData } from '../../lib/posts';
// 投稿データのレイアウトを取得
export default function Post({ postData }) {
return (
<Layout>
{postData.title}
<br />
{postData.id}
<br />
{postData.date}
</Layout>
);
}
// 投稿データのID一覧を取得
export async function getStaticPaths() {
const paths = getAllPostIds();
return {
paths,
fallback: false,
};
}
// 投稿データを取得
export async function getStaticProps({ params }) {
const postData = getPostData(params.id);
return {
props: {
postData,
},
};
}
以前作成した「first-post.js」はもう使わないので、消します。
「index.js」にリンクを付け加えます。以下コードを追加してください。
import Link from 'next/link';
// id と date と title を渡して、リンクを生成する
<li className={utilStyles.listItem} key={id}>
<Link href={`/posts/${id}`}>
<a>{title}</a>
</Link>
<br />
<small className={utilStyles.lightText}>
{date}
</small>
</li>
動作確認
http://localhost:3000、http://localhost:3000/posts/ssg-ssrとhttp://localhost:3000/posts/pre-renderingにアクセスしてそれぞれ表示されることを確認します。



さらにCSSなど組み込んで、見栄えを良くしたい場合はNext.jsのドキュメントを参考に組み込んでみてください。
