Part 44: Enhancing Your Next.js Shop Website with Product Detail Pages

[Pages] Data Fetching

[Pages] Data Fetching

Now that we've chosen the best approach for fetching product data, it's time to enhance our shop website by adding more features. Currently, our website displays a list of products, but users can't click on these products to view more details. To address this, we'll introduce clickable links for each product, leading to dedicated product detail pages.

The first step is to make our product titles clickable. This requires using the Next.js Link component, which allows for client-side navigation between routes in a Next.js application. Let's modify our product list to include these links.

Code Update for Product List

Here's how to add links to each product in the list:

// pages/index.js

import Head from 'next/head';
import Link from 'next/link';
import Title from '../components/Title';
import { getProducts } from '../lib/products';

export async function getStaticProps() {
  console.log('[HomePage] getStaticProps()');
  const products = await getProducts();
  return {
    props: { products },
    revalidate: 5 * 60, // revalidate every 5 minutes
  };
}

function HomePage({ products }) {
  console.log('[HomePage] render:', products);
  return (
    <>
      <Head>
        <title>Next Shop</title>
      </Head>
      <main className="px-6 py-4">
        <Title>Next Shop</Title>
        <ul>
          {products.map((product) => (
            <li key={product.id}>
              <Link href={`/products/${product.id}`}>
                <a>{product.title}</a>
              </Link>
            </li>
          ))}
        </ul>
      </main>
    </>
  );
}

export default HomePage;

Explanation

  • Link Component: We wrap the product title in a Link component to enable navigation to the product detail page.

  • Dynamic Route: The href attribute points to a dynamic route /products/${product.id}, where product.id represents the unique identifier for each product.

Creating Dynamic Product Pages

To display individual product details, we need to create a dynamic route. This involves setting up a new file in the pages directory that will handle requests to /products/[id].

Creating the Dynamic Route

  1. Create a Folder: Inside the pages directory, create a new folder named products.

  2. Dynamic Route File: Inside the products folder, create a file named [id].js. The square brackets indicate that this file is a dynamic route, capturing the id parameter from the URL.

Implementing the Product Page

The product page will fetch specific product data using the getStaticProps function and display the product title and description. Here's the implementation:

// pages/products/[id].js

import { getProduct, getAllProductIds } from '../../lib/products';
import Head from 'next/head';

export async function getStaticPaths() {
  const paths = await getAllProductIds();
  return {
    paths,
    fallback: false,
  };
}

export async function getStaticProps({ params }) {
  const product = await getProduct(params.id);
  return {
    props: {
      product,
    },
  };
}

function ProductPage({ product }) {
  return (
    <>
      <Head>
        <title>{product.title} - Next Shop</title>
      </Head>
      <main className="px-6 py-4">
        <h1 className="text-2xl font-bold">{product.title}</h1>
        <p>{product.description}</p>
      </main>
    </>
  );
}

export default ProductPage;

Explanation

  • getStaticPaths: This function generates paths for all products based on their IDs, allowing Next.js to pre-render these pages.

  • getStaticProps: Fetches data for a specific product using its ID. This data is passed as props to the component.

  • Component Structure: The product page displays the product's title and description, with the title also used in the page's <title> tag for better SEO.

Conclusion

By adding product detail pages with dynamic routing, we've significantly improved our shop website's functionality. Users can now click on a product to learn more about it, enhancing their browsing experience. This setup not only makes our website more interactive but also prepares us for future enhancements, such as adding more product details or implementing a shopping cart feature. Happy coding!

Last updated