動的ルーティング(2階層)
2023-03-18
以下のような場合に複数階層の動的ルーティングが発生する。
例)タグ別記事一覧ページのページ分け https://example.com/tags/[tag]/[page]
要点はgetStaticPaths() が何と返せばよいか?
タグの一覧を取得して、タグの一覧.map() でタグごとに該当する投稿を拾って、paginateでページ分けしたものを返す。
最終的に以下のような配列を返してくれればよい。
[
{ params: { tag: 'Astro', page: '1' }, props: { page: [Object] } },
{ params: { tag: 'blog', page: '1' }, props: { page: [Object] } },
{ params: { tag: 'blog', page: '2' }, props: { page: [Object] } },
{ params: { tag: 'knowledge', page: '1' }, props: { page: [Object] } },
]
なので以下のようになる。
---
import { getCollection } from 'astro:content';
import Layout from "../../../layouts/Layout.astro";
import Summary from "../../../components/Summary.astro";
export async function getStaticPaths({ paginate }) {
const allPosts = await getCollection('posts');
allPosts.sort((a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime())
const tags = [...new Set(allPosts.map((post) => post.data.tags).flat())];
return tags.map(tag => {
const posts = allPosts.filter((post) => post.data.tags.includes(tag))
return paginate(posts, { params:{ tag }, pageSize: 10 });
}).flat()
}
const { tag } = Astro.params;
const { page } = Astro.props;
---
<Layout title={tag}>
<h2>Posts tagged with {tag} <small class="fs-5">({page.currentPage}/{page.lastPage})</small></h2>
<div>
{page.data.map((post) => <Summary post={post} />)}
</div>
<div>
前のページリンク
次のページリンク
</div>
</Layout>