目次
はじめに
今回は Next.js でダイナミックパスを使って動的ルーティングを行う際に、同階層にダイナミックパスを置いてはいけませんよ。というお話です。
ダイナミックパスで動的ルーティングを行うというのは、例えばこんなディレクトリ構造の場合です。
src/
app/
[slug]/page.tsx
[test]/page.tsx
みたいな構成はできませんよ。というイメージです。
動的ルーティングの仕組み
まず、Next.js での動的ルーティングについて簡単に解説していきます。
2023/03 現在 Next.js はバージョン 13 の大台にのり、動的ルーティングの方法も変わりました。
これまではgetStaticPaths
を使った方法でした。
// pages/posts/[slug].js
// Generates `/posts/1` and `/posts/2`
export async function getStaticPaths() {
return {
paths: [{ params: { slug: '1' } }, { params: { slug: '2' } }],
fallback: false, // can also be true or 'blocking'
}
}
// `getStaticPaths` requires using `getStaticProps`
export async function getStaticProps(context) {
return {
// Passed to the page component as props
props: { post: {} },
}
}
export default function Post({ post }) {
// Render post...
}
こうすることで、/before
というページが作成されます。
続いて、バージョン 13 の APP Router(beta 版) での方法です。
// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default function Page({ params }: { params: { slug: string } }) {
const { slug } = params
// ...
}
公式ドキュメントによると、この方法を使うと、要求時のオンデマンドではなく、ビルド時にルートを静的に生成できます。
とあるので、パフォーマンス面での期待もできますね!
解決方法
基本的な動的ルーティングの方法を押さえたところで、本題の「同階層にダイナミックパスを置いてはいけませんよ。」という話についてです。
はじめにでも書きましたが、こんなふうに同階層にダイナミックパスを置いてしまうと、このようなエラーが出てしまいます。
Error: You cannot use different slug names for the same dynamic path ('slug' !== 'test').
まあ、ただエラーの内容のまんまで「同階層にダイナミックパスは置けないよ!」というだけの話ではあるので、こんな感じに修正すれば問題ありません。
src/
app/
/post/[slug]/page.tsx
/[test]/page.tsx
といった感じで、ダイナミックパスの親階層に通常のディレクトリを挟むことで解決できます。というお話でした。
参考
さいごに
「そんなの知っとるわ!」というお話だったかもしれないですが、つまらないところで時間を無駄にしてしまってはもったいないので、同じようなエラーで詰まった方は参考にしてみてください。