Part 53: Enhancing the User Interface with Product Cards in a Next.js Application

[Pages] Responsive Design and Image Optimisation

[Pages] Responsive Design and Image Optimisation

In the previous section, we discussed data fetching from an API and how to refresh it using Incremental Static Regeneration. Now, let's focus on enhancing the user interface of our Next.js application. Specifically, we'll transform a basic list of products on the HomePage into a more visually appealing layout using product cards. This will involve creating a ProductCard component to display each product's name, image, and price.

Designing the Product Card Component

Step 1: Creating the ProductCard Component

We'll start by creating a new React component called ProductCard. This component will encapsulate the logic for displaying a product's details.

// components/ProductCard.js

import Link from 'next/link';

function ProductCard({ product }) {
  return (
    <div className="border my-4 w-80 shadow hover:shadow-xl">
      <Link href={`/products/${product.id}`}>
        <img src="https://dummyimage.com/320x240" alt="" />
        <div className="p-2 flex justify-between items-baseline">
          <h2 className="text-lg font-bold">
            {product.title}
          </h2>
          <span>
            {product.price}
          </span>
        </div>
      </Link>
    </div>
  );
}

export default ProductCard;

In this component, we use a placeholder image from dummyimage.com. The ProductCard displays the product's title and price, using Tailwind CSS for styling.

Step 2: Integrating ProductCard in the HomePage

Next, we'll replace the existing simple text links with our new ProductCard component.

// pages/index.js

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

function HomePage({ products }) {
  return (
    <>
      <Head>
        <title>Home Page</title>
      </Head>
      <Title />
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            <ProductCard product={product} />
          </li>
        ))}
      </ul>
    </>
  );
}

export default HomePage;

By using ProductCard, we encapsulate the styling and layout logic, making it easier to manage and update.

Step 3: Adding Styling with Tailwind CSS

We've already included some basic styles in the ProductCard. Here's a breakdown of how these styles enhance the UI:

  • Borders and Shadows: The border and shadow classes give each card a distinct boundary and a subtle shadow effect. The hover:shadow-xl class adds a larger shadow on hover, making the card appear to lift slightly.

  • Flexbox Layout: Using flex, justify-between, and items-baseline, we arrange the product title and price horizontally, ensuring they are aligned neatly.

  • Responsive Design: The w-80 class sets a fixed width for each card, aligning with the image dimensions, and ensuring a consistent layout.

Step 4: Displaying Real Product Data

To display real product prices instead of placeholder text, we modify the data fetching logic in lib/products.js:

// lib/products.js

function stripProduct(product) {
  return {
    id: product.id,
    title: product.title,
    description: product.description,
    price: '$' + product.price.toFixed(2),
  };
}

Here, we format the price as a string with a dollar sign and two decimal places. This ensures consistency across the UI.

Conclusion

By creating a dedicated ProductCard component, we not only improve the visual appeal of our HomePage but also make our codebase more modular and maintainable. Tailwind CSS helps achieve a clean and responsive design effortlessly. In future iterations, we can replace placeholder images with actual product images and further enhance the styling to fit our brand's aesthetic.

This approach demonstrates how component-based design in React, combined with powerful styling utilities like Tailwind, can significantly enhance the user experience in web applications. As you continue developing, consider how you can apply similar techniques to other parts of your UI for a cohesive and engaging user interface.

Last updated