4

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 :

  1. .../cars/ -> displays all the categories (sedan, suv, 4x4)

  2. .../cars/category/ -> displays cars in the category

    ex : .../cars/sedan -> displays cars in the sedan category

  3. .../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],
    },
  };
};

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your reply. I can't adapt your example to my code. You are using getServerSideProps while I need getStaticPaths and getStaticProps. Also when I try your directives I get an error message Error: A required parameter (category) was not provided as a string in getStaticPaths for / cars / [category]
I've edited example. You just provide path based on data. Here: stackblitz
Thank you for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.