テンプレートはnetlify-templates/nextjs-blog-theme
フォルダの名称を変更
pages/posts/[slug].js
↓
pages/posts/[[...slug]].js
すると
pages/posts/[[...slug]].jsのgetStaticPropsやgetStaticPathsがエラーになるから返り値などを変更
export const getStaticProps = async ({ params }) => {
const globalData = getGlobalData();
// const { mdxSource, data } = await getPostBySlug(params.slug);
// const prevPost = getPreviousPostBySlug(params.slug);
// const nextPost = getNextPostBySlug(params.slug);
↓
配列から文字列に直して引数に入れる
const slug = params.slug.join('/');
const { mdxSource, data } = await getPostBySlug(slug);
const prevPost = getPreviousPostBySlug(slug);
const nextPost = getNextPostBySlug(slug);
return {
props: {
globalData,
source: mdxSource,
frontMatter: data,
prevPost,
nextPost,
},
};
};
export const getStaticPaths = async () => {
const paths = postFilePaths
.map((path) => path.replace(/\.mdx?$/, ''))
.map((slug) => {
// return { params: { slug } }
↓
return { params: { slug: [slug] } }
});
return {
paths,
// fallback: false,
↓
fallback: true,
};
};
utils/mdx-utils.js
/* 追加 */
const readSubDirSync = (folderPath) => {
let result = [];
const readTopDirSync = ((folderPath) => {
let items = fs.readdirSync(folderPath)
items = items.map((itemName) => (path.join(folderPath, itemName)))
items.forEach((itemPath) => {
const relativePath = itemPath.match(/.+\/posts\/(.+)/)
result.push(relativePath[1])
//再帰処理
if (fs.statSync(itemPath).isDirectory()) readTopDirSync(itemPath)
})
})
readTopDirSync(folderPath)
// mdxだけ抽出
const onlyMdx = result.filter((path) => /\.mdx?$/.test(path))
return onlyMdx
}
/* 変更 */
// export const postFilePaths = fs
// .readdirSync(POSTS_PATH)
// // Only include md(x) files
// .filter((path) => /\.mdx?$/.test(path));
↓
// 深い海藻のファイルも取り出せる
export const postFilePaths = readSubDirSync(POSTS_PATH).filter((path) => /\.mdx?$/.test(path));
pages/index.jsのLinkコンポーネントを修正
<Link
as={`/posts/${post.filePath.replace(/\.mdx?$/, '')}`}
// href={`/posts/[slug]`}
↓
href={`/posts/[[...slug]]`}
>
ビルドしたらエラーが出てしまった
Error occurred prerendering page "/posts/[[...slug]]".
pages/posts/[[...slug]].jsを修正
export default function PostPage({
source,
frontMatter,
prevPost,
nextPost,
globalData,
}) {
↓ 追加
if (!frontMatter) return ''
return (
<Layout>
<SEO
title={`${frontMatter.title} - ${globalData.name}`}
description={frontMatter.description}
/>
...
これでビルドも上手く行った
参考