Query a Product Recommendation model with Headless

This is for:


This article describes how to query a Product Recommendation (PR) model with the Coveo Headless library.

Configure your pipeline

To receive recommendations through Headless, you must ensure that your request is routed to the proper query pipeline and targets the correct model association within that pipeline.

To achieve this, your requests must fulfill two query pipeline conditions

Step 1: Target the proper query pipeline

To render recommendations, your request must trigger the pipeline that’s associated with the Product Recommendation (PR) model.

A query pipeline can be targeted by adding a query pipeline condition to it.

You can choose one or more of the following mechanisms to trigger the condition on your pipeline, depending on your specific requirements:

Search Hub

The search hub is a query parameter that indicates the name of the search interface from which the query originates. This parameter can be used to trigger a query pipeline condition.

First, from within the Coveo Administration Console, navigate to the Query Pipelines (platform-ca | platform-eu | platform-au) page. Double-click your pipeline and define a Condition by choosing SearchHub from the dropdown menu.

Next, you must ensure that the requests made with Headless use the same value as the one defined in the condition. This can be achieved in two ways:


You can send custom context information with Headless to determine if a pipeline condition is triggered. For example:

First, navigate to the Query Pipelines (platform-ca | platform-eu | platform-au) page from within the Administration Console. Double-click your pipeline and define a Condition by choosing Context from the dropdown menu. Specify the Context Key as website and the value as sports.

Now, using the Context controller, set the context for your Headless engine:

import {buildContext} from '@coveo/headless';
import {engine} from './Engine.ts'

export function Context() {
  const ctx = buildContext(engine);
  ctx.set({'website': 'sports'})

Step 2: Trigger the model associated within the pipeline

Once the Headless request is routed to the proper pipeline, you must ensure that the request triggers the correct machine learning model association in the pipeline, as many models can be associated to that pipeline. This can be done with the recommendation parameter.

When sending a PR request to the Search API with Headless, the controller automatically populates the recommendation parameter with the identifier of the recommendation interface from which the request originates. The value assigned to this field depends on which Headless controller you use.

You can add a condition to your query pipeline to trigger the correct machine learning model when the recommendation field is populated with a specific value.

Let’s take a look at how this can be done using the Frequently bought together strategy and thus the FrequentlyBoughtTogetherList controller. Search API requests sent with this controller will populate the recommendation field with the frequentBought type value.

To ensure the correct model gets triggered on this request, choose Recommendations when creating the condition and set the value of the condition to be frequentBought.

For more details on which controller maps to which type, see the reference documentation.

Render recommendations with Headless

You can use various Headless engines to implement a product recommendations component for your commerce implementation. If you haven’t already installed Headless, access the Usage page to get started.


Headless can be used with any JavaScript/TypeScript framework or no framework at all. However, this article makes heavy use of the React library. If you have experience developing in a front-end framework that isn’t React, consult the React documentation.

Depending on which PR strategy you are trying to implement, you will either have to use the ProductRecommendations or the Recommendations engine.

Some common PR strategies have a dedicated ProductRecommendation (PR) controller. A list of strategies for which a controller exists can be found within the reference documentation.

If a dedicated controller doesn’t exist for the strategy you are trying to implement, you will have to use the Recommendation engine.

ProductRecommendation engine

  1. Configure a headless engine for product recommendations.

    import {
    } from "@coveo/headless/product-recommendation"; 1
    export const productRecommendationsEngine: ProductRecommendationEngine =
      buildProductRecommendationEngine({ 2
        configuration: { 3
          accessToken: "xxc23ce82a-3733-496e-b37e-9736168c4fd9",
          organizationId: "electronicscoveodemocomo0n2fu8v",
    1 Import the required builder function and data type from the @coveo/headless/product-recommendation package.
    2 Use a builder function to initialize a PR engine.
    3 Specify the configuration options of your engine. These determine how the engine connects to your Coveo organization. For now, we’re using a demo configuration so that you already have some data to work with.

    The query pipeline defined for the demo organization is triggered by requests whose Recommendation parameter is populated.

  2. Initialize your controller.

    import { productRecommendationsEngine } from "./Engine"; 1
    import {
    } from "@coveo/headless/product-recommendation";
    export const frequentlyViewedTogether: FrequentlyViewedTogetherList =
      buildFrequentlyViewedTogetherList(productRecommendationsEngine, { 2
        options: {
          maxNumberOfRecommendations: 4,
    1 Import the engine initialized above.
    2 Use the buildFrequentlyViewedTogetherList function to create an instance of the FrequentlyViewedTogetherList controller. The controller requires the engine you initialized in src/Engine.ts in addition to an options object, which specifies the number of recommendations.

    Headless PR controllers return recommendations using the product’s SKU attribute. A SKU is a unique ID that distinguishes each product variant from all other variants.

    In order to get recommendations, call the setSkus method on the controller. This method will update the controller’s state with recommendations based on the SKU passed to it.

  3. Create a component that utilizes the controller.

    import {
    } from "@coveo/headless/product-recommendation";
    import { useEffect, useState } from "react";
    import { productRecommendationsEngine } from "../Engine";
    interface FreqViewedTogetherProps { 1
      controller: FrequentlyViewedTogetherList;
      productID: string;
    export const FreqViewedTogether: React.FC<FreqViewedTogetherProps> = (
    ) => {
      const { controller, productID } = props;
      const [state, setState] = useState(controller.state);
      useEffect(() => { 2
        controller.subscribe(() => setState(controller.state));
      }, [controller]);
      if (state.error) {
        return null;
      const logClick = (recommendation: ProductRecommendation) => { 3
        if (!productRecommendationsEngine) {
        const { logProductRecommendationOpen } = loadClickAnalyticsActions(
      controller.setSkus([productID]); 4
      return (
        <div className="recs-list">
          <h2>People also viewed</h2>
            {state.recommendations.map((recommendation) => { 5
              return (
                <li key={recommendation.permanentid}>
                  <h2> 6
                      onClick={() => logClick(recommendation)}
                      onContextMenu={() => logClick(recommendation)}
                      onMouseDown={() => logClick(recommendation)}
                      onMouseUp={() => logClick(recommendation)}
    export default FreqViewedTogether;
    1 Specify the FrequentlyViewedTogetherList controller and the productID as props for this component. The productID acts as the unique SKU of the item you want to get recommendations for.
    2 Use the useEffect hook to re-render the component every time the state of the controller changes by binding controller.state to the local state. Also call the refresh method on the controller to get the latest recommendations.
    3 Define the logClick function that dispatches an action which sends a click event when a recommendation is opened.
    4 Call the setSkus method on the controller by passing in the productID of the items you wish to use to fetch recommendations. The controller will then return frequently viewed items with the given products. The recommendations returned by the controller are those items that would be frequently viewed with all the SKUs you specify here.
    5 Use the controller’s state to loop through the recommendations array to list the recommended products.
    6 Call the logClick method defined above if the user interacts with the recommendation.
  4. Render the recommendations component.

    To display recommendations on your page, use the FreqViewedTogether component created above by passing in the controller and the SKU of the product you wish to render recommendations for:

    import FreqViewedTogether from "./components/FreqViewedTogether";
    import { frequentlyViewedTogether as FreqViewedTogetherController } from "../controllers";
    // . . .
      return (
        {/* ... */}
        {/* ... */}

Recommendation Engine

To implement a recommendation strategy for which there is no dedicated ProductRecommendation controller available, you can use the RecommendationList controller.

While implementation of components using this controller is similar to those done via a PR controller, you do need to ensure that you specify an id parameter for the RecommendationListOptions object of the RecommendationList controller. We recommend using an id that represents the purpose of the recommendation component.

import { buildRecommendationList } from "@coveo/headless/recommendation"
import { recommendationEngine } from "./Engine.ts"
// . . .
const controller = buildRecommendationList(recommendationEngine, {
  options: {
    id: <MY_ID> 1
1 Specify the id parameter for the RecommendationListOptions object.

This id parameter provides the flexibility to name your component in a way that best represents its purpose. You may choose an ID such as "home-page-recs" for home page recommendations or "plp-recs" for product listings page recommendations.

Once sent with Headless, the ID can then be used within Administration Console to accurately trigger the model in your pipeline.

Product Recommendation controllers

The following table shows the Headless Product Recommendations controller of each ML PR strategy:

Controller Strategy Recommendation type


Cart recommender



Frequently bought together



Frequently viewed together



Popular items (bought)



Popular items (viewed)



User recommender