Build recommendation interfaces (Shopify Hydrogen)

This is for:

Developer

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},
    }), 1
    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
1 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'; 1

export function Recommendations() {
  const homepageRecommendations = useHomepageRecommendations();

  return (
    <div>
      {homepageRecommendations.state.products.map(
        (
          recommendation 2
        ) => (
          <div key={recommendation.permanentid}>
            <strong>{recommendation.ec_name}</strong>
            {recommendation.ec_price != null && (
              <span> — ${recommendation.ec_price.toFixed(2)}</span>
            )}
          </div>
        )
      )}
    </div>
  );
}
Recommendations annotations
1 Use the useHomepageRecommendations hook to access the homepage recommendation controller.
2 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) { 1
  const navigatorContextProvider = () =>
    new ServerSideNavigatorContextProvider(request);
  standaloneEngineDefinition.setNavigatorContextProvider(
    navigatorContextProvider
  );
  recommendationEngineDefinition.setNavigatorContextProvider( 2
    navigatorContextProvider
  );

  const standaloneStaticState = await fetchStaticState({
    k: 'standaloneEngineDefinition',
    url: request.url, 3
  });

  let recommendationStaticState = null;
  try {
    recommendationStaticState = await fetchRecommendationStaticState({ 4
      context,
      request,
      k: ['homepageRecommendations'],
    });
  } catch {
    // Recommendations fetch failed — page will render without them.
  }

  return {standaloneStaticState, recommendationStaticState};
}
Homepage loader annotations
1 The loader runs on the server to fetch the static state for the standalone search box and recommendations before rendering.
2 Set the navigator context provider for the recommendation engine.
3 Pass the current request URL so Coveo knows which page the user is on.
4 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 1
        navigatorContext={new ClientSideNavigatorContextProvider()} 2
        staticState={standaloneStaticState as StandaloneStaticState} 3
      >
        <StandaloneSearchBox />
      </StandaloneProvider>
      {recommendationStaticState && ( 4
        <RecommendationProvider 5
          navigatorContext={new ClientSideNavigatorContextProvider()}
          staticState={recommendationStaticState as RecommendationStaticState}
        >
          <Recommendations />
        </RecommendationProvider>
      )}
    </div>
  );
}
Homepage component annotations
1 Wrap your components with the StandaloneProvider and provide the navigatorContext and staticState props.
2 Since navigation context providers have already been created, use ClientSideNavigatorContextProvider on the client side.
3 Use the pre-fetched static state from the loader to hydrate the engine on the client without an additional request.
4 Only render recommendations if the static state was successfully fetched. Recommendations require valid slot IDs configured in your Coveo organization.
5 Wrap your recommendations component with your recommendation provider.