Course
Dynamic Routes
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
Dynamic Routes
In real-world project development, routing scenarios can often become complex. For example, managing routes for numerous articles individually in a database is impractical. How can we address this challenge?
How do we structure our code to accommodate routes tailored for mobile and desktop users? Additionally, how can we conditionally render pages, such as displaying a login page for unauthorized users? Furthermore, how can a single route present different content based on varying conditions?
This article delves into these questions by highlighting the powerful routing features of the App Router.
Dynamic Routes
Sometimes, it's impossible to know the specific route addresses in advance. For instance, when displaying an article based on an ID parameter in the URL. With a large number of articles, creating individual routes for each one is impractical. This is where dynamic routing becomes crucial.
[folderName]
To implement dynamic routes, you should enclose the folder name in square brackets, such as [id] or [slug]. This route name is then passed as a params prop to the layout, page, route handlers, and the generateMetadata function.
For example, create a new folder named [slug] under app/blog, and add a page.js file in that folder with the following code:
// app/blog/[slug]/page.jsexport default function Page({ params }) { return <div>My Post: {params.slug}</div>}
The result will be as follows:
- Visiting
/blog/a
will set params to { slug: 'a' }. - Visiting
/blog/hello
will set params to { slug: 'hello' }. - …
Playground
[...folderName]
Adding an ellipsis inside the square brackets, like [...folderName], captures all subsequent route segments.
This means
app/shop/[...slug]/page.js
will match /shop/clothes
, as well as /shop/clothes/tops
, /shop/clothes/tops/t-shirts
, and so forth.
For example, the code for
app/shop/[...slug]/page.js
is:// app/shop/[...slug]/page.jsexport default function Page({ params }) { return <div>My Shop: {JSON.stringify(params)}</div>}
The result will be as follows:
- Visiting
/shop/a
will set params to { slug: ['a'] }. - Visiting
/shop/a/b
will set params to { slug: ['a', 'b'] }. - Visiting
/shop/a/b/c
will set params to { slug: ['a', 'b', 'c'] }. - ...
[[...folderName]]
Adding an ellipsis inside double square brackets, like [[...folderName]], optionally captures all subsequent route segments.
This means
app/shop/[[...slug]]/page.js
will match /shop
, as well as /shop/clothes
, /shop/clothes/tops
, /shop/clothes/tops/t-shirts
, and so on.The difference from the previous method is that routes without parameters will also be matched (such as
/shop
).
For example, the code for
app/shop/[[...slug]]/page.js
is:// app/shop/[[...slug]]/page.jsexport default function Page({ params }) { return <div>My Shop: {JSON.stringify(params)}</div>}
The result will be as follows:
- Visiting
/shop
will set params to { }. - Visiting
/shop/a
will set params to { slug: ['a'] }. - Visiting
/shop/a/b
will set params to { slug: ['a', 'b'] }. - Visiting
/shop/a/b/c
will set params to { slug: ['a', 'b', 'c'] }. - ...