前回、ブログの個別のページに関して、Dynamic Route で ID を利用して作成する手順を紹介しました。今回はもう1つ改善して、URL のパスに日付と Slug を利用して処理できるように進めていきます。
Slug と日付を確認
前回、タイトルだけを表示していたブログの記事で、PublishDate と Slug を取得できているかを app/blog/[slug]/page.tsx のファイルを書き換えて確認します。
return (
<>
<div>Title: {post.title}</div>
<div>Publish Date: {post.publishDate}</div>
<div>Slug: {post.slug}</div>
</>
);
実際に publishDate および slug が表示されます。
ページで必要なデータの取得ができているのを確認しました。
ID から Slug に切り替える
URL として利用していた値を ID から Slug の値に変更をします。まず、Slug を利用してブログの記事を表示するために、 Slug の値が同じブログの記事を取得するクエリを作成します。今回はサンプルの記事を利用して以下のように作成しました。
query AllBlog {
allBlog(where: { slug_eq: "introducing-sitecore-composable-dxp-products" }) {
total
results {
description
id
name
publishDate
slug
title
body
image {
total
results {
description
fileHeight
fileId
fileName
fileSize
fileType
fileUrl
fileWidth
id
name
}
}
}
}
}
Postman で以下のようにデータの取得が出来ていることがわかります。
呼び出しをするための定義を src/interfaces/Blog/index.ts に追加します。
export const BlogFromSlugQuery = (slug: string) => {
return `
query AllBlog {
allBlog(where: { slug_eq: "${slug}" }) {
total
results {
description
id
name
publishDate
slug
title
body
image {
total
results {
description
fileHeight
fileId
fileName
fileSize
fileType
fileUrl
fileWidth
id
name
}
}
}
}
}
`
}
上記では slug の値を渡して呼び出しをするようにしました。このクエリは全てのブログの記事から Slug の値が同じものを取得する形です。このため Slug にはユニークな値を設定するようにします。続いて記事を取得する関数を定義している、src/utils/getBlog/index.ts に、以下のコードを追加します。
export async function getBlogFromSlug(slug: string): Promise<Partial<Blog>> {
const results: AllBlogResponse = (await fetchGraphQL(
BlogFromSlugQuery(slug)
)) as AllBlogResponse;
return results.data.allBlog.results[0];
}
これで Slug を利用して該当する記事を取得することが可能となります。なお Slug が重複して登録されている場合でも1つめの結果を取得する形としています。
では実際に slug を URL で利用するために、 app/blog/[slug]/page.tsx のファイルで、ページで取得するコードを以下のように変更します。
const post = await getBlogFromSlug(params.slug);
これで Slug の値を利用してページを表示します。テストをしやすいように、トップページのapp/page.tsx のファイルの出力部分も以下のように変更します。
<main>
<h1>Content Hub ONE - Title list</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
</main>
実行をすると、以下のように slug を利用してブログのページが表示されていることがわかります。
日付を URL に設定する
最後に、 Slug だけでなく、URL を YYYY/MM/DD/Slug という形で URL を設定できるように Dynamic Routes を設定したいと思います。複数のパスを利用できるようにするためには、 Catch-all Segments を利用することになるため、パスを [...slug] に変更をします。
変更後のファイル src/app/blog/[...slug]/page.tsx において、4 つ目の値が slug という扱いになるため、params.slug[3] で slug を取得するように以下のように書き換えます。
export default async function Page({ params }: { params: { slug: string } }) {
const post = await getBlogFromSlug(params.slug[3]);
これで日付などを指定したあと、URL に日付を入れることが可能となりました。
まとめ
今回は Slug として利用するフィールドを追加して URL に関して制御できるようにする手順を紹介しました。しかしながら、日付に関してのところは指定できるようにしただけで、今のところ何も指定していません。これは次回実装していきます。サンプルとして表示しているコンテンツは title だけですが、データとしては取得できているので、あとはブログのページを作ったりしていく形です。
関連ページ
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(前編)
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(中編)
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(後編)