JavaScript Search Framework Tutorial 6: Usage Analytics

Coveo Usage Analytics (Coveo UA) is a very important part of any Coveo implementation. Without it, a large part of the Coveo technology stack can’t function properly.

For example, the Coveo Machine Learning (Coveo ML) service won’t be able to work correctly if it can’t access the usage analytics data about your search page (see Coveo Machine Learning).

In this tutorial, you’ll learn more about the Analytics component and its options. You’ll also learn how to log analytics events programmatically and modify standard analytics events.

  • For more detailed information on Coveo UA, see Analyze Data and Usage Analytics Concepts.

  • If you significantly modified the ./bin/index.html page in previous tutorials, you can undo these changes by rebuilding the project. To do so, run the following command line from the root of the tutorial project folder:

npm run build

The Analytics Component

To allow your search page to log usage analytics events, you need to insert an Analytics component in your search interface as shown in the following code excerpt:

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

If your Coveo organization is in the HIPAA environment, set the endpoint option of your Analytics component to

<div class="CoveoAnalytics" data-endpoint=""></div>

The Analytics component can be inserted anywhere inside the search interface. It doesn’t provide any visual aspect to your search page. Therefore, moving it around will have no impact on the rendering of your search interface.

After it has been added, the Analytics component will take care of logging all search and click events triggered by basic components.

It’s important to note that the Analytics component doesn’t decide which event data or metadata needs to be logged. Each component will individually do an explicit call to the Analytics component to signal its need to log an event.

About the searchHub Option

The searchHub option is a very important parameter which is used to determine from what page the analytics events originated.

This parameter is essential to many concepts, such as the query pipeline (see What’s a Query Pipeline?).

There are two ways to specify the searchHub:

  • Client side, by setting the data-search-hub option on the CoveoAnalytics component in the markup.

    This means the property isn’t “enforced”, but rather set client side with JavaScript code. You can still use the property to create conditions in query pipelines, but you shouldn’t use it for features that require the searchHub to be set securely (such as providing query suggestions based on the searchHub).

  • Enforced by the search token (see Search Token Authentication).

    This is more complicated to setup, but is much more secure. This is discussed in JavaScript Search Framework Tutorial 8: Configure Your Own Search Endpoint).

Whenever possible, you should use a searchHub enforced by the search token.

In some scenarios, for example when inside the Coveo for Salesforce application, the Analytics component is properly configured out of the box with a valid searchHub enforced in the token.

You should refer to your specific Coveo product documentation for more specific information.

Troubleshooting Analytics Requests

The following steps detail the requests and responses of a very basic search event when the Analytics component present in a search page.

You can actively follow these steps by inspecting the requests and responses from your web browser.

  1. Make sure there’s an Analytics component in your page. It can be placed anywhere inside the search interface.

  2. Type something in the search box, then send the request.

  3. You should see that your browser sends an OPTIONS request to

    This is called a CORS preflight request (see HTTP access control (CORS)).

    Very simply speaking, the browser is making sure that the back-end service supports CORS correctly.

  4. You should then see that your browser sends a POST request to

    Here is the important information you should look for in that request:

    1. Authorization header

      This will normally use the same search token or API key that you used to perform the query, unless you specified a different one in the Analytics component.

    2. Visitor query string parameter

      This is an ID that the UI retrieves from your cookies to track a single visit.

      The first time someone visits a Coveo-powered search page in which the Analytics component is enabled, the ID of this visitor will be sent from Coveo UA and stored in your cookie.

      Each event belonging to the same visit will send the same visitor ID.

    3. The request payload

      This is the body of the request. It’s different for each event type. Feel free to investigate the data that the framework sends to Coveo UA.

      The actionType and actionCauseparameters specify which component triggered the event.

      The customData parameter is a simple key-value pair which can be used to create customized dashboards and reports in Coveo UA.

      The originLevel1, originLevel2, and originLevel3 parameters should specify where the event was triggered from.

      originLevel1should be a general name for your search interface (e.g., the location of the search page or a string that describes the purpose of the page). If not set, it will fallback to "default".

      originLevel2 will try to match the current Tab component, if available. If not set, it will fallback to an empty string.

      originLevel3 is set to the document.referrer value.

  5. You should then see a response from

    1. If the request was successful, you should see a 200 OK response with the content being a JSON containing the visitor ID and query ID.

    2. If the request was not successful, you should inspect the response content. It will normally be a detailed response describing what the problem is. Usually, this will be a privilege related error. Concretely, this means that if you used an API key to log a search event, you need to make sure that this API key has the privilege to push analytics data (i.e., the Push access level on the Analytics data domain) (see Manage Privileges and Analytics Data Domain).

Log Search Events Programmatically

All out of the box components take care of logging their own events in Coveo UA. However, it’s important that your implementation takes care of logging search events correctly, since you can create your own components and execute queries using JavaScript code (see JavaScript Search Framework Tutorial 2: Interact With the Search Interface and Component Instances). Logging search events correctly can be done with the logSearchEvent function.

Consider the following code:

  <script class="coveo-script" src=""></script>
    document.addEventListener("DOMContentLoaded", () => {
      const root = document.getElementById("search");
<body id="search" class="CoveoSearchInterface" data-auto-trigger-query="false">
  <div class="CoveoAnalytics"></div>

The script would produce a warning such as:

This is because a search was triggered without any related search event while the Analytics component was active on the page.

To log a search event correctly, you would need to modify the script like this:

const eventCause = { name: "searchEventName", type: "searchEventType" };
const metadata = { key1: "value1", key2: "value2" };
Coveo.logSearchEvent(root, eventCause, metadata);

Q: Is it necessary to make the logSearchEvent call before the executeQuery call?

A: Yes, because it allows the Analytics component to queue the search event and wait for the query to successfully complete before sending the event.

If you were to only call logSearchEvent without any query, you wouldn’t see the search event being sent from the browser.

Q: What’s the customEventCause parameter ?

A: This parameter accepts a JSON with the following two properties: name and type.

Both of these properties can be set to any arbitrary string value. However, you should respect the following guidelines:

  • The name property should uniquely identify the precise action that caused the search event to be triggered.

  • The type property should describe the general category of the event. This value can be used by more than one event or component.

The basic Searchbox component can log the following search events:

  • The user “submits” the query by pressing Enter: {name: "searchboxSubmit", type: "search box"}

  • The user “clears” the query by pressing the clear button in the Searchbox component: {name: "searchboxClear", type: "search box"}

  • The search-as-you-type feature is used to trigger queries: {name: "searchboxAsYouType", type: "search box"}

It’s not useful to memorize the individual name and type values logged by each out of the box component. However, it’s important to understand that the name value should uniquely identify the action itself whereas the type value should be a general concept for a given component.

If you were to implement a calendar component which would trigger queries, you could log search events with customEventCause parameters such as these:

  • The user clicks on a day in the calendar: {name: "selectDay", type: "calendar"}

  • The user clicks on the next month button: {name: "nextMonth", type: "calendar"}

Q: What’s the metaData parameter?

A: This parameter can be used to send any arbitrary data to the Coveo Analytics service to create custom dimensions (see Manage Dimensions on Custom Data).

The metaData parameter needs to be a key-value pair, with the value being a string containing no more than 255 characters.

This parameter is optional. If you don’t want to log any metadata, you can pass an empty JSON: {}.

Logging Click Events Programmatically

Click events can be associated to any action resulting in the end user viewing an item, such as a ResultLink click or a Quickview click.

Logging click events can be done using the logClickEvent function as shown in the following code excerpt:

const eventCause = { name: "clickEventName", type: "clickEventType" };
const metadata = { key1: "value1", key2: "value2" };
const result = getTheResult();
Coveo.logClickEvent(root, eventCause, metadata, result)

Q: How can I get the result?

A: The result can be retrieved in many ways. One way is to use the querySuccess event (see JavaScript Search Framework Tutorial 3: Understanding the Event System).

Most of the time, a function that needs to log a click event will be executed inside the scope of a result template. The result object is always available inside a result template (see JavaScript Search Framework Tutorial 5: Result Templates).

Logging Search-As-You-Type Events Programmatically

Logging search-as-you-type events follows the exact same logic as logging normal search events, with the exception that those types of event are handled with a bit of extra logic.

Search-as-you-type events will wait until one of the following conditions is met before logging the actual event after it has been queued up:

  • Five seconds have passed since the search-as-you-type event was queued up.

    If a new search-as-you-type event is queued up, the countdown is reset. Only the last search-as-you-type event queued up in this manner will be logged.

  • Another search event which isn’t a search-as-you-type event is queued up.

    For example, a facet value is selected. In that case, the search-as-you-type event is logged, followed by the standard search event.

This is done to avoid logging many partial queries. Only the last “valid” query will be logged.

Search-as-you-type events can be logged programmatically using the logSearchAsYouTypeEvent function as shown in the following code excerpt:

const eventCause = { name: "searchAsYouTypeEventName", type: "searchAsYouTypeEventType" };
const metadata = { key1: "value1", key2: "value2" };
Coveo.logSearchAsYouTypeEvent(root, eventCause, metadata);

Logging Custom Events Programmatically

A custom event can be any event that doesn’t trigger a search and doesn’t result in the end user viewing an item.

For example, a Case Deflection form powered by Coveo search could log a custom event when a Cancel or Submit button is pressed.

Custom events can be logged programmatically using the logCustomEvent function as shown in the following code excerpt:

const eventCause = { name: "customEventName", type: "customEventType" };
const metadata = { key1: "value1", key2: "value2" };
Coveo.logCustomEvent(root, eventCause, metadata);

Modifying Standard Analytics Events

Sometimes, it can be useful to tweak and modify the standard usage analytics events logged by the Coveo JavaScript Search Framework.

For example, you could want to add the end-user profile name to all usage analytics events for a given implementation.

You can do so by using adding a changeAnalyticsCustomData event handler as shown in the following code excerpt:

document.addEventListener("DOMContentLoaded", () => {
  // ...
  const root = document.getElementById("search");
  Coveo.$$(root).on("changeAnalyticsCustomData", (e, args) => {
    // See
    args.originLevel1 = "myOriginLevel1";
    args.metaObject["foo"] = "bar";
  // ...

Other Useful Reference Documentation

What’s Next?

You should now proceed to JavaScript Search Framework Tutorial 7: Interact With Component States.

Recommended Articles