skip to Main Content

when I click on a item is goes to the dynamic route "http://localhost:3000/products/{id}" but gives error instead of displaying data

so my file sturcture is

  • app
    • components
      • Product.js
    • pages
      • Products
        • [id].js
    • layout.js
    • page.js
[id].js

const ProductDetail = () => {
  const router = useRouter();
  const { id } = router.query;
  const [product, setProduct] = useState(null);

  useEffect(() => {
    if (id) {
      fetch(`https://fakestoreapi.com/products/${id}`)
        .then((response) => {
          if (!response.ok) {
            throw new Error('Failed to fetch product');
          }
          return response.json();
        })
        .then((data) => setProduct(data))
        .catch((error) => console.error(error));
    }
  }, [id]);

  if (!product) {
    return <p>Loading...</p>;
  }

  return (
    <div>
      <h1 className="text-3xl font-bold text-center my-4">{product.title}</h1>
      <div className="flex justify-center">
        <img
          src={product.image}
          alt={product.title}
          className="mx-auto w-64 h-64"
        />
      </div>
      <p className="text-lg font-semibold mt-2 text-center">${product.price}</p>
    </div>
  );
};

export default ProductDetail;

Product.js

const Product = ({ product: { image, title, price, id } }) => {
  return (
    <div>
      <Link href={`/products/${id}`}>
        <div className="product-card">
          <h1>Product</h1>
          <img 
            src={image}
            width={250}
            height={250}
            className="product-image"
          />
          <p className="product-name">{title}</p>
          <p className="product-price">₹{price}</p>
        </div>
      </Link>
    </div>
  )
}

page.js

"use client";
const Home = () => {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch('https://fakestoreapi.com/products')
      .then((response) => response.json())
      .then((data) => setProducts(data));
  }, []);

  return (
<>
     <div className="products-container">
      {products?.map((product) => <Product key={product.id} product={product} />)}  
    </div>
</>
  );
};
export default Home;

I tried changing the folders but of dynamic [id] an Product but no luck

2

Answers


  1. You don’t use useEffect for generating dynamic routes. Utilize some of NextJS’s data fetching features – specifically getStaticPathshttps://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths

    Here’s the link to client-side fetching: https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side – delves into what you’re doing now and explains why you’re getting the 404 error.

    Login or Signup to reply.
  2. From your structure, it seems that you are using the app router but have some a folder called pages inside. I guess there might be some confusion there.

    Having a file called [id].js will work in the "old" pages router but the pages directory should then be at the root of the source code in your project (not inside the app folder).

    As your are using the app folder/router, the correct filename to map http://localhost:3000/products/{id} is /app/products/[id]/pages.js

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search