Upsell & Cross-sell
Integrate Fast Simon's Upsell & Cross-sell feature.
Step 1: Fetch Upsell & Cross-sell Products
Locate the File:
- Identify the file where you want to display the Upsell & Cross-sell Widget.
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.