ブログの記事に関してそれぞれのページを用意したいと思います。前編では ID を利用して URL を作成する形で作っていきます。
ID を確認する
すでに動作しているコードを利用して、以下のようにページでの表示を切り替えます。
<h1>Content Hub ONE - Title list</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
{post.id} - {post.title}
</li>
))}
</ul>
結果として、以下のような HTML を取得できています。
<main>
<h1>Content Hub ONE - Title list</h1>
<ul>
<li>bthW8EnPU0-tdSeXOdMdSQ<!-- --> - <!-- -->Introducing Sitecore Composable DXP Products</li>
<li>jPUxNefHAkW31dYrXPwuUg<!-- --> - <!-- -->Welcome to Our Blog</li>
</ul>
</main>
ここで取得できている ID は Content Hub ONE のコンテンツに付与されている ID になります。今回のブログ記事では、これを URL として利用します。
Dynamic Routes を作成して動作確認
App Router で利用している Dynamic Routes を利用する際には、Page Router の時に利用した [slug].tsx のように記述するのではなく、パスとして app/blog/[slug]/page.tsx という形でディレクトリを作成して、この slug のところでキーを設定する形になります。シンプルにサンプルをまず動かします。
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>;
}
このファイルを作成した後、http://localhost/blog/hello とアクセスすると、以下のような結果が表示されています。
Page Router まずと App Router ではまずパスの記述方法が変わっていることがわかります。
ブログの記事を取得する
ブログの記事を取得するための ID の取得ができるようになっているため、この ID を利用しする Query を作成して、データを取得していきます
query Blog {
blog(id: "bthW8EnPU0-tdSeXOdMdSQ") {
body
description
id
locale
name
publishDate
slug
title
image {
total
results {
description
fileHeight
fileId
fileName
fileSize
fileType
fileUrl
fileWidth
id
name
}
}
}
}
URL に関してはトップページで渡すように書き換えます。
import { getAllBlog } from "@/utils/getBlog";
import Link from "next/link";
export default async function Home() {
const posts = await getAllBlog();
return (
<main>
<h1>Content Hub ONE - Title list</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.id}`}>{post.title}</Link>
</li>
))}
</ul>
</main>
);
}
結果として、トップページから Blog の ID を利用して各ブログの URL を作成して、Blog のページでは ID を利用して該当する記事を取得することが出来ます。このブログの記事を取得するために、以下のクエリを src\interfaces\Blog\index.ts に追加します。
export const BlogFromIdQuery = (id: string) => {
return `
query Blog {
blog(id: "${id}") {
body
description
id
locale
name
publishDate
slug
title
image {
total
results {
description
fileHeight
fileId
fileName
fileSize
fileType
fileUrl
fileWidth
id
name
}
}
}
}
`
}
この Query をすでに作成している fetchGraphQL を利用して Slug の ID を利用してデータを取得するようにします。これに関しては、 src\utils\getBlog\index.ts に以下の関数を追加してください。
export async function getBlogFromID(id: string) {
const post: BlogResponse = (await fetchGraphQL(
BlogFromIDQuery(id)
)) as BlogResponse;
return post.data.blog;
}
この関数は slug に指定された id を利用してブログの記事を返す形となります。
では app/blog/[slug]/page.tsx のファイルに戻って、Page の中を以下のように書き換えます。
import { getBlogFromID } from "@/utils/getBlog";
import { notFound } from "next/navigation";
export default async function Page({ params }: { params: { slug: string } }) {
const post = await getBlogFromID(params.slug);
if (!post) {
return notFound();
}
return <div>{post.title}</div>;
}
ここで突然 notFound(); を呼び出しています。これは next/navigation で準備されていますので、import ですでに追加してあります。
これで ID を利用してブログのタイトルが表示されるようになります。
まとめ
ブログの個別のページに関して、ID を利用して URL を設定して表示することができました。ただ、これでは URL にキーワードも入っていないため SEO としてはいまいちの状況です。次回はこの URL の部分をもう少し使い勝手の良い形にしたいと思います。
関連ページ
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(前編)
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(中編)
- Nextjs の App Route の Dynamic Routes を利用してブログのページを作る(後編)