Dynamic Routing and Catch-All Routes in Next.js


Dynamic routing in Next.js allows you to create flexible routes that adapt to user input. This feature is particularly useful for building dynamic applications like blogs, e-commerce sites, and user-specific dashboards. Additionally, Next.js provides robust support for handling non-existent routes through custom 404 pages and catch-all routes.
What is Dynamic Routing?
Dynamic routing enables you to define routes where part of the URL can change dynamically. For example:
/product/[id]
can match URLs like/product/1
,/product/2
or/product/special-item
.
Difference Between next/navigation
and next/router
Both next/navigation
and next/router
offer routing utilities, but they cater to different environments within Next.js.
next/navigation
Scope: Specifically designed for the App Router (introduced in Next.js 13).
Features:
useParams
: Access dynamic route parameters.useSearchParams
: Access query parameters.useRouter
: Provides navigation methods likepush
,replace
, andback
.notFound
: Programmatically trigger 404 pages.redirect
: Redirect users to a specific URL.
Recommended Use: When using the App Router for building routes in the
src/app
directory.
next/router
Scope: Designed for the Pages Router (traditional routing system in Next.js).
Features:
useRouter
: Access the router object for navigation and dynamic route handling.query
: Access route parameters and query strings.prefetch
: Prefetch pages for better performance.
Recommended Use: When building applications in the
src/pages
directory.
Creating Dynamic Routes
Step 1: Define a Dynamic Route File
To create a dynamic route, use square brackets ([ ]
) in your file or folder name within the pages
or app
directory. For example:
src/app/products/[id]/page.tsx
Step 2: Access the Dynamic Parameter
Inside your dynamic route, you can access the parameter using params
(in the App Router) or query
(in the Pages Router).
App Router Example:
interface ProductPageProps {
params: { id: string };
}
export default function ProductPage({ params }: ProductPageProps) {
return <h1>Product ID: {params.id}</h1>;
}
Pages Router Example:
import { useRouter } from 'next/router';
export default function ProductPage() {
const router = useRouter();
const { id } = router.query;
return <h1>Product ID: {id}</h1>;
}
Inside your dynamic route, you can access the parameter using the params
object provided by Next.js.
Example Using App Router:
import { notFound } from 'next/navigation';
interface ProductPageProps {
params: { id: string };
}
export default function ProductPage({ params }: ProductPageProps) {
if (!params.id) {
notFound();
}
return <h1>Product ID: {params.id}</h1>;
}
Alternatively, use the useParams
hook from next/navigation
:
import { useParams } from 'next/navigation';
export default function ProductPage() {
const params = useParams();
if (!params.id) {
return <h1>404 - Product Not Found</h1>;
}
return <h1>Product ID: {params.id}</h1>;
}
Catch-All Routes
Catch-all routes match multiple URL segments and are defined using [...param]
in the file or folder name.
Example:
src/app/docs/[...slug]/page.tsx
Handling Catch-All Parameters:
interface DocsPageProps {
params: { slug: string[] };
}
export default function DocsPage({ params }: DocsPageProps) {
const slugPath = params.slug.join('/');
return <h1>Viewing: {slugPath}</h1>;
}
This route will match paths like:
/docs
/docs/getting-started
/docs/tutorials/advanced
Optional Catch-All Routes
You can make a catch-all route optional by adding a question mark (?
) in the file name:
This matches both /docs
and any nested paths under /docs
.
By adding a question mark (?
) after the ...slug
part, you can make the catch-all segment optional, meaning the route will match even if there's no additional path segment after the base URL.
pages/docs/[...slug]?
This route will match:
- /docs
- /docs/post-title
- /docs/category/article-name
Usage:
This is particularly useful for creating fallback pages or handling situations where a user might access a URL with or without additional parameters.
Handling 404 Errors
Next.js allows you to create a custom 404 page for non-existent routes.
Step 1: Create a 404
Page
In the App Router:
src/app/not-found.tsx
In the Pages Router:
src/pages/404.tsx
Step 2: Define the Custom 404 Page
export default function NotFound() {
return <h1>404 - Page Not Found</h1>;
}
With the App Router, you can also use the notFound()
function to programmatically trigger a 404:
import { notFound } from 'next/navigation';
export default function ProductPage({ params }: { params: { id: string } }) {
if (!params.id) {
notFound();
}
return <h1>Product ID: {params.id}</h1>;
}
Practical Use Cases
Blogs:
/blog/[slug]
for articles with unique slugs.
E-Commerce:
/products/[id]
for individual product pages.
Documentation:
/docs/[...slug]
for structured documentation paths.
Custom 404 Pages:
- Enhance user experience with branded 404 pages.
Conclusion
Dynamic and catch-all routes in Next.js provide a flexible and powerful way to build dynamic applications. By understanding how to create and use these routes effectively, you can handle a wide variety of use cases, from user-specific pages to structured documentation paths. Start exploring dynamic routing today to unlock the full potential of your Next.js applications!
Subscribe to my newsletter
Read articles from Strnge directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Strnge
Strnge
Full-stack developer with a passion for building scalable web applications using Next.js, TypeScript, and modern technologies. Experienced in ServiceNow development and scripting. Sharing knowledge and insights on web development and programming.