Next.js
I. Next.js Fundamentals
1. Introduction to Next.js
2. Next.js vs React
3. Project Setup
4. Folder Structure
5. Pages and Routing
6. Link and Navigation
7. Static Assets
8. CSS and Styling
II. Routing, Data & Rendering
9. Dynamic Routing
10. API Routes
11. Data Fetching Basics
12. getStaticProps
13. getServerSideProps
14. Incremental Static Regeneration
15. Rendering Strategies
16. Image Optimization
III. Advanced Next.js & Performance
17. Middleware
18. Authentication Basics
19. Authorization
20. Environment Variables
21. Performance Optimization
22. SEO with Next.js
23. Internationalization
24. Error Handling
IV. Projects, Deployment & Best Practices
25. Next.js Best Practices
26. Folder and Code Organization
27. Testing Next.js Apps
28. Security in Next.js
29. Next.js Interview Questions
30. Mini Project – Blog
31. Mini Project – Dashboard
32. Mini Project – Ecommerce
33. Mini Project – API Integration
34. Next.js Case Study
35. Real-World Use Cases
36. Project Planning
37. Final Project
38. Deployment with Vercel
39. Course Review
40. Career Roadmap
Lesson 9
Dynamic Routing
Build flexible page routes that adapt to user data — from article URLs to category filters
Dynamic routing transforms static websites into flexible applications. Think of it as the difference between a paper magazine with fixed pages and a digital platform that creates new pages on demand. Every time someone visits a unique URL, your application can generate the perfect page for that specific request. NewsWave needs dynamic routes everywhere. Article pages like/articles/breaking-ai-news and category filters like /category/tech cannot exist as static files. You would need thousands of individual page files. Dynamic routing solves this by creating one template that works for any article slug or category name.
Unlike React Router where you define routes in JavaScript, Next.js uses the file system itself as your routing configuration. Square brackets in file names tell Next.js "this part of the URL can change." The magic happens automatically — no route configuration files or complex setup required.
Route Parameters
Route parameters capture the dynamic parts of URLs. When a user visits/articles/covid-vaccine-update, the parameter covid-vaccine-update gets passed to your page component. Your code can then use this parameter to fetch the right article, display the correct content, or make database queries.
Parameters work like variables in a URL. Instead of hardcoding every possible value, you create a pattern that matches any value in that position. The file name determines the parameter name — a file called [slug].js creates a parameter called slug. A file called [id].js creates a parameter called id.
Real applications use this pattern constantly. GitHub uses github.com/[username]/[repository] for user profiles and repositories. Medium uses medium.com/@[author]/[article-slug] for article pages. The same principle applies to e-commerce sites, documentation, and any application with user-generated content.
📁 app
📁 articles
📄 [slug]
📄 page.js ← matches /articles/any-article-title
📁 category
📄 [name]
📄 page.js ← matches /category/tech or /category/sports
📁 search
📄 page.js ← static route /search
📁 articles
📄 [slug]
📄 page.js ← matches /articles/any-article-title
📁 category
📄 [name]
📄 page.js ← matches /category/tech or /category/sports
📁 search
📄 page.js ← static route /search
Creating Your First Dynamic Route
Start with the NewsWave article page. Every news article needs its own URL based on the article title or slug. Create the folder structure first, then build the page component that receives the dynamic parameter.# Create the articles folder with dynamic route
mkdir app/articles
mkdir app/articles/[slug]
touch app/articles/[slug]/page.jsTerminal
$ mkdir -p app/articles/[slug] && touch app/articles/[slug]/page.js
Created dynamic route structure
✓ Ready for article pages
params prop contains the dynamic route parameters automatically passed by Next.js.
// app/articles/[slug]/page.js
// Dynamic article page that shows different content based on URL slug
export default function ArticlePage({ params }) {
// params.slug contains the URL parameter (everything after /articles/)
const articleSlug = params.slug;
return (
<div style={{ maxWidth: '800px', margin: '0 auto', padding: '40px 20px' }}>
<h1 style={{ color: '#0f172a', fontSize: '32px', marginBottom: '16px' }}>
Article: {articleSlug.replace(/-/g, ' ')}
</h1>
<p style={{ color: '#6b7280', marginBottom: '24px' }}>
URL parameter captured: {articleSlug}
</p>
</div>
);
}localhost:3000/articles/breaking-tech-news — NewsWave
What just happened?
Next.js extracted "breaking-tech-news" from the URL and passed it as params.slug to your component. The square brackets in the folder name told Next.js this part of the route is dynamic. Try this: visit different URLs like /articles/covid-update or /articles/sports-news to see the parameter change.
Real Article Data Integration
Static text demonstrations help understand the concept, but real applications need actual data. NewsWave articles should display authentic content based on the URL parameter. Create a mock database of articles that your dynamic route can query and display.// Mock article database (normally this would be a real database)
const articles = {
'breaking-ai-news': {
title: 'Breaking: AI Breakthrough Changes Everything',
author: 'Sarah Chen',
date: '2024-01-15',
category: 'Tech',
views: 2847,
content: 'Revolutionary AI system demonstrates unprecedented capabilities...'
},
'climate-summit-2024': {
title: 'Global Climate Summit Reaches Historic Agreement',
author: 'Michael Rodriguez',
date: '2024-01-14',
category: 'World',
views: 1923,
content: 'World leaders unite on ambitious climate action plan...'
}
};// Updated article page with real data lookup
export default function ArticlePage({ params }) {
const article = articles[params.slug]; // Look up article by slug
// Handle case where article doesn't exist
if (!article) {
return (
<div style={{ textAlign: 'center', padding: '80px 20px' }}>
<h1 style={{ color: '#dc2626' }}>Article Not Found</h1>
<p style={{ color: '#6b7280' }}>No article exists with slug: {params.slug}</p>
</div>
);
}
return (
<article style={{ maxWidth: '800px', margin: '0 auto', padding: '40px 20px' }}>
<h1 style={{ fontSize: '36px', color: '#0f172a', marginBottom: '20px' }}>
{article.title}
</h1>
</article>
);
}localhost:3000/articles/breaking-ai-news — NewsWave
What just happened?
Your component now looks up real article data using the URL slug as a key. The conditional rendering handles missing articles gracefully. Try this: create more articles in your mock database and visit their URLs to see different content.
Category Pages
Category filtering represents another common dynamic routing pattern. Instead of creating separate pages for tech news, sports news, and business news, one dynamic route handles all categories. The category name in the URL determines which articles to display. Category pages differ from article pages because they show multiple items instead of a single piece of content. The dynamic parameter filters a collection rather than selecting a specific item. This pattern appears everywhere — shopping sites filter products by category, job boards filter listings by industry, and social media apps filter posts by topic. NewsWave needs category pages that feel fast and responsive. Users clicking "Tech" should immediately see technology articles without waiting for slow database queries. The category parameter lets you pre-filter content and create focused experiences for different types of readers.# Create category dynamic route structure
mkdir app/category
mkdir app/category/[name]
touch app/category/[name]/page.jsTerminal
$ mkdir -p app/category/[name] && touch app/category/[name]/page.js
Category route structure created
✓ Ready for dynamic category filtering
// Mock articles database expanded with categories
const allArticles = [
{ slug: 'breaking-ai-news', title: 'AI Breakthrough Changes Everything', category: 'tech', views: 2847 },
{ slug: 'climate-summit-2024', title: 'Climate Summit Reaches Agreement', category: 'world', views: 1923 },
{ slug: 'quantum-computing-advance', title: 'Quantum Computing Milestone Achieved', category: 'tech', views: 1456 },
{ slug: 'olympic-records-broken', title: 'Multiple Olympic Records Fall', category: 'sports', views: 3421 },
{ slug: 'market-volatility-continues', title: 'Stock Market Sees Major Swings', category: 'business', views: 2156 }
];// app/category/[name]/page.js
// Dynamic category page that filters articles by category name
export default function CategoryPage({ params }) {
const categoryName = params.name; // Get category from URL parameter
// Filter articles that match the category parameter
const categoryArticles = allArticles.filter(
article => article.category.toLowerCase() === categoryName.toLowerCase()
);
return (
<div style={{ maxWidth: '1000px', margin: '0 auto', padding: '40px 20px' }}>
<h1 style={{ fontSize: '32px', color: '#0f172a', marginBottom: '8px' }}>
{categoryName.charAt(0).toUpperCase() + categoryName.slice(1)} News
</h1>
<p style={{ color: '#6b7280', marginBottom: '32px' }}>
{categoryArticles.length} articles found
</p>
</div>
);
}localhost:3000/category/tech — NewsWave
Multiple Route Parameters
Advanced applications often need multiple dynamic segments in a single URL. Consider a news site with URLs like/category/tech/2024/january for monthly archives, or an e-commerce site with /products/electronics/smartphones/brand/apple for nested product filtering.
Multiple parameters create powerful URL structures that feel intuitive to users and search engines. Each segment adds another layer of organization and filtering capability. The challenge lies in managing the complexity — more parameters mean more edge cases and validation requirements.
NewsWave could benefit from date-based routing for archived content. Users browsing older articles might prefer URLs like /archive/2023/december rather than endless pagination. This pattern also helps with SEO since search engines can better understand content organization.
# Create nested dynamic route with multiple parameters
mkdir -p app/archive/[year]/[month]
touch app/archive/[year]/[month]/page.jsTerminal
$ mkdir -p app/archive/[year]/[month] && touch app/archive/[year]/[month]/page.js
Nested dynamic route created
✓ Multiple parameters ready
// app/archive/[year]/[month]/page.js
// Archive page with year and month parameters
export default function ArchivePage({ params }) {
const { year, month } = params; // Destructure both parameters
// Mock function to get articles for specific year/month
const getArchiveArticles = (year, month) => {
// In real app, this would query database with date filters
return allArticles.filter(article => {
// Simulate date filtering logic
return Math.random() > 0.3; // Mock: randomly show some articles
});
};
const archiveArticles = getArchiveArticles(year, month);
return (
<div style={{ maxWidth: '1000px', margin: '0 auto', padding: '40px 20px' }}>
<h1 style={{ fontSize: '32px', color: '#0f172a', marginBottom: '16px' }}>
NewsWave Archive: {month.charAt(0).toUpperCase() + month.slice(1)} {year}
</h1>
</div>
);
}localhost:3000/archive/2023/december — NewsWave
What just happened?
Next.js passed both URL segments as separate parameters in the params object. The nested folder structure [year]/[month] created a two-level dynamic route that matches URLs like /archive/2023/december. Try this: visit different year/month combinations to see both parameters change.
Catch-All Routes
Some applications need routes that match any number of URL segments. Documentation sites often use paths like/docs/api/routes/dynamic or /docs/getting-started/installation/setup where the depth varies. Catch-all routes solve this with a special syntax that captures everything after a certain point.
The triple-dot syntax [...slug] tells Next.js to match one or more segments and pass them as an array. A file named [...slug].js matches /docs/api, /docs/api/routes, and /docs/api/routes/dynamic/advanced. The parameter becomes an array like ['api', 'routes', 'dynamic', 'advanced'].
This pattern works perfectly for content management systems, documentation platforms, and any application with hierarchical content. NewsWave could use catch-all routes for topic hierarchies like /topics/technology/artificial-intelligence/machine-learning where users can browse increasingly specific content areas.
# Create catch-all route for topics
mkdir -p app/topics/[...path]
touch app/topics/[...path]/page.jsTerminal
$ mkdir -p app/topics/[...path] && touch app/topics/[...path]/page.js
Catch-all route structure created
✓ Variable depth routing ready
// app/topics/[...path]/page.js
// Catch-all route that handles any number of path segments
export default function TopicsPage({ params }) {
const pathSegments = params.path; // Array of all URL segments after /topics/
// Create breadcrumb navigation from path segments
const breadcrumbs = pathSegments.map(segment =>
segment.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase())
);
return (
<div style={{ maxWidth: '1000px', margin: '0 auto', padding: '40px 20px' }}>
<nav style={{ marginBottom: '24px' }}>
<span style={{ color: '#6b7280' }}>Topics > </span>
{breadcrumbs.map((crumb, index) => (
<span key={index} style={{ color: index === breadcrumbs.length - 1 ? '#0369a1' : '#6b7280' }}>
{crumb}
{index < breadcrumbs.length - 1 && <span style={{ color: '#6b7280' }}> > </span>}
</span>
))}
</nav>
</div>
);
}localhost:3000/topics/technology/artificial-intelligence/machine-learning — NewsWave
Route Priority and Conflicts
Multiple route patterns can match the same URL, creating conflicts that Next.js must resolve. Understanding route priority prevents unexpected behavior and helps you structure applications correctly. The file system routing follows specific rules to determine which route wins when multiple patterns match the same path. Static routes always beat dynamic routes. A file calledapp/articles/featured/page.js takes priority over app/articles/[slug]/page.js when someone visits /articles/featured. Dynamic routes beat catch-all routes. Single parameter routes like [id] beat catch-all routes like [...path].
Route conflicts become critical in large applications. NewsWave needs special pages like /articles/submit for article submission and /articles/trending for popular content. Without understanding priority, these might conflict with the dynamic /articles/[slug] route.
Route Priority Rules
1. Static routes beat dynamic routes
2. Dynamic routes beat catch-all routes
3. Named catch-all [...slug] beats optional [[...slug]]
4. More specific routes beat less specific ones
// Example of route priority in NewsWave
// File structure that handles conflicts correctly:
// app/articles/trending/page.js ← Static route (highest priority)
// app/articles/submit/page.js ← Static route (highest priority)
// app/articles/[slug]/page.js ← Dynamic route (medium priority)
// app/articles/[...path]/page.js ← Catch-all route (lowest priority)
// URL /articles/trending → goes to trending/page.js (static wins)
// URL /articles/breaking-news → goes to [slug]/page.js (dynamic matches)
// URL /articles/tech/ai/deep → goes to [...path]/page.js (catch-all matches)What just happened?
Next.js evaluates routes from most specific to least specific. Static paths like "trending" always match first, then single dynamic parameters, then catch-all routes. This prevents dynamic routes from accidentally capturing URLs meant for specific pages. Plan your route structure to avoid conflicts.
Quiz
1. NewsWave has a file at app/articles/[slug]/page.js. When a user visits /articles/breaking-tech-news, what happens?
2. You want NewsWave to handle URLs like /category/tech, /category/sports, and /category/business with one component. What file structure do you create?
3. NewsWave has both app/articles/featured/page.js and app/articles/[slug]/page.js. What happens when someone visits /articles/featured?
Up Next: API Routes
Transform NewsWave into a full-stack application by building custom API endpoints that handle data, authentication, and server-side logic.