> ## Documentation Index
> Fetch the complete documentation index at: https://docs.depict.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Setting up your product card

> Your product card components needs to meet some specific requirements

## Requirements

For both search and product listing pages, you need to set up your product card component.

That component will receive a `display` of the type `YourDisplay` (see [previous page](/react-ui-guide/setup/depict-provider)) <b>OR `null`</b>.

If `display` is `null`, it means that there's no data for this product card yet, and you should display <b>a product card as close to the dimensions as the one you'll display when you'll have data</b>, we'll call this a "placeholder". The placeholder serves as a loading indicator for users as well as enabling scroll restoration when going back and minimizing content shift.

## Example expected output of your product card component

The same card in its two states. Left: `display` is `null`, so the card draws the placeholder at the final dimensions. Right: the display has loaded and the card shows image, title and price.

<CardGroup cols={2}>
  <Frame caption="Loading state: `display` is `null`">
    <img src="https://mintcdn.com/depictai/VbPAGLCs8-reBo4C/images/listing/product-card-loading.png?fit=max&auto=format&n=VbPAGLCs8-reBo4C&q=85&s=b94c9a1234dfbc8c5b9b7329fc31aa54" alt="A product card placeholder: a grey image block in the final aspect ratio, with a grey bar where the title goes and a shorter one where the price goes" width="644" height="976" data-path="images/listing/product-card-loading.png" />
  </Frame>

  <Frame caption="Loaded state: `display` is your display type">
    <img src="https://mintcdn.com/depictai/VbPAGLCs8-reBo4C/images/listing/product-card.png?fit=max&auto=format&n=VbPAGLCs8-reBo4C&q=85&s=43e927f93c320c7b4048bea5be06b937" alt="The same product card with a dress photo, the product title and the price in kronor" width="646" height="974" data-path="images/listing/product-card.png" />
  </Frame>
</CardGroup>

## Provided placeholder components

To make it easier for you to create a placeholder, the SDK exports two shimmering placeholder components. Their usage is shown in the code example below.

### `ImagePlaceholder`

Renders a shimmering placeholder in place of an image. Set `aspectRatio` to match the dimensions of your product images. Alternatively, set `width` and `height` (instead of `aspectRatio`) to use it as a [block](https://developer.mozilla.org/en-US/docs/Glossary/Block/CSS)-mode placeholder.

| Prop | Type | Description |
| - | - | - |
| `aspectRatio` | `number` | Aspect ratio of the image the placeholder stands in for. Mutually exclusive with `width` and `height` |
| `width` | `string` | Width of the placeholder in block mode. Mutually exclusive with `aspectRatio` |
| `height` | `string` | Height of the placeholder in block mode. Mutually exclusive with `aspectRatio` |
| `className` | `string` | Extra classes to add to the placeholder |
| `style` | `object` | Extra styles to add to the placeholder |

### `TextPlaceholder`

Renders a shimmering placeholder in place of text, such as a title or price. Set `width` and `height` to match the dimensions of the text it stands in for.

| Prop | Type | Description |
| - | - | - |
| `width` | `string` | Width of the text placeholder |
| `height` | `string` | Height of the text placeholder |
| `className` | `string` | Extra classes to add to the placeholder |
| `style` | `object` | Extra styles to add to the placeholder |

## Displaying color swatches

```ts theme={null}
export interface YourDisplay {
  /**
  * The index of the variant to show in the variant_displays array
  */
  variant_index: number;
  /**
  * All variants for that product - here you can, for example, get the color of each variant to display color swatches
  */
  variant_displays: YourVariantDisplay[];
  // … other properties
}
```

## Code example

You probably have an existing product card which you just can add placeholder functionality for. Here's an example of how it could look like:

```tsx theme={null}
import { ImagePlaceholder, TextPlaceholder } from "@depict-ai/react-ui";

// Aspect ratio of your product images — the placeholder reserves the same space
const imageAspectRatio = 3 / 4;

export function ProductCard({ display }: { display: null | YourDisplay }) {
  const variant_to_show = display?.variant_displays[display?.variant_index];

  return (
    <a
      href={variant_to_show?.page_url || "#"}
      className="rec-outer"
      {...(variant_to_show && "recommendation_id" in variant_to_show
        ? { "data-recommendation-id": variant_to_show.recommendation_id }
        : {})}
    >
      {variant_to_show ? (
        <div className="image-container">
          {/* Use the first image in image_urls as the default image */}
          <img className="default-image" src={variant_to_show.image_urls[0]} />
          {/* Use the second image in image_urls as the hover image */}
          <img className="hover-image" src={variant_to_show.image_urls[1]} />
        </div>
      ) : (
        <ImagePlaceholder aspectRatio={imageAspectRatio} />
      )}

      <div className="text-container">
        <div className="rec-title">
          {variant_to_show?.title ?? <TextPlaceholder height="1em" width="20ch" />}
        </div>
        <div className="price-container">
          <span className="price">
            {variant_to_show ? (
              variant_to_show.sale_price
            ) : (
              <TextPlaceholder height="1em" width="5ch" />
            )}
          </span>
        </div>
      </div>
    </a>
  );
}
```

<Note>Note how we branch off to the shimmering placeholder effect in place of the content, when there is no content</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.