Step 2: Creating a Custom Card Component

Before creating a custom card component, let’s take a look at the CardComponent type signature:

type CardComponent<T> = (props: CardProps<T>) => JSX.Element;

Every card component captures the type that is provided so that the information can be safely used in the UI.

In your project create a folder called cards and add a file called ProductCard.tsx. This component will eventually be passed to the <VerticalResults /> component as the CardComponent prop.

// src/cards/ProductCard.tsx

import { CardProps } from "@yext/search-ui-react";
import { Product } from "../types/products";

export const ProductCard = ({ result }: CardProps<Product>): JSX.Element => {
  const product = result.rawData;
  const imageUrl = product.photoGallery?.[0]?.image.url;

  return (
    <div className="flex flex-col px-4 py-4 border items-center">
      <img className="w-24" src={imageUrl} alt={product.name} />
      <div className="text-center">
        <h3>{product.name}</h3>
        <p>${product.price?.value}</p>
      </div>
    </div>
  );
};

There’s a few things to call out about the example above:

  • The result prop contains a generic field called rawData. By passing the Product type to CardProps, rawData is typed as a Product
  • photoGallery and price are both optional fields. Since this example is type safe, there is no concern of an uncaught type error breaking the app.