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.tsxThe `[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.