Skip to main content

Upsell & Cross-sell

Integrate Fast Simon's Upsell & Cross-sell feature.


Step 1: Fetch Upsell & Cross-sell Products

  1. Locate the File:

    • Identify the file where you want to display the Upsell & Cross-sell Widget.
  2. Updating the Root Loader:

    • Integrate the getRecommendations function into your root loader to fetch personalized recommendations.
    • Props:
      • widgetIds: An array of widget IDs from your Fast Simon dashboard.
      • productId(optional): The product ID to use as a reference for recommendations.
      • widgetsToCategories(optional): A map of widget IDs to category IDs, filtering recommendations by specific categories. storefront-kit version 1.4.10 or later is required
        • Note: For more accurate recommendations, pass a random productId from the relevant collection.
    • Key Points:
    • You can pass multiple widget IDs to fetch recommendations for each in a single request.
    • For handling the response:
      • Await the promise (simpler but may impact performance), or
      • Pass it down as a stream to enhance performance.
    • (Optional) Transform the response to Shopify’s data format by using transformToShopifyStructure as shown in the example below.
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);

// Your widgetID from your widgets at Fast Simon dashboard
const widgetIds = ["17301826035377900", "17301826035377911"];

// Optional: Map widget IDs to categories
const widgetsToCategories = {
"17301826035377900": ["category_id1"],
"17301826035377911": ["category_id1", "category_id2", "category_id3"]
};

const recommendationsResponse = args.context.fastSimon.getRecommendations({
props: {
widgetIds: widgetIds,
widgetsToCategories: widgetsToCategories
}
});

return defer({...deferredData,
...criticalData,
recommendationsData: recommendationsResponse.then(data => {
return {
uuid: data.uuid,
widget_responses: data.widget_responses.map(widget => {
return {
...widget,
products: transformToShopifyStructure(widget.products)
}
})
}
})
});
}

Step 2: Use Fast Simon Components

After fetching the data, display it using components from @fast-simon/storefront-kit.

import { FastSimonWidget , transformToShopifyStructure } from '@fast-simon/storefront-kit';

function ProductPage() {

const data = useLoaderData<typeof loader>();

// ... other component logic

return (
<div>
{/* ... other parts of your product page */}
<Suspense fallback={<div className={'spinner-fallback'}><MyLoadingSpinner/></div> }>
<Await resolve={data.recommendationsData}>
{(data) => data.widget_responses.map((widget, index) => (
<FastSimonWidget key={index}
title={widget.title}
products={widget.products}
breakpoints={{
mobile: 2,
tablet: 3,
desktop: 4,
}}
RightArrowIcon={<MyRightArrowIcon/>}
imageAspectRatio="3/4"
/>
))}
</Await>
</Suspense>
</div>
);
}

Key Concepts

Critical vs. Non-Critical Data

  • Critical Data: Includes essential information required for the initial render (e.g., product details).
  • Non-Critical Data: Includes additional elements like visual similarity results, fetched asynchronously to optimize TTFB.

Component Customization

  • Use the FastSimonWidget to display Upsell & Cross-sell products in a visually appealing format.
  • Customize components, such as icons and aspect ratios, to match your theme's design.

Additional Notes

  • The transformToShopifyStructure function ensures compatibility with Shopify's data format. You can skip this if you're using custom components.
  • Use a caching strategy (CacheLong) for optimal performance when fetching similarity results.
  • Important: Implementing the Analytics Section is required before implementing any personalized based widget.