Skip to main content

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

  1. Navigate to the file: routes/collections.$handle.tsx.
  2. Invoke getSmartCollection:
    • Use the root loader function in the same file.
    • Pass parameters such as category URL, page number, sort by, and narrow filters.
  3. Pass the Results:
    • Forward the fetched data to the Collection component for rendering.
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:

  1. Facets Ready in the Collection Response:
    • Assign the facets directly and pass them with the rest of the data.
  2. 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.