Dynamic Routes in Menu - Article
Learn how to add links for dynamic routes in the menu.
To create dynamic routes, refer to the official Next.js documentation.
Issues we faced previously
If you had two dynamic routes with the same parameter/slug name, you might be redirected to the wrong page.
How to fix the issue?
We introduced exactMatch and activeUrl props in the MenuItem component to address this issue.
Understanding the issue with an example
Consider the routes /products/[id] and /blogs/[id] in your menu. If the active route is /products/46 and you click on the blogs' link, you will be redirected to /blogs/46. If there's no blog with id 46, you'll see a 404 page.
Previously, you might have used the following code for the static menu:
import { useParams } from 'next/navigation'
const MenuComponent = (/* props */) => {
const { id } = useParams()
return (
/* ... */
<MenuItem href={`/products/${id}`}>Products</MenuItem>
<MenuItem href={`/blogs/${id}`}>Blogs</MenuItem>
/* ... */
)
}
For the dynamic menu, you might have used:
const menuDataFile = (params, /* other parameters */) => [
/* ... */
{
label: 'Products',
href: `/products/${params.id}`,
},
{
label: 'Blogs',
href: `/blogs/${params.id}`,
},
/* ... */
]
Understanding the solution
exactMatch and activeUrl Props
By default, exactMatch is set to true. In this case, you don't need to pass the activeUrl prop in the MenuItem component. The MenuItem component will be active if the current URL exactly matches the href prop. Clicking the link redirects to the URL in the href prop.
If exactMatch is set to false, you must pass the activeUrl prop in the MenuItem component. The MenuItem component will will be active if the current URL contains the activeUrl prop. Clicking the link redirects to the URL in the href prop.
Using the props
Here's how to use the exactMatch and activeUrl props in the MenuItem component in the static menu:
const MenuComponent = (/* props */) => {
return (
/* ... */
<MenuItem href='/products/1' exactMatch={false} activeUrl='/products'>
Products
</MenuItem>
<MenuItem href='/blogs/1' exactMatch={false} activeUrl='/blogs'>
Blogs
</MenuItem>
/* ... */
)
}
And in the dynamic menu:
const menuDataFile = (/* other parameters */) => [
/* ... */
{
label: 'Products',
href: '/products/1',
exactMatch: false,
activeUrl: '/products',
},
{
label: 'Blogs',
href: '/blogs/1',
exactMatch: false,
activeUrl: '/blogs',
},
/* ... */
]
Using the above code, all the dynamic routes such as /products/1, /products/2, /products/3, etc. will be active for the Products link and all the routes like /blogs/1, /blogs/2, /blogs/3, etc. will be active for the Blogs link.