Send custom context information

This is for:

Developer

Coveo JavaScript Search Framework (September 2016)

The Coveo JavaScript Search Framework provides various ways of including custom context information in the search requests and Coveo Usage Analytics (Coveo UA) events originating from a search interface.

Custom context information can serve several purposes in a Coveo implementation:

The PipelineContext component is specifically designed to inject custom context information into search requests and Coveo UA search events.

When using this component, you can set the custom context to send statically (that is, in the component markup configuration), and dynamically (that is, by invoking methods on the initialized component instance).

Setting custom context statically

If some, or all, of the custom context information you want to send is meant to remain static after the page has been served, you can set it as JSON in the markup configuration of the PipelineContext component. Custom context values set in this fashion must be strings.

<div id="search" class="CoveoSearchInterface">
  <!--  ...  -->
  <script class="CoveoPipelineContext" type="text/context">
    {
      "ageGroup": "30-45",
      "mainInterest": "sports"
    }
  </script>
  <!--  ...  -->
</div>

To send the same custom context info along with click and custom events, use a changeAnalyticsCustomData event handler (see Modify the metadata to send with UA events).

<head>
  <script>
  document.addEventListener("DOMContentLoaded", () => {
    // ...
    const root = document.getElementById('search');
    Coveo.$$(root).on('changeAnalyticsCustomData', (e, args) => {
      if (args.type === 'ClickEvent' || args.type === 'CustomEvent'){
        args.metaObject.context_ageGroup = "30-45",
        args.metaObject.context_mainInterest = "sports"
      }
    });
    Coveo.init(root);
    // ...
  });
  </script>
</head>

<body id="search" class="CoveoSearchInterface">
  <!--  ...  -->
  <div class="CoveoAnalytics"></div>
  <script class="CoveoPipelineContext" type="text/context">
    {
      "ageGroup": "30-45",
      "mainInterest": "sports"
    }
  </script>
  <!--  ...  -->
</body>

When using certain versions of the Interface Editor to modify the code of a legacy hosted search page, configuring a PipelineContext component as shown in the example above may not work.

In such a situation, configure your PipelineContext through the UI View rather than the Code View to ensure that the required character encoding is generated.

Setting custom context dynamically

If some, or all, of the custom context information you want to send may change dynamically (for example, based on actions taken by the end user), you can set it as needed by invoking the setContextValue or setContext methods on the initialized PipelineContext component instance. Custom context values set in this fashion can be strings or maps of strings.

The methods described in this section are available since the December 2017 release (v2.3679.4) of the JavaScript Search Framework. To set custom context dynamically with prior versions of the framework, you must use a buildingQuery event handler.

Consider the following search interface markup configuration:

<div id="search" class="CoveoSearchInterface">
  <!--  ...  -->
  <script class="CoveoPipelineContext" type="text/context"></script>
  <!--  ...  -->
</div>

Suppose the following functions are available to retrieve contextual information about the current end user:

/**
 * @returns {String}: The age group to which the current user belongs.
 * For example, "30-45"
 */
function getUserAgeGroup() { /* Implementation... */ }
 
/**
 * @returns {Map<String, String>}: The interests selected by the current user.
 * For example, { "0": "sports", "1": "camping", "2": "electronics" }
 */
function getUserInterests() { /* Implementation... */ }

You can use the setContextValue method of the PipelineContext component to include this contextual information in search requests and usage analytics events.

// ...
const root = Coveo.$$(document).find("#search");
// ...
Coveo.$$(root).on("afterInitialization", (e, args) => {
  let pipelineContext = Coveo.$$(root).find(".CoveoPipelineContext");
  pipelineContext = Coveo.get(pipelineContext);
  pipelineContext.setContextValue("ageGroup", getUserAgeGroup());
  pipelineContext.setContextValue("interests", getUserInterests());
})
// ...
Coveo.init(root);

Alternatively, you can use the setContext method to set multiple context key-values at once.

pipelineContext.setContext({
  "ageGroup": getUserAgeGroup(),
  "interests": getUserInterests()
});

To send the same custom context info along with click and custom events, use a changeAnalyticsCustomData event handler (see Modify the metadata to send with UA events).

<head>
  <script>
  // ...
  document.addEventListener("DOMContentLoaded", () => {
    function getUserAgeGroup() {
      // ...implementation...
    }
    function getUserInterests() {
      // ...implementation...
    }
    const root = document.getElementById('search');
    Coveo.$$(root).on("afterInitialization", (e, args) => {
      let pipelineContext = Coveo.$$(root).find(".CoveoPipelineContext");
      pipelineContext = Coveo.get(pipelineContext);
      pipelineContext.setContext({
        "ageGroup": getUserAgeGroup(),
        "interests": getUserInterests()
      });
    })
    Coveo.$$(root).on('changeAnalyticsCustomData', (e, args) => {
      if (args.type === 'ClickEvent' || args.type === 'CustomEvent'){
        args.metaObject.context_ageGroup = getUserAgeGroup();
        args.metaObject.context_interests = getUserInterests();
      }
    });
    Coveo.init(root);
    // ...
  });
  </script>
</head>

<body id="search" class="CoveoSearchInterface">
  <!-- ... -->
  <div class="CoveoAnalytics"></div>
  <script class="CoveoPipelineContext" type="text/context"></script>
  <!-- ... -->
</body>

To see an example of custom context being sent dynamically in the context of Salesforce, see:

Using a buildingQuery event handler

Since the December 2017 release (v2.3679.4) of the JavaScript Search Framework, we recommend that you use the PipelineContext component instead of a buildingQuery event handler to send custom context information.

You can use a buildingQuery event handler to dynamically set context information (see JavaScript Search Framework Events).

// ...
const root = Coveo.$$(document).find("#search");
// ...
Coveo.$$(root).on("buildingQuery", (e, args) => {
  args.queryBuilder.addContext({
    "ageGroup": "30-45",
    "interests": {
      "0": "sports",
      "1": "camping",
      "2": "electronics"
    }
  })
})
// ...
Coveo.init(root);

To send the same custom context info along with click and custom events, use a changeAnalyticsCustomData event handler (see Modify the metadata to send with UA events).

<head>
  <script>
  document.addEventListener("DOMContentLoaded", () => {
    // ...
    const root = document.getElementById('search');
    Coveo.$$(root).on("buildingQuery", (e, args) => {
      args.queryBuilder.addContext({
        "ageGroup": "30-45",
        "interests": {
          "0": "sports",
          "1": "camping",
          "2": "electronics"
        }
      });
    });
    Coveo.$$(root).on('changeAnalyticsCustomData', (e, args) => {
      if (args.type === 'ClickEvent' || args.type === 'CustomEvent'){
        args.metaObject.context_ageGroup = "30-45",
        args.metaObject.context_interests = {
          "0": "sports",
          "1": "camping",
          "2": "electronics"
        }
      }
    });
    Coveo.init(root);
    // ...
  });
  </script>
</head>

<body id="search" class="CoveoSearchInterface">
  <!--  ...  -->
  <div class="CoveoAnalytics"></div>
  <!--  ...  -->
</body>

In the samples above, the interests context is passed as an object that simulates an array.

To access a specific element within such an “array” in a query expression, you would pass something like $context.interests.1