PART 8: DYNAMIC ROUTES
What Are Dynamic Routes?
Dynamic routes are pages that show different content based on parameters in the URL.
Examples:
/blog/first-postshows the first post/blog/second-postshows the second post/user/123shows user 123’s profile/product/456shows product 456
You can’t create a file for every possible route. That would be impossible! Instead, you use dynamic routes.
Creating Dynamic Routes
To create a dynamic route, use square brackets [] in the folder name
app/
├── page.js
└── blog/
├── page.js (shows /blog)
└── [id]/
└── page.js (shows /blog/123, /blog/456, etc.)
Create app/blog/[id]/page.js:
javascript
export default function BlogPost({ params }) {
const { id } = params;
return (
<main>
<h1>Blog Post {id}</h1>
<p>This is post number {id}</p>
</main>
);
}
Now:
/blog/1shows “Blog Post 1”/blog/helloshows “Blog Post hello”/blog/anythingshows “Blog Post anything”
The params object contains the dynamic parts of the URL.
Real Dynamic Content
The above example just shows the ID. In real apps, you fetch data
export default function BlogPost({ params }) {
const { id } = params;
// In real apps, you'd fetch from a database
const posts = {
'1': { title: 'Learning React', content: 'React is amazing...' },
'2': { title: 'Next.js Guide', content: 'Next.js is great...' },
};
const post = posts[id];
if (!post) {
return <h1>Post not found</h1>;
}
return (
<main>
<h1>{post.title}</h1>
<p>{post.content}</p>
</main>
);
}
Now:
/blog/1shows the first post/blog/2shows the second post/blog/99shows “Post not found”
Multiple Dynamic Segments
You can have multiple dynamic parts:
app/
└── store/
└── [category]/
└── [productId]/
└── page.js
This matches: /store/electronics/123
Access them:
export default function Product({ params }) {
const { category, productId } = params;
return (
<main>
<h1>Category: {category}</h1>
<p>Product: {productId}</p>
</main>
);
}
URLs that work:
/store/electronics/123/store/clothing/456/store/books/789
Real-World Example: Amazon Product Page
Amazon has URLs like: /product/B08H8RHKWS
In Next.js:
app/
└── product/
└── [productId]/
└── page.js
The component:
export default function ProductPage({ params }) {
const { productId } = params;
// Fetch product from database
const product = getProductFromDatabase(productId);
return (
<main>
<h1>{product.name}</h1>
<p>${product.price}</p>
<button>Add to Cart</button>
</main>
);
}
Catch-All Routes
What if you want to match multiple segments? Use [...slug]:
app/
└── docs/
└── [...slug]/
└── page.js
This matches:
/docs/docs/getting-started/docs/guide/installation/docs/a/b/c/d
Access the segments:
export default function Docs({ params }) {
const { slug } = params; // array of segments
return (
<main>
<h1>Docs Page</h1>
<p>Path: {slug?.join('/')}</p>
</main>
);
}
If you visit /docs/getting-started/installation, slug is ['getting-started', 'installation']
Common Beginner Mistake #6: Forgetting params
New developers do:
// ❌ Wrong
export default function BlogPost() {
return <h1>Post</h1>;
}
// ✅ Correct
export default function BlogPost({ params }) {
const { id } = params;
return <h1>Post {id}</h1>;
}
The component must accept params to access the dynamic parts!
Generating Static Params (For Performance)
For very popular blog posts, you can pre-generate them at build time
export async function generateStaticParams() {
return [
{ id: '1' },
{ id: '2' },
{ id: '3' },
];
}
export default function BlogPost({ params }) {
const { id } = params;
return <h1>Post {id}</h1>;
}
This creates the pages at build time instead of when the user visits.
Exercise 5: Create Dynamic Routes
Create a blog with:
/blog– shows list of all posts/blog/1– shows post 1/blog/2– shows post 2/blog/3– shows post 3
Make each post have a title and content. Use dynamic routes!