> ## 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.

We call the product data that you receive for each product card that you have to render `display`.
That component will receive a `display` of the type `YourDisplay | null`.
`YourDisplay` is a type definition of your specific display. Please ask Depict for this.

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.

The `productCard` component has to return a `HTMLElement` or `HTMLElement[]`.

## 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.

| Option | 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` |
| `class` | `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.

| Option | Type | Description |
| - | - | - |
| `width` | `string` | Width of the text placeholder |
| `height` | `string` | Height of the text placeholder |
| `class` | `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:

<Tip>"Why is this JSX? I'm not using react!" - Did you miss the [previous page?](/js-ui-guide/setup/setting-up-jsx)</Tip>

```tsx theme={null}
import { ImagePlaceholder, TextPlaceholder } from "@depict-ai/js-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 || "#"}
      class="rec-outer"
      {...(variant_to_show && "recommendation_id" in variant_to_show
        ? { "data-recommendation-id": variant_to_show.recommendation_id }
        : {})}
    >
      {variant_to_show ? (
        <div class="image-container">
          {/* Use the first image in image_urls as the default image */}
          <img class="default-image" src={variant_to_show.image_urls[0]} />
          {/* Use the second image in image_urls as the hover image */}
          <img class="hover-image" src={variant_to_show.image_urls[1]} />
        </div>
      ) : (
        <ImagePlaceholder aspectRatio={imageAspectRatio} />
      )}

      <div class="text-container">
        <div class="rec-title">
          {variant_to_show?.title ?? <TextPlaceholder height="1em" width="20ch" />}
        </div>
        <div class="price-container">
          <span class="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.