Build recommendation interfaces (Shopify Hydrogen)
Build recommendation interfaces (Shopify Hydrogen)
To build a recommendation interface with Coveo Headless and Shopify Hydrogen, you need to use Recommendations controller hooks, create recommendation components, and display recommendations through a recommendation provider.
Prerequisites
Before you begin building your recommendation interfaces, make sure you:
Define and retrieve the target recommendation controller hooks
When defining your commerce engine, leverage the defineRecommendations functions to define and retrieve the target recommendation hooks.
homepageRecommendations: defineRecommendations({
options: {slotId: HOMEPAGE_SLOT_ID},
}),
cartRecommendations: defineRecommendations({
options: {slotId: CART_SLOT_ID},
}),
pdpRecommendationsLowerCarousel: defineRecommendations({
options: {slotId: PDP_LOWER_CAROUSEL_SLOT_ID},
}),
pdpRecommendationsUpperCarousel: defineRecommendations({
options: {slotId: PDP_UPPER_CAROUSEL_SLOT_ID},
}),
Recommendation controller annotations
For each recommendation controller, specify the slot ID of the recommendation slot configuration from your Coveo organization. The slot IDs are defined in recommendation-slots.ts. |
Create recommendation components
Create recommendation components that use the target recommendation controller hooks.
The following is an example implementation of the homepageRecommendations strategy, which showcases featured products as cards on the home page.
// app/components/Recommendations.tsx
import {useHomepageRecommendations} from '~/lib/commerce-engine';
export function Recommendations() {
const homepageRecommendations = useHomepageRecommendations();
return (
<div>
{homepageRecommendations.state.products.map(
(
recommendation
) => (
<div key={recommendation.permanentid}>
<strong>{recommendation.ec_name}</strong>
{recommendation.ec_price != null && (
<span> — ${recommendation.ec_price.toFixed(2)}</span>
)}
</div>
)
)}
</div>
);
}
Recommendations annotations
Use the useHomepageRecommendations hook to access the homepage recommendation controller. |
|
| Map each product recommendation to a display component. |
Display recommendations with your recommendation provider
When displaying recommendation components on a page, ensure that they’re wrapped in a recommendation provider.
The following showcases the home page with the homepageRecommendations component.
export async function loader({request, context}: LoaderFunctionArgs) {
const navigatorContextProvider = () =>
new ServerSideNavigatorContextProvider(request);
standaloneEngineDefinition.setNavigatorContextProvider(
navigatorContextProvider
);
recommendationEngineDefinition.setNavigatorContextProvider(
navigatorContextProvider
);
const standaloneStaticState = await fetchStaticState({
k: 'standaloneEngineDefinition',
url: request.url,
});
let recommendationStaticState = null;
try {
recommendationStaticState = await fetchRecommendationStaticState({
context,
request,
k: ['homepageRecommendations'],
});
} catch {
// Recommendations fetch failed — page will render without them.
}
return {standaloneStaticState, recommendationStaticState};
}
Homepage loader annotations
| The loader runs on the server to fetch the static state for the standalone search box and recommendations before rendering. | |
| Set the navigator context provider for the recommendation engine. | |
| Pass the current request URL so Coveo knows which page the user is on. | |
| Fetch the static state for recommendations. Wrapped in try-catch because recommendations may fail if slot IDs are not configured for your organization. |
export default function Homepage() {
const {standaloneStaticState, recommendationStaticState} =
useLoaderData<typeof loader>();
return (
<div>
<h2>Welcome</h2>
<p>
This is an example Shopify Hydrogen storefront with Coveo Headless
commerce integration.
</p>
<StandaloneProvider
navigatorContext={new ClientSideNavigatorContextProvider()}
staticState={standaloneStaticState as StandaloneStaticState}
>
<StandaloneSearchBox />
</StandaloneProvider>
{recommendationStaticState && (
<RecommendationProvider
navigatorContext={new ClientSideNavigatorContextProvider()}
staticState={recommendationStaticState as RecommendationStaticState}
>
<Recommendations />
</RecommendationProvider>
)}
</div>
);
}
Homepage component annotations
Wrap your components with the StandaloneProvider and provide the navigatorContext and staticState props. |
|
Since navigation context providers have already been created, use ClientSideNavigatorContextProvider on the client side. |
|
| Use the pre-fetched static state from the loader to hydrate the engine on the client without an additional request. | |
| Only render recommendations if the static state was successfully fetched. Recommendations require valid slot IDs configured in your Coveo organization. | |
| Wrap your recommendations component with your recommendation provider. |