Reputation: 3945
I'm using the default dynamic routing technique of nextjs in my project which is based on the folder structure. I have a route which is:
pages/[language]/location/[location_id]
Now I'm coming across a use case where I need the above route exactly the same except the last parameter of [location_id]
, I need [route_id]
here.
When I created a file [route_id].js
for this new route, I'm facing this error:
throw new Error(`You cannot use different slug names for the same dynamic path ('${previousSlug}' !== '${nextSlug}').`);
I'm aware of the error and the problem about why it's showing me this after doing some research but I'm unable to understand how I can solve this problem. I just want a solution how I can implement these two routes in my app:
Route 1: pages/[language]/location/[location_id]
Route 2: pages/[language]/location/[route_id]
PS: I've already studied this: https://github.com/zeit/next.js/issues/9081
Upvotes: 28
Views: 42841
Reputation: 61
I want to add something very dumb, but it could be a solution to this problem as it was for mine, since i am learning next
make sure the folder names are not in round braces like
(sign-up)
but rather simply,
sign-up
because these round braces make anything written inside the braces as null and is entirely for our help to remember what the folder has inside it.
Upvotes: 0
Reputation: 140
As per latest version in 2023 Oct:
To create a route with catch-all segments in Next.js, you can use the ellipsis notation inside the square brackets [...segmentName]. This allows your dynamic route to match multiple segments after the initial dynamic segment. Here's how to set it up:
Create the dynamic route file in the pages directory. In your case, you want to handle routes with varying numbers of segments like /shop/a, /shop/a/b, and /shop/a/b/c. You can create a file called pages/shop/[...slug].js to achieve this.
In your [...slug].js file, you can access the matched segments using the router.query object. Here's an example of how to write the code:
import { useRouter } from 'next/router';
const ShopPage = () => {
const router = useRouter();
const { slug } = router.query;
return (
<div>
<h1>Shop Page</h1>
<p>Segments: {slug.join('/')}</p>
</div>
);
};
export default ShopPage;
In this example, slug is an array that contains all the segments matched by the catch-all route.
When you access the URL /shop/a, slug will be ['a']. For /shop/a/b, slug will be ['a', 'b'], and for /shop/a/b/c, slug will be ['a', 'b', 'c']. This catch-all segment feature is a powerful tool in Next.js, enabling you to create dynamic routes that handle various URL structures with ease. It's perfect for scenarios where you have variable-length segments in your URLs, such as category hierarchies or nested structures.
I hope this helps you implement catch-all segments in your Next.js project. If you have any further questions or need clarification, feel free to ask!
Upvotes: 0
Reputation: 7510
It would have been possible for Next.js to handle multiple dynamic routes under some circumstances. For instance, once a dynamic route is detected to have multiple files, if those files also included getStaticPaths
, it could iterate through them. If the first file didn't have the path, it would attempt to find it on the second file. This however could have many edge cases in how its expected to function, so it's understandable that they didn't include it.
I resolved this issue by having a single dynamic route which acts as a union for both sets of data. During rendering, I check which data the page is and provide the appropriate component. Below is some code as an example.
const getStaticPaths = () => {
const pathsA = [...]
const pathsB = [...]
return {paths: [...pathsA, ...pathsB]}
}
const getStaticProps = (context) => {
const isDataA = ...
const data = ...
return {props: {isDataA, data}}
}
const Page = (props) => {
if (props.isDataA) {
return <DataAPage data={props.data} />
} else {
return <DataBPage data={props.data} />
}
}
const DataAPage = (props) => {
return <>{props.data}</>
}
const DataBPage = (props) => {
return <>{props.data}</>
}
Upvotes: 1
Reputation: 1993
From the official code of Next.js:
currently multiple dynamic params on the same segment level are not supported
if (previousSlug !== null) {
// If the specific segment already has a slug but the slug is not `something`
// This prevents collisions like:
// pages/[post]/index.js
// pages/[id]/index.js
// Because currently multiple dynamic params on the same segment level are not supported
if (previousSlug !== nextSlug) {
// TODO: This error seems to be confusing for users, needs an error link, the description can be based on above comment.
throw new Error(`You cannot use different slug names for the same dynamic path ('${previousSlug}' !== '${nextSlug}').`);
}
}
Upvotes: 5
Reputation: 2722
The two routes you have provided are exactly equivalent and are not at all different. Therefore, they will be handled by a single page. There is no example of two urls that will route to different nextjs pages for the above two routes.
Anything written in []
will handle any type of value e.g 1 or 2 or any other value for that matter.
You can not make two pages to handle same request because there is no way for next or anyone else for that matter to know whether you are using route_id or location_id because these are both variables that are representing any value.
If you want to differentitate between them, either create a new route with
/route/[route_id]
instead of
/location/[location_id]
, or use queryparams
e.g
pages/[language]/location?locationid=[location_id]
And
pages/[language]/location?routeid=[route_id]
Upvotes: 23