Tailwind Logo

Using Nextjs' App Route's Dynamic Routes to create blog pages (Part 1)

Content Hub ONENext.js

Published: 2024-08-21

We would like to prepare a page for each of the blog posts. In the first part, we will create URLs by using IDs.

Verify Content ID

Using code that is already working, switch the display on the page as follows

TypeScript
      <h1>Content Hub ONE - Title list</h1>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            {post.id} - {post.title}
          </li>
        ))}
      </ul>

As a result, the following HTML is obtained.

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>

The ID you are getting here is the ID assigned to the Content Hub ONE content. This will be used as the URL in this blog post.

Create Dynamic Routes and check operation

When using the Dynamic Routes used in the App Router, instead of writing the [slug].tsx used in the Page Router, create a directory in the form app/blog/[slug]/page.tsx as a path and set the key at this The key is set at this slug. Let's run a simple sample first.

TypeScript
export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>;
}

After creating this file, accessing http://localhost/blog/hello shows the following results.

nextappdynamicroute01.png

Page Router First of all, you can see that the path description method is different between Page Router and App Router.

Retrieve blog posts

Since it is possible to obtain an ID to retrieve blog posts, we will create a Query that uses this ID to retrieve data.

GraphQL
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
            }
        }
    }
}

As for the URL, rewrite it so that it is given on the top page.

TypeScript
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>
  );
}

As a result, from the top page, you can use the Blog's ID to create a URL for each blog, and on the Blog's page, you can use the ID to retrieve the corresponding article. To retrieve the articles for this blog, the following query is added to src\interfaces\Blog\index.ts

TypeScript
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
            }
        }
    }
}
  `
}

We will use fetchGraphQL, which we have already created, to retrieve data using Slug's ID. For this, please add the following function to src\utils\getBlog\index.ts

TypeScript
export async function getBlogFromID(id: string) {
    const post: BlogResponse = (await fetchGraphQL(
        BlogFromIDQuery(id)
    )) as BlogResponse;

    return post.data.blog;
}

This function returns a blog post using the id specified in the slug.

Now go back to the file app/blog/[slug]/page.tsx and rewrite the inside of Page as follows

TypeScript
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>;
}

Here we suddenly call notFound();. This is already prepared in next/navigation, so we have already added it in import.

The ID will now be used to display the title of the blog.

nextappdynamicroute03.png

Summary

For individual blog pages, we were able to set up and display URLs using IDs. However, this is not a good SEO situation since there are no keywords in the URL. In the next issue, I would like to make this URL part a little more user-friendly.

Related article

  • Using Nextjs' App Route's Dynamic Routes to create blog pages (Part 1)
  • Using Nextjs' App Route's Dynamic Routes to create blog pages (Part 2)
  • Using Nextjs' App Route's Dynamic Routes to create blog pages (Part 3)

Tags