Next.js with Shadcn UI Product Cards Example

In this tutorial, we’ll create product cards using Next.js and Shadcn UI. We’ll make them responsive, add hover animations, and include sale tags, using Tailwind CSS for styling.

Before using the card in Next.js 13 with Shadcn UI, you need to install it by running npx shadcn-ui add card.

npx shadcn-ui add card
# or
npx shadcn-ui@latest add

Nextjs with Shadcn UI Product Cards Example

1. Create a New Arrival product card using Next.js and Shadcn UI. Use components like Card, CardContent, CardDescription, CardFooter, CardHeader, and CardTitle.

import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";

export default function ProductCard() {
  return (
    <div className="container mx-auto my-10">
      <Card className="bg-white max-w-sm rounded-lg overflow-hidden shadow-md hover:shadow-lg transition duration-300">
        <CardHeader className="relative">
          <img
            src="/watch.png"
            alt="Product Image"
            className="w-full h-48 bg-contain bg-center"
          />
          <div className="absolute top-0 left-0 bg-gradient-to-r from-blue-500 to-purple-500 p-2 text-white">
            New Arrival
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <CardTitle className="text-xl font-semibold mb-2">Product Title</CardTitle>
          <CardDescription className="text-gray-600 mb-4">
            Product Description goes here. Provide a brief overview of the product.
          </CardDescription>
          <p className="text-gray-700 mb-2">$99.99</p>
        </CardContent>
        <CardFooter className="p-4 bg-gray-100">
          <button className="bg-blue-500 hover:bg-blue-700 text-white py-2 px-4 rounded-full">
            Add to Cart
          </button>
        </CardFooter>
      </Card>
    </div>
  );
}
Shadcn UI Product Cards

2. Create a responsive product card using Next.js and Shadcn UI, styled with Tailwind CSS grid classes.

import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"

export default function ProductCard() {
  return (
    <div className="container mx-auto my-10 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
      {/* Product Card 1 */}
      <Card className="bg-white max-w-sm rounded-lg overflow-hidden shadow-md hover:shadow-lg transition duration-300">
        <CardHeader className="relative">
          <img
            src="/watch.png"
            alt="Product Image"
            className="w-full h-48 bg-contain bg-center"
          />
          <div className="absolute top-0 left-0 bg-gradient-to-r from-blue-500 to-purple-500 p-2 text-white">
            New Arrival
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <CardTitle className="text-xl font-semibold mb-2">
            Product Title
          </CardTitle>
          <CardDescription className="text-gray-600 mb-4">
            Product Description goes here. Provide a brief overview of the
            product.
          </CardDescription>
          <p className="text-gray-700 mb-2">$99.99</p>
        </CardContent>
        <CardFooter className="p-4 bg-gray-100">
          <button className="bg-blue-500 hover:bg-blue-700 text-white  py-2 px-4 rounded-full">
            Add to Cart
          </button>
        </CardFooter>
      </Card>

      {/* Product Card 2 */}
      <Card className="bg-white max-w-sm rounded-lg overflow-hidden shadow-md hover:shadow-lg transition duration-300">
        <CardHeader className="relative">
          <img
            src="/watch.png"
            alt="Product Image"
            className="w-full h-48 bg-contain bg-center"
          />
          <div className="absolute top-0 left-0 bg-gradient-to-r from-blue-500 to-purple-500 p-2 text-white">
            New Arrival
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <CardTitle className="text-xl font-semibold mb-2">
            Product Title
          </CardTitle>
          <CardDescription className="text-gray-600 mb-4">
            Product Description goes here. Provide a brief overview of the
            product.
          </CardDescription>
          <p className="text-gray-700 mb-2">$99.99</p>
        </CardContent>
        <CardFooter className="p-4 bg-gray-100">
          <button className="bg-blue-500 hover:bg-blue-700 text-white  py-2 px-4 rounded-full">
            Add to Cart
          </button>
        </CardFooter>
      </Card>

      {/* Product Card 3 */}
      <Card className="bg-white max-w-sm rounded-lg overflow-hidden shadow-md hover:shadow-lg transition duration-300">
        <CardHeader className="relative">
          <img
            src="/watch.png"
            alt="Product Image"
            className="w-full h-48 bg-contain bg-center"
          />
          <div className="absolute top-0 left-0 bg-gradient-to-r from-blue-500 to-purple-500 p-2 text-white">
            New Arrival
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <CardTitle className="text-xl font-semibold mb-2">
            Product Title
          </CardTitle>
          <CardDescription className="text-gray-600 mb-4">
            Product Description goes here. Provide a brief overview of the
            product.
          </CardDescription>
          <p className="text-gray-700 mb-2">$99.99</p>
        </CardContent>
        <CardFooter className="p-4 bg-gray-100">
          <button className="bg-blue-500 hover:bg-blue-700 text-white  py-2 px-4 rounded-full">
            Add to Cart
          </button>
        </CardFooter>
      </Card>
    </div>
  )
}
shadcn ui responsive product card

3. Create a product card with sale tags and hover-scale animations using Next.js and Shadcn UI, styled with Tailwind CSS.

import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";

export default function ProductCard() {
  return (
    <div className="container mx-auto my-10 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
      <Card className="bg-white rounded-lg overflow-hidden shadow-md hover:shadow-lg transition duration-300 ease-in-out transform hover:-translate-y-1">
        <CardHeader className="relative">
          <img
            src="/watch.png"
            alt="Elegant Watch"
            className="w-full h-48 object-cover object-center transition duration-300 ease-in-out"
          />
          <div className="absolute top-0 right-0 bg-red-600 text-white p-2 rounded-bl-lg">
            Sale
          </div>
        </CardHeader>
        <CardContent className="p-4">
          <CardTitle className="text-xl font-semibold mb-2">Product Title 2</CardTitle>
          <CardDescription className="text-gray-700 mb-4">
            Another compelling product description here.
          </CardDescription>
          <p className="text-gray-800 mb-2">$129.99</p>
        </CardContent>
        <CardFooter className="p-4 bg-gray-200">
          <button className="bg-blue-600 hover:bg-blue-800 text-white py-2 px-4 rounded-full transition duration-300 ease-in-out">
            Add to Cart
          </button>
        </CardFooter>
      </Card>
    </div>
  );
}
 shadcn ui animation product card
Aaronn
Aaronn

Hey there! I'm Aaronn, a Full Stack Developer who's all about React, NEXTJS, Node.js, and Tailwind CSS. I'm on a mission to craft awesome websites that look great and work even better.