Reputation: 33
I am stuck with Nextjs : I need to create nested dynamic routes based on my (local) data.
Here are the routes that I would like to create :
.../cars/
-> displays all the categories (sedan, suv, 4x4)
.../cars/category/
-> displays cars in the category
ex : .../cars/sedan -> displays cars in the sedan category
.../cars/category/id
-> displays the details of the car from category which has id = 1
ex : .../cars/sedan/1 -> displays the details of the sedan car with id = 1
For routes 1 and 2 it's ok but I don't know how to do the last one. Can you help me please ?
data.js
export const cars = [
{
id: 1,
name: 'sedan',
models: [
{
id: 1,
name: 'model1',
image: '/sedan1.jpg',
},
{
id: 2,
name: 'model2',
image: '/sedan2.jpg',
},
{
id: 3,
name: 'model3',
image: '/sedan3.jpg',
},
],
},
{
id: 2,
name: 'suv',
models: [
{
id: 1,
name: 'model1',
image: '/suv1.jpg',
},
{
id: 2,
name: 'model2',
image: '/suv2.jpg',
},
{
id: 3,
name: 'model3',
image: '/suv3.jpg',
},
],
},
{
id: 3,
name: '4x4',
models: [
{
id: 1,
name: 'model1',
image: '/4x4_1.jpg',
},
{
id: 2,
name: 'model2',
image: '/4x4_2.jpg',
},
{
id: 3,
name: 'model3',
image: '/4x4_3.jpg',
},
],
},
];
/cars/index.js
import { cars } from '../../data';
import Link from 'next/link';
export default function Categories({ car }) {
return (
{car.map((c) => (
<Link key={c.id} href={`/cars/${c.name}`} passHref>
<div>{c.name}</div>
</Link>
))}
);
}
export const getStaticProps = async () => {
return {
props: {
car: cars,
},
};
};
/cars/[name].js
import React from 'react';
import { cars } from '../../data';
export default function CategoriesCars({ cars }) {
return (
<div>
{cars.models.map((m) => (
<p key={m.id}>{m.name}</p>
))}
</div>
);
}
export const getStaticPaths = async () => {
const paths = await cars.map((c) => ({
params: {
name: c.name,
},
}));
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const { params } = context;
const response = await cars.filter((c) => c.name === params.name);
return {
props: {
cars: response[0],
},
};
};
Upvotes: 3
Views: 3285
Reputation: 444
The page folder must be:
pages/
cars/
[category]/
[id]/
index.jsx
index.jsx
then go /cars/sedan/2
you can access to category
and id
variables like this:
cars/[category]/[id]/index.jsx
import React from 'react';
import { useRouter } from 'next/router';
export default function Index() {
const router = useRouter();
// router.query.category -> sedan
// router.query.id -> 2
return <div>{JSON.stringify(router.query)}</div>;
}
// or
export const getServerSideProps = async (context) => {
const { params } = context;
console.log(params); // { category: 'sedan', id: '2' }
return {
props: {
cars: {},
},
};
};
// or if you wish use getStaticProps for SSG (with getStaticPaths)
export const getStaticPaths = async (context) => {
const paths = cars
.map((car) =>
car.models.map((model) => ({
params: {
id: model.id.toString(),
category: car.name,
},
}))
)
.flat(); // this is important
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const { params } = context;
console.log(params);
return {
props: {
cars: {},
},
};
};
Example: StackBlitz
Upvotes: 5