Encountering a 404 error with Next.js 13 dynamic routing

Whenever I click on an item, it redirects to the dynamic route "http://localhost:3000/products/{id}" but instead of displaying the data, I get an error.

Here is my file structure:

  • 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 have attempted changing the folders for dynamic [id] and Product but without any success.

Answer №1

It appears from your structure that you are utilizing the app router, but there is a folder named pages within it which may be causing some confusion.

If you have a file named [id].js, it will function in the "old" pages router setup. However, for this to work, the pages directory should be at the root of your project's source code, not nested inside the app folder.

Since you are using the app folder/router, the proper filename to correspond with

http://localhost:3000/products/{id}
would be /app/products/[id]/page.js

Answer №2

If you're looking to create dynamic routes, using useEffect may not be the best approach. Instead, take advantage of NextJS's data fetching capabilities, like getStaticPaths. You can learn more about it here: https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths

For client-side fetching, check out this link: https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side. It explains why you might be encountering a 404 error with your current approach.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

GWT Validation - Enhance Your Application with a Third Party Library

Is there a reliable JavaScript library available for validating GWT fields such as Email, Text Length, Phone Number, Date & SSN, etc.? I am unable to use the GWT Validation Framework or GWT Errai in my application because I receive responses as JSON r ...

Encountering an internal server error when using Next.js API routes with Nodemailer

Using cPanel to host my Next.js website, I encountered an issue with an API route that uses Nodemailer to send messages. While the route works perfectly fine on localhost and Vercel, every time I call it on the live server, I receive an internal server err ...

Navigating through a collection of images with Next Js using button clicks

I'm currently working on a project that involves looping through a folder of six images when the user clicks the "update profile picture" button. I've encountered some challenges with props in Next Js and would greatly appreciate any assistance. ...

The life cycle of the request/response object in Express.js when using callbacks

Feel free to correct me if this question has already been asked. (I've done as much research as I can handle before asking) I'm really trying to wrap my head around the life cycle of request and response objects. Take a look at the following co ...

Determine your age by manually inputting your date of birth

Utilizing Ajax Calendar, I have successfully implemented a feature to calculate age based on the date selected in one textbox and display it in another. However, I am facing two challenges. First Issue:- I want the Age Textbox to be disabled so users cann ...

Is it better to set the language of Puppeteer's Chromium browser or utilize Apify proxy?

Looking to scrape a website for French results, but the site supports multiple languages. How can I achieve this? Is it best to configure Puppeteer Crawler launch options using args, like so: const pptr = require("puppeteer"); (async () => { const b ...

An issue with Axios request in a cordova app using a signed version

Currently, I am in the process of developing a Cordova application utilizing Axios and React. The interesting part is that everything runs smoothly when I build the app with Cordova and test it on my phone using the APK. However, once I sign, zipalign it, ...

Execute a function on a canvas timer using the setTimeout method

I'm having an issue with my setTimeout function in this code. I want it to call a timer function for a delay, but it's not working consistently every second. Why is that happening? <head> <script> function timer(sec) { var c = do ...

Checking for offline status in a Cordova app using Angular

I have implemented the following code to determine whether my Cordova application is online or offline. var networkState = navigator.connection.type; var states = {}; states[Connection.UNKNOWN] = 'Unknown'; states[Connection.ETHERNET] = ' ...

Generate and delete dynamic iFrames through variable manipulation

I'm currently developing a landing page specifically for our pilots to conveniently access weather information before taking off. However, due to the limitations posed by our computer security measures, I can only utilize iframes to obtain the necessa ...

Revolutionary custom binding with Bootstrap popover integration

Utilizing asp.net mvc with dynamic knockout columns, I am facing an issue with one of the column headers named "Status". The desired functionality includes a bootstrap popover that displays information when a user clicks a font-icon question mark. Here is ...

Declaring module public type definitions for NPM in Typescript: A comprehensive guide

I have recently developed a npm package called observe-object-path, which can be found on GitHub at https://github.com/d6u/observe-object-path. This package is written in Typescript and has a build step that compiles it down to ES5 for compatibility with ...

What is the optimal frequency for saving data when dealing with a particularly extensive form?

I am facing a challenge with saving data to the database using Ajax. While I can handle this aspect, my difficulty lies in the fact that I have a very extensive form that is nested and cannot be altered. This large form consists of approximately 100 input ...

I am looking to transfer the value of one textbox to another textbox within a dynamic creation of textboxes using JavaScript

var room = 1; function add_fields() { room=$('#row_count').val()-1; room++; var objTo = document.getElementById('education_fields'); var divtest = document.createElement("div"); divtest.setAttribute("class", "form- ...

Leverage the power of rxjs to categorize and organize JSON data within an

I am in need of reformatting my data to work with nested ngFor loops. My desired format is as follows: this.groupedCities = [ { label: 'Germany', value: 'de', items: [ {label: 'Berlin', value: 'Berlin ...

Is it possible to utilize JavaScript to access a .php file located in a separate directory?

Although I have been searching all day, I couldn't find a workout that specifically addresses my issue. I'm new to JavaScript and AJAX. Currently, I am exploring a web app called calendar.php located in the directory C:\xampp\htdocs&bs ...

Is Jquery Steps causing interference with the datepicker functionality?

I am currently using the jquery steps plugin for creating a wizard on my website. However, I am experiencing some issues with the functionality of the datepicker and qtip inside the steps. Even after switching the .js references, the problem still persists ...

Tips on altering the input's background color using nextui?

I am currently facing an issue while working with NextJs, TailwindCss, and NextUI. When trying to use the inputs, I found the default white color unappealing. Despite numerous attempts to change the color in various ways, I still end up with this undesired ...

Is it possible to execute a function within an HTML page simply by clicking on it?

As someone who is new to the world of HTML, CSS, and JS, I'm currently facing a challenge: On my website's page1.html, I have implemented a feature that allows users to sort different articles on the page by selecting a sub-menu from the navigat ...

Is it possible to invoke Next.js server actions as a queryFn in ReactQuery?

When implementing a query or mutation using React Query in Next.js 13-14, is it acceptable to substitute an actual function with a server action? ...