Smart Collections
Learn how to integrate the Fast Simon getSmartCollection
function into your Hydrogen app's root loader to enhance your collections with Smart Collection capabilities.
Step 1: Add getSmartCollection
to the Root Loader
- Navigate to the file:
routes/collections.$handle.tsx
. - Invoke
getSmartCollection
:- Use the root loader function in the same file.
- Pass parameters such as category URL, page number, sort by, and narrow filters.
- Pass the Results:
- Forward the fetched data to the
Collection
component for rendering.
- Forward the fetched data to the
import {CacheLong} from '@shopify/hydrogen';
import {transformToShopifyStructure,PaginationBar} from '@fast-simon/storefront-kit';
import {Narrow} from '@fast-simon/utilities';
Step 2: Define the 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 facets = {
facets: criticalData.collection.getFacetsOnly
? criticalData.collection.getFacetsOnly()
: criticalData.collection.facets,
};
const dashboardConfig = {
dashboardConfig: args.context.fastSimon.getDashboardConfig({
cacheStrategy: CacheLong(),
}),
};
return defer({...criticalData, ...facets, ...dashboardConfig});
}
Step 3: Fetch Critical Data with loadCriticalData
async function loadCriticalData({
context,
params,
request,
}: LoaderFunctionArgs) {
const {handle} = params;
const {fastSimon} = context;
if (!handle) {
throw redirect('/collections');
}
const url = new URL(request.url);
const page = Number(url.searchParams.get('page')) || 1;
const narrowString = url.searchParams.get('filters');
const sortBy = url.searchParams.get('sort');
const narrow = narrowString
? Narrow.toServerNarrow(Narrow.parseNarrow(narrowString || ''))
: [];
const collection = await fastSimon.getSmartCollection({
props: {
categoryURL: '/collections/' + handle,
page,
narrow,
facetsRequired: true,
productsPerPage: 20,
categoryID: undefined,
sortBy,
},
});
if (!collection) {
throw new Response(`Collection ${handle} not found`, {
status: 404,
});
}
const transformed = transformToShopifyStructure(collection.items);
collection.products = transformed.products;
collection.handle = collection.category_url.split('/')[1];
collection.title = collection.category_name;
collection.description = collection.category_description;
return {
collection,
};
}
Key Concepts
Translating Fast Simon Results
- Use
transformToShopifyStructure
to map Fast Simon results into the Shopify GraphQL structure. - This step allows you to leverage Shopify’s template components but is optional if you use custom components.
Handling Facets
Fast Simon facets can be optimized in two scenarios:
- Facets Ready in the Collection Response:
- Assign the facets directly and pass them with the rest of the data.
- Facets Not Ready:
- Use the getFacetsOnly callback in the collection response to fetch facets asynchronously.
- Pass the resulting Promise down to the stream.
Additional Notes
- For detailed examples of rendering streamed facets, refer to the Filters component in the sample site.
- Ensure the Collection component can handle the transformed data appropriately.