0

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

sam
  • 1
  • 1

2 Answers2

1

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

grekier
  • 2,322
  • 1
  • 16
  • 23
-1

You don't use useEffect for generating dynamic routes. Utilize some of NextJS's data fetching features - specifically getStaticPaths - https://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.

V4k4
  • 33
  • 6