GitHub|Since 2007
Step 11

Dynamic Post Pages ([slug])

Use Next.js dynamic routing to automatically generate individual pages for every WordPress blog post.

18 min

Dynamic Routing for Posts

A list of posts isn't useful if you can't read them. We'll use Next.js Dynamic Routes to generate a unique page for every WordPress post automatically.

1. The Directory Structure

Create a nested folder inside `app` using square brackets:

app/blog/[slug]/page.tsx

The `[slug]` syntax tells Next.js that this part of the URL is dynamic. For example, `/blog/my-first-post` will match this file.

2. Fetching the Single Post

In `app/blog/[slug]/page.tsx`, use the URL parameter to fetch the specific data:

import { getPostBySlug } from '@/lib/wordpress';
import { notFound } from 'next/navigation';

export default async function PostPage({ params }: { params: { slug: string } }) {
  const post = await getPostBySlug(params.slug);

  if (!post) notFound();

  return (
    <article className="container mx-auto py-12 px-4">
       <h1 className="text-5xl font-extrabold mb-8">{post.title.rendered}</h1>
       <div 
         className="prose lg:prose-xl"
         dangerouslySetInnerHTML={{ __html: post.content.rendered }} 
       />
    </article>
  );
}

3. Core Concepts

URL Params

Next.js passes a `params` object to your server component containing the dynamic segment. We pass `params.slug` directly to our API handler.

The `prose` class

Since WordPress returns raw HTML, standard Tailwind classes won't apply to the tags inside. We use the Tailwind Typography plugin (`prose`) to automatically style headings, paragraphs, and lists without manual targetting.

Comments and Discussion