⚠️ After March 18, 2024, the FastStore documentation will be migrated to the Developer Portal. For more information, access the official release note.

Contextual Images

Sometimes store owners want images to appear only in specific contexts, such as a product image that should appear only on the SKU Selector, not on the gallery.

How to use contextual images

1. Use Labels on VTEX Catalog

On VTEX's catalog, you should set the Label field of the product image to a context name. The only labels with special meaning are generic and skuvariation. If you label an image with generic you won't be able to filter for that individual label, you will always end up with the full set of images.

In this example we're going to add the gallery label (opens in a new tab) to images that we want to display on the PDP's Image Gallery.

2. Query for the correct images on their context

Add fragments to both ServerProductQuery and ClientProductQuery:

src/fragments/ServerProduct
import { gql } from '@faststore/core/api'
 
export const fragment = gql`
  fragment ServerProduct on Query {
    product(locator: $locator) {
      galleryImages: image(context: "gallery", limit: 3) {
        url
        alternateName
      }
    }
  }
`
src/fragments/ClientProduct
import { gql } from '@faststore/core/api'
 
export const fragment = gql`
  fragment ClientProduct on Query {
    product(locator: $locator) {
      galleryImages: image(context: "gallery", limit: 3) {
        url
        alternateName
      }
    }
  }
`

Note that we are only selecting three images by passing the limit: 3 argument. If we omit this argument, all images labeled gallery will be returned. For backward compatibility, all the images are returned whenever a context is not found as a Label on a Product's images.

3. Override the ImageGallery

Create the src/components/overrides/ProductDetails.tsx file and add the following content to it:

import { SectionOverride } from "@faststore/core";
 
import { usePDP } from "@faststore/core";
import { Image_unstable as Image } from "@faststore/core/experimental";
 
import { ImageGallery, ImageGalleryViewer } from "@faststore/ui";
import { useState } from "react";
 
const SECTION = "ProductDetails" as const;
 
const ImageComponent = ({ url, alternateName }: {url: string, alternateName?: string}) => {
  return <Image src={url} alt={alternateName} width={68} height={68}/>
}
 
const override: SectionOverride = {
  section: SECTION,
  components: {
    __experimentalImageGallery: {
      Component: () => {
        // The ServerProductQuery and ClientProductQuery fragments are accessed via the usePDP Hook.
        const { data } = usePDP();
        const [selectedIndex, setSelectedIndex] = useState<number>(0);
 
        // Instead of using the images being passed to the ImageGallery Component, we are using the galleryImages we specifically asked for.  
        const currentImage = data.product.galleryImages[selectedIndex];
 
        return (
          <ImageGallery
            images={data.product.galleryImages}
            ImageComponent={ImageComponent}
            selectedImageIdx={selectedIndex}
            setSelectedImageIdx={setSelectedIndex}
            data-fs-product-details-gallery="true"
          >
            <ImageGalleryViewer>
              <Image
                sizes="(max-width: 360px) 50vw, (max-width: 768px) 90vw, 50vw"
                width={691}
                height={691 * (3 / 4)}
                loading="eager"
                src={currentImage.url}
                alt={currentImage.alternateName}
              />
            </ImageGalleryViewer>
          </ImageGallery>
        );
      },
    },
  },
};
 
export { override };

4. Selecting an image for the SKU Selector

As mentioned above, the FastStore API defines a special name for images that are supposed to appear on the SKU Selector. The first image labeled skuvariation on the Catalog will automatically appear on the SKU Selector. If no image has the skuvariation label, the first image of the SKU will be displayed.

Trade-offs

If you need an image to appear in different contexts (SKU Selector and Product Gallery) you should upload it twice and set different labels for each of the images.