Skip to main content

Visual Similarity Usage

  • Implementation in file \app\routes\products.$handle.tsx

Configuration

getVisualSimilarityProducts Function

You can customize the behavior of the getVisualSimilarityProducts function by passing the specs parameter to control aspects such as:

  • maxSuggestions: Maximum number of similar products to fetch.
  • sources: Sources of the results. Example sources:
    • similar_products: Products sharing category, tags, or keyword similarity with the viewed product.
    • similar_products_by_attributes: Products sharing categories and chosen attributes (requires selecting relevant attributes in the Fast Simon dashboard).
    • similar_products_lookalike: Visually similar products (requires enabling Look-alike Visually Similar Recommendations in the Fast Simon dashboard).
    • related_top_products: Popular products in the store.

For a full list of configurable parameters, refer to the API product recommendation documentation.

Return Object

The function returns a Promise of an object type ServerProduct[].

FastSimonWidget Component

You can customize the FastSimonWidget component with various props to match your store's design and layout requirements:

  • renderProduct: A function that receives a product object and returns a React element. This allows you to customize the product card for each product in the widget.
  • title: The title of the widget, for example, "Similar Products" or "You may also like".
  • breakpoints: An object of breakpoints to control the number of products displayed on different devices.
  • carouselGap: The gap between products in the carousel (default value: 16px).
  • RightArrowIcon: A JSX element to use as the right arrow icon in the carousel. The left arrow is rotated automatically.
  • imageAspectRatio: The aspect ratio of the product image (default value: "2/3").
<FastSimonWidget
title={'Similar Products'}
products={visualSimilarityProducts}
renderProduct={(product, pos) => <MyProductCard key={product.id} product={product} />}
breakpoints={{
mobile: 2,
tablet: 3,
desktop: 4
}}
carouselGap={16}
RightArrowIcon={<MyRightArrowIcon />}
imageAspectRatio={"2/3"}/>

Usage Example

Imports

import {CacheLong} from '@shopify/hydrogen';
import {FastSimonWidget , transformToShopifyStructure} from '@fast-simon/storefront-kit';
... // additional imports

Loader Function

export async function loader(args: LoaderFunctionArgs) {
// Start fetching non-critical data without blocking time to first byte
const deferredData = loadDeferredData(args);

// Await the critical data required to render initial state of the page
const criticalData = await loadCriticalData(args);

const visualSimilarityProducts = await args.context.fastSimon.getVisualSimilarityProducts({
props: {
productId: criticalData.product.id,
},
cacheStrategy: CacheLong(),
});

return defer({...deferredData, ...criticalData, visualSimilarityProducts});
}


... // more functions and logic

Display Product

export default function Product() {
const {product, variants, visualSimilarityProducts} =
useLoaderData<typeof loader>();
const selectedVariant = useOptimisticVariant(
product.selectedVariant,
variants,
);
const fastStructureProducts = transformToShopifyStructure(visualSimilarityProducts);

const {title, descriptionHtml} = product;

return (
<div className="product">
<ProductImage image={selectedVariant?.image} />
<div className="product-main">
<h1>{title}</h1>
<ProductPrice
price={selectedVariant?.price}
compareAtPrice={selectedVariant?.compareAtPrice}
/>
<br />
<Suspense
fallback={
<ProductForm
product={product}
selectedVariant={selectedVariant}
variants={[]}
/>
}
>
<Await
errorElement="There was a problem loading product variants"
resolve={variants}
>
{(data) => (
<ProductForm
product={product}
selectedVariant={selectedVariant}
variants={data?.product?.variants.nodes || []}
/>
)}
</Await>
</Suspense>
<br />
<br />
<p>
<strong>Description</strong>
</p>
<br />
<div dangerouslySetInnerHTML={{__html: descriptionHtml}} />
<br />
</div>

<FastSimonWidget
title={'Similar Products'}
products={fastStructureProducts}
RightArrowIcon={
<svg
xmlns="http://www.w3.org/2000/svg"
height="1em"
fill="white"
viewBox="0 0 448 512"
>
<path d="M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z" />
</svg>
}
/>

</div>
);
}