--- title: Capture click events (Coveo UA) slug: n6mf0358 canonical_url: https://docs.coveo.com/en/n6mf0358/ collection: coveo-for-commerce source_format: adoc --- # Capture click events (Coveo UA) > **Important** > > We strongly recommend that all new Commerce implementations use the [Event Protocol](https://docs.coveo.com/en/o1n91230/) to log events. This article explains how to capture a [click event](https://docs.coveo.com/en/2064/) and send the information to Coveo along with the product information. ## When to capture a click event A click event should be captured when a [visitor](https://docs.coveo.com/en/nbub9475/) clicks a product rendered using Coveo. For example, results displayed on a search results page, [product listing page (PLP)](https://docs.coveo.com/en/m1sf3187/), a recommendations carousel, or a [search-as-you-type](https://docs.coveo.com/en/2068/) search box. Tracking click events is a requirement for [Coveo Machine Learning (Coveo ML)](https://docs.coveo.com/en/188/) and [Coveo Analytics reporting](https://docs.coveo.com/en/266/). ## Click events and attribution Coveo [attributes](https://docs.coveo.com/en/m7l98577/) transactions to [product discovery solutions](https://docs.coveo.com/en/o9cf0524/) by tracking [touchpoints](https://docs.coveo.com/en/o6ha0421/) along the user journey. In a Coveo-powered commerce implementation, click events are the main [touchpoints](https://docs.coveo.com/en/o6ha0421/) used for [attribution](https://docs.coveo.com/en/m7l98577/). Cart events don't count towards [attribution](https://docs.coveo.com/en/m7l98577/). If your commerce implementation lets users modify the cart directly from the search results page, [product listing pages (PLPs)](https://docs.coveo.com/en/m1sf3187/), or [recommendation slots](https://docs.coveo.com/en/o9b80563/), you must [send an additional click event](#send-an-additional-click-event) along with the cart event. This lets Coveo [attribute](https://docs.coveo.com/en/m7l98577/) transactions to the correct [solutions](https://docs.coveo.com/en/o9cf0524/). You must send click events to track [attribution](https://docs.coveo.com/en/m7l98577/) on the [Coveo for Commerce Advanced Reports](https://docs.coveo.com/en/lbtf7260/). For more information, see [Attribution at Coveo](https://docs.coveo.com/en/m1ae0440/). **Example** A user performs a query on a Coveo-powered commerce site. They click a product to open its [product detail page (PDP)](https://docs.coveo.com/en/n8ad7392/), but they don't make a purchase and navigate away from the site. Coveo tracks this [touchpoint](https://docs.coveo.com/en/o6ha0421/) as part of the user's journey. Later, they revisit the site and see the same product in a [recommendation slot](https://docs.coveo.com/en/o9b80563/). They click the product to open its [product detail page (PDP)](https://docs.coveo.com/en/n8ad7392/), creating another [touchpoint](https://docs.coveo.com/en/o6ha0421/) tracked by Coveo. This time, the user adds the product to their cart and completes the purchase. This product is [attributed](https://docs.coveo.com/en/m7l98577/) to the recommendation [solution](https://docs.coveo.com/en/o9cf0524/). ## Headless controllers and Atomic components [Headless](https://docs.coveo.com/en/headless/latest/) and [Atomic](https://docs.coveo.com/en/atomic/latest/) components facilitate the logging of click [events](https://docs.coveo.com/en/260/). [Atomic](https://docs.coveo.com/en/lcdf0264/) components automatically log click [events](https://docs.coveo.com/en/260/), while with [Headless](https://docs.coveo.com/en/lcdf0493/), specific controllers need to be used when constructing UI components. The following section provides guidance on the necessary configuration to ensure that click [events](https://docs.coveo.com/en/260/) are properly logged. > **Tip** > > * You can leverage [Atomic](https://docs.coveo.com/en/lcdf0264/) components to implement search and content recommendations functionality. > > * For PLPs and product recommendations, use [Headless](https://docs.coveo.com/en/lcdf0493/) for a more customized and comprehensive implementation. ### Send the appropriate `actionCause` Depending on the user context, the click [event](https://docs.coveo.com/en/260/) will have a corresponding [`actionCause`](https://docs.coveo.com/en/2064#actioncause-string) value. The `actionCause` is the identifier of the user action that triggered the [event](https://docs.coveo.com/en/260/). For example, when the user clicks a result from a search [query](https://docs.coveo.com/en/231/), the `actionCause` would be `documentOpen`, whereas when the user clicks a recommendation, the `actionCause` would be `recommendationOpen`. #### For Headless Let's take a look at some popular `actionCause` values that you may need to send when logging click [events](https://docs.coveo.com/en/260/): * [`documentOpen`](https://docs.coveo.com/en/2948#documentopen-documentview): You should use [`InteractiveResult`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Search.InteractiveResult.html) when implementing your result components, as it [automatically extracts relevant data from results items](https://docs.coveo.com/en/headless/latest/usage/headless-usage-analytics/headless-ep#log-events). * [`recommendationOpen`](https://docs.coveo.com/en/2948#recommendationopen): To send this [event](https://docs.coveo.com/en/260/), we suggest that you use the `logRecommendationOpen` action, found in the [Recommendation](https://docs.coveo.com/en/headless/latest/reference/interfaces/Recommendation.ClickAnalyticsActionCreators.html) engine. Refer to the [Headless project repository](https://github.com/coveo/ui-kit/blob/main/samples/headless/search-react/src/components/recommendation-list/recommendation-list.class.tsx) for an example of how to dispatch this action. #### For Atomic With [Atomic](https://docs.coveo.com/en/lcdf0264/) components, you don't need to specify the `actionCause`, as these components handle all of the necessary actions and [event](https://docs.coveo.com/en/260/) logging automatically, therefore simplifying your development process. ### Set the search hub Depending on the type of interface the event originates from, there are [naming conventions for the search hub value](https://docs.coveo.com/en/n89e0266#search-hub-naming-conventions) you need to follow. We recommend setting the search hub on Headless and Atomic to control how the queries are processed in the [Coveo Administration Console](https://docs.coveo.com/en/183/) (see [Query routing](https://docs.coveo.com/en/n89e0266#query-routing)). When configured, the frameworks will automatically send the value in search events in the `originLevel1` field. You can either configure the search hub in the [authentication method](https://docs.coveo.com/en/n89e0266#defining-the-search-hub-in-the-authentication), or set it at [interface level](https://docs.coveo.com/en/n89e0266#defining-the-search-hub-at-the-interface-level). #### For Headless Specify the value of the [search hub](https://docs.coveo.com/en/1342/) in the [`SearchConfigurationOptions`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Search.SearchConfigurationOptions.html) object when initializing your [Headless](https://docs.coveo.com/en/lcdf0493/) engine: ```javascript import { buildSearchEngine } from '@coveo/headless'; export const headlessEngine = buildSearchEngine({ configuration: { organizationId: '', accessToken: '' search: { searchHub: "", }, }, }); ``` #### For Atomic Specify the [search hub](https://docs.coveo.com/en/1342/) value as a property on the [`atomic-search-interface`](https://static.cloud.coveo.com/atomic/v3/storybook/index.html?path=/docs/atomic-search-interface\--docs) component: ```html ``` ### Query pipeline When the interface sends a query to your [Coveo organization](https://docs.coveo.com/en/185/), it goes through a specific [Coveo query pipeline](https://docs.coveo.com/en/180/) before reaching the index. This can be done by specifying a Search Hub and then using [condition based routing](https://docs.coveo.com/en/1666#condition-based-routing-recommended) in the Administration Console to target a specific pipeline. A query pipeline uses its rules to transform that query and apply specific features following a specific order of execution. While it's not necessary to specify the query pipeline, we recommend that you do, as it allows you to filter and segregate events when looking at usage analytics reports. ### Origin levels The `originLevel` feature provides valuable information about the origin of usage analytic events, similar to the Search Hub. Several fields are associated with the `originLevel` feature: * [`originLevel1`](https://docs.coveo.com/en/2064#originlevel1-string) (required): This field should match the value of the Search Hub. If you initialize Headless or Atomic with the SearchHub configuration, this field is automatically set. * [`originLevel2`](https://docs.coveo.com/en/2064#originlevel2-string) (recommended): This field lets you differentiate between different tabs within the search interface if multiple tabs are present. When using the [Tab](https://docs.coveo.com/en/headless/latest/reference/interfaces/Search.Tab.html) controller, Headless can automatically populate the `originLevel2` field with the ID specified during the initialization of your controller. ** For the "Search" interface without any tabs, you can send the value "default." ** For the "Listing" page, send the path name of the listing (for example, "my-products/shoes.") ** For "Recs," you can send the value "default." * [`originLevel3`](https://docs.coveo.com/en/2064#originlevel3-string) (recommended): This field represents the URL of the page that redirects the browser to the search interface. It helps you analyze the effectiveness of various entry points leading to the search experience. It's typically extracted from `document.referrer`. During engine initialization, you can set the values for the `originLevel` fields. However, if you need to dynamically modify these values, you have the flexibility to modify the usage analytics data sent to Coveo. You can do so by leveraging the `analyticsClientMiddleware` property of an `AnalyticsConfiguration` to hook into an analytics event payload before it's sent to Coveo. This can be done for both [Headless](https://docs.coveo.com/en/headless/latest/usage/headless-usage-analytics/headless-coveo-ua#modify-the-metadata-to-send-with-coveo-analytics-events) and [Atomic](https://docs.coveo.com/en/atomic/latest/usage/atomic-usage-analytics/atomic-coveo-ua#modify-the-metadata-to-send-with-coveo-analytics-events). ### Custom data Along with the regular [fields](https://docs.coveo.com/en/200/) added by [Headless](https://docs.coveo.com/en/lcdf0493/) and [Atomic](https://docs.coveo.com/en/lcdf0264/), [Coveo Analytics events](https://docs.coveo.com/en/260/) must contain a `[customData](https://docs.coveo.com/en/1341/)` JSON with additional [fields](https://docs.coveo.com/en/200/). While the library adds some [fields](https://docs.coveo.com/en/200/) to this `[customData](https://docs.coveo.com/en/1341/)` JSON, there are other [fields](https://docs.coveo.com/en/200/) that have to be manually added using the [Headless library](https://docs.coveo.com/en/lcdf0493/): > **Note** > > If you're using the [Atomic library](https://docs.coveo.com/en/lcdf0264/), you'll need to [access Headless through Atomic](https://docs.coveo.com/en/atomic/latest/usage/headless-through-atomic/). #### `customData.variant` and `customData.group` (recommended) The `group` represents the group ID of the clicked product and `variant` represents the variant ID of the clicked variant. To add this [metadata](https://docs.coveo.com/en/218/) to your analytics request, you can use the `analyticsClientMiddleware` property on your engine as follows: ```javascript const createSearchEngine = buildSearchEngine({ configuration: { organizationId: "barcagroupproductionkwvdy6lp", accessToken: "XXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", search: { pipeline: "Sports", searchHub: "MainSearch", }, analytics: { analyticsClientMiddleware: (eventType, payload) => { if (eventType === 'click') { <1> const matchingResult = createSearchEngine.state.search.results[payload.documentPosition - 1]; <2> payload = { ...payload, customData: { <3> ...payload.customData, group: matchingResult.ec_item_group_id, variant: matchingResult.variant_id, } }; } return payload; }, }, }, }); ``` Where: <1> Hook into the analytics payload and check to see if the [event](https://docs.coveo.com/en/260/) is a click. <2> Use the state of the engine to fetch the matching result for which the click [event](https://docs.coveo.com/en/260/) is sent. <3> Retrieve the group and variant ID from the matching result and concatenate it to the `[customData](https://docs.coveo.com/en/1341/)` payload of the [event](https://docs.coveo.com/en/260/). ### Language In Coveo Machine Learning (ML) models, [multilingual search and recommendations are supported](https://docs.coveo.com/en/1956#supported-languages-for-machine-learning-models), allowing you to deliver personalized and relevant content to users in different languages. To ensure accurate and effective language-based results, it's important to consider the language of the search query and align it with the language specified in the various usage analytics events. Headless and Atomic automatically set the language of usage analytics events to the language of the search query. The language is set to `en` by default; however, if your use case serves content in multiple languages, we recommend specifying the language by setting the value of the `locale` field when initializing your components. The [`locale`](https://docs.coveo.com/en/13#operation/searchUsingPost-locale) field is formed by combining the language and region values with a hyphen, like `en-US`, where `en` represents the language and `US` represents the region. > **Note** > > The value of the [`language`](https://docs.coveo.com/en/1502#language-string) field must be a two letter [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) code. #### Headless Specify the language by setting the value of the `locale` field in the [`SearchConfigurationOptions`](https://docs.coveo.com/en/headless/latest/reference/interfaces/Search.SearchConfigurationOptions.html) object when initializing your [Headless](https://docs.coveo.com/en/lcdf0493/) engine: ```javascript import { buildSearchEngine } from '@coveo/headless'; export const headlessEngine = buildSearchEngine({ configuration: { organizationId: '', accessToken: '' search: { locale: "", }, }, }); ``` #### Atomic Specify the language as a property on the [`atomic-search-interface`](https://static.cloud.coveo.com/atomic/v3/storybook/index.html?path=/docs/atomic-search-interface\--docs) component: ```html ``` ## Capture a click event using Coveo UA library commands Use either the [Headless](https://docs.coveo.com/en/lcdf0493/) or [Atomic](https://docs.coveo.com/en/lcdf0264/) libraries. These libraries are designed to facilitate the logging of click [events](https://docs.coveo.com/en/260/) and inclusion of appropriate [metadata](https://docs.coveo.com/en/218/), simplifying the [event](https://docs.coveo.com/en/260/) collection process. However, if you choose not to use these libraries or want to track clicks using a component that's not powered by Coveo, you can still log click [events](https://docs.coveo.com/en/260/) manually using the [Coveo Usage Analytics (Coveo UA) library](https://www.npmjs.com/package/coveo.analytics). The following is an example of the JavaScript code that uses the [Coveo Analytics](https://docs.coveo.com/en/182/) library to send a click [event](https://docs.coveo.com/en/260/): ```js coveoua('send', 'click', { <1> 'actionCause': 'documentOpen', 'anonymous': true, 'documentPosition': 1, 'documentTitle': 'BruBrown Bottle', 'documentUrl': 'https://sports.barca.group/pdp/SP03929_00009', 'originLevel1': 'MainSearch', 'originLevel2': 'default', 'originLevel3': 'http://localhost:3000/search', 'searchHub': 'MainSearch', 'searchQueryUid': '514970dd-7c76-429f-8e80-6ea2f957f303', <2> 'sourceName': 'demo-barca-sport', 'language': 'en' 'trackingId': 'Sports', <3> 'customData:' { 'contentIDKey': 'permanentid', 'contentIDValue': 'SP03929_00012', }, }); ``` <1> Send the click [event](https://docs.coveo.com/en/260/), [specifying the various required fields](#click-data-payload-requirements). <2> When a click [event](https://docs.coveo.com/en/260/) happens directly from a Coveo-powered search result page or listing page, you must specify the `searchUid` of the [query](https://docs.coveo.com/en/231/) that was responsible for showing this set of results. Otherwise, the [Coveo Platform](https://docs.coveo.com/en/186/) won't be able to attribute the potential transaction to the right service (that is, search or listing). You must pass this value in the [`searchQueryUid`](https://docs.coveo.com/en/2064#searchqueryuid-string) parameter of the click payload. For more information, refer to [Extract the searchUid](https://docs.coveo.com/en/l2jb0279/). <3> While this code snippet includes [`trackingId`](https://docs.coveo.com/en/l2bf0354#tracking-id) in the payload of the click [event](https://docs.coveo.com/en/260/), it's recommended to set it as a [global custom field](https://docs.coveo.com/en/l29e0540#global-custom-fields-reference) instead. This ensures that the [field](https://docs.coveo.com/en/200/) is available on all [events](https://docs.coveo.com/en/260/) emitted using the [Coveo Analytics](https://docs.coveo.com/en/182/) library, without duplicating it in each [event](https://docs.coveo.com/en/260/) payload. ### Click data payload requirements The following table lists the fields sent along with the event and the solutions that use these fields. _Search_, _Listings_, and _Recs_ columns refer to whether the ML that powers those solutions needs those data points. The _Reporting_ column is for general reporting purposes that encompasses all solutions. > **Important** > > If your [catalog data](https://docs.coveo.com/en/obcf0333/) contains group IDs or variants, you must include the [`customData.group` or `customData.variant`](#customdata-variant-and-customdata-group-recommended) fields so Coveo can track [attribution](#click-events-and-attribution). [%header,cols="2,2,4*"] |=== |Field |Priority |Search |Listings |Recs |Reporting |[`actionCause`](https://docs.coveo.com/en/2064#actioncause-string) |Required |[check] |[check] |[check] |[check] |[`anonymous`](https://docs.coveo.com/en/2064#anonymous-boolean) |Required |[check] |[check] |[check] |[check] |[`documentPosition`](https://docs.coveo.com/en/2064#documentposition-unsigned-integer) |Required |[check] |[check] |[check] |[check] |[`documentTitle`](https://docs.coveo.com/en/2064#documenttitle-string) |Required |[check] | | |[check] |[`documentUrl`](https://docs.coveo.com/en/2064#documenturl-string)[.footnote]^1^ |Required | | |[check] | |[`language`](https://docs.coveo.com/en/2064#language-string)[.footnote]^2^ |Required |[check] |[check] |[check] |[check] |[`trackingId`](https://docs.coveo.com/en/2064#trackingid-string) |Required |[check] |[check] |[check] |[check] |[`originLevel1`](https://docs.coveo.com/en/2064#originlevel1-string) |Required |[check] |[check] |[check] |[check] |[`originLevel2`](https://docs.coveo.com/en/2064#originlevel2-string) |Recommended |[check] |[check] | |[check] |[`originLevel3`](https://docs.coveo.com/en/2064#originlevel3-string) |Recommended |[check] |[check] | |[check] |[`searchQueryUid`](https://docs.coveo.com/en/2064#searchqueryuid-string)[.footnote]^3^ |Required |[check] |[check] |[check] |[check] |[`sourceName`](https://docs.coveo.com/en/2064#sourcename-string) |Required | | | |[check] |[`customData.contentIDKey`](https://docs.coveo.com/en/2064#contentidkey-string) |Required |[check] |[check] |[check] |[check] |[`customData.contentIDValue`](https://docs.coveo.com/en/2064#contentidvalue-string) |Required |[check] |[check] |[check] |[check] |[`customData.group`](https://docs.coveo.com/en/2064#click-event-customdata-key-value-pairs)[.footnote]^4^ |Required[.footnote]^*^ | | | |[check] |[`customData.variant`](https://docs.coveo.com/en/2064#click-event-customdata-key-value-pairs)[.footnote]^5^ |Required[.footnote]^*^ | | | |[check] |[`rankingModifier`](https://docs.coveo.com/en/2064#rankingmodifier-string)[.footnote]^6^ |Recommended | | | |[check] |=== -- *: These fields are only required if your [catalog data](https://docs.coveo.com/en/obcf0333/) contains [group IDs or variants](#customdata-variant-and-customdata-group-recommended). 1. The `documentUrl` field is used by ML for content recommendations, but not product recommendations. 2. Defaults to english. 3. Refer to [Extract the searchUid](https://docs.coveo.com/en/l2jb0279/). 4. This field is necessary when configuring ML models to provide recommendations at the group level. If this field is sent with one event, it must be included in all subsequent events. 5. If this field is sent with one event, it's also recommended that it's included in all subsequent events. 6. While this field isn't required for ML models to function, it's recommended to include it for better reporting. For example, it's used in the standard [usage analytics reports](https://docs.coveo.com/en/1674/) that assess the performance of ML models. -- Refer to [Log click events](https://docs.coveo.com/en/2064/) for more information and optional [fields](https://docs.coveo.com/en/200/). ## Click event validation To validate that a click [event](https://docs.coveo.com/en/260/) was sent, [use the developer tools for client-side request verification](https://docs.coveo.com/en/n8493503#use-developer-tools-for-client-side-request-verification) to inspect your visit to ensure that everything done using the UI is captured as a set of consistent and coherent [events](https://docs.coveo.com/en/260/). This must occur after the implementation is applied. Inspect the click [event](https://docs.coveo.com/en/260/) through the network browser and ensure that it satisfies the following: ![Barca click event network browser](https://docs.coveo.com/en/assets/images/coveo-for-commerce/images/3188_images/barca-click-event-validation-example.png) 1 Ensure that the `click` [event](https://docs.coveo.com/en/260/) is sent without error and that it's not sent twice. 2 Validate the [`actionCause`](https://docs.coveo.com/en/2064#actioncause-string) parameter of the event. The most common values are: [%header,cols="2"] |=== |Value |Description |`documentOpen` |When a user clicks any [item](https://docs.coveo.com/en/pa8f6515/) from a search results or product listings page, either right-click or left-clicks (user opens in a new [tab](https://docs.coveo.com/en/1406/)). |`recommendationOpen` |When a user clicks any [item](https://docs.coveo.com/en/pa8f6515/) in a recommendation interface. |`documentQuickview` |When a user previews a [query](https://docs.coveo.com/en/231/) result (Quickview). |=== The full list of standard `actionCause` values is available in the [Coveo JavaScript Search Framework](https://docs.coveo.com/en/187/) [source code](https://github.com/coveo/search-ui/blob/master/src/ui/Analytics/AnalyticsActionListMeta.ts#L321). 3 The [`anonymous`](https://docs.coveo.com/en/2064#anonymous-boolean) [field](https://docs.coveo.com/en/200/) is set to the correct value based on the implementation. The default value is `false`. 4 The `contentIDKey` is set to `permanentid`. 5 The `contentIDValue` matches the correct [`ec_product_id`](https://docs.coveo.com/en/n73f0502#define-a-unique-product-identifier). 6 The correct group ID is sent in the `group` [field](https://docs.coveo.com/en/200/) within the `[customData](https://docs.coveo.com/en/1341/)` object (if applicable). 7 The correct variant's unique identifier is sent in the `variant` [field](https://docs.coveo.com/en/200/) within the `[customData](https://docs.coveo.com/en/1341/)` object (if applicable). 8 The value of the `[originLevel1](https://docs.coveo.com/en/1337/)` field in the [Coveo Analytics](https://docs.coveo.com/en/182/) request matches the value of the [`searchHub`](https://docs.coveo.com/en/l29e0540#search-hub) from the corresponding Search API request [event](https://docs.coveo.com/en/260/), as seen below: ![Barca click event search API request](https://docs.coveo.com/en/assets/images/coveo-for-commerce/images/3188_images/barca-click-event-validation-searchapi-example-2.png) 9 The value of the `trackingId` [field](https://docs.coveo.com/en/200/) for the [Coveo Analytics](https://docs.coveo.com/en/182/) request is sending the right value assigned to that website and matches the value of the `website` [field](https://docs.coveo.com/en/200/) within the [context](https://docs.coveo.com/en/1345/) object of the Search API request [event](https://docs.coveo.com/en/260/) that took place before the click [event](https://docs.coveo.com/en/260/), as seen below: ![Barca click event search API request](https://docs.coveo.com/en/assets/images/coveo-for-commerce/images/3188_images/barca-click-event-validation-searchapi-example-1.png) For a complete list of parameters that can be sent in the [event](https://docs.coveo.com/en/260/), see [​Log click events](https://docs.coveo.com/en/2064/).