Log view events with Coveo UA

In this article

View events are a powerful way to understand how users interact with your Salesforce Experience Cloud site. By tracking page views, you unlock valuable insights into your users' journeys, content engagement, and site performance. These events fuel Coveo Usage Analytics and machine learning (ML) content recommendations models, helping optimize the search experience to deliver more relevant results to users.

This article explains how to log view events with the Coveo UA in a Salesforce Experience Cloud site using an example implementation. See the examplePageViewTracker folder for the full implementation example.

Send view events

The examplePageViewTracker component is designed to track user navigation and page views for analytics purposes. It’s an invisible Lightning Web Component (LWC) that you can drag onto your pages using the Salesforce Experience Builder. Once added, it listens for navigation changes within the site. On each page navigation, it determines the page type and emits a corresponding view event, including identifiers for the content on the page such as record IDs or URLs.

examplePageViewTracker component

Important

For reliable integration and compatibility with Salesforce Experience Cloud and Locker Service, use the examplePageViewTracker component and the build process provided in the Quantic repository. The Quantic build process applies a required transformation to the Coveo Usage Analytics library, so it works within Salesforce’s Locker Service environment. If you try to use the raw coveoua library from npm or GitHub, it won’t function correctly in Salesforce.

While advanced implementers can perform these transformations themselves, start from the Quantic project to save time, and avoid compatibility issues.

Note

Throughout this article, examplePageViewTracker refers to the sample implementation of a page view tracking Lightning Web Component. You can rename or adapt this component for your own Experience Cloud site as needed, but all references here use the example name for consistency.

The examplePageViewTracker LWC serves as a template for tracking page views within your Salesforce Experience Cloud site using Coveo UA. This section explains its structure, core logic, and extension points for customization.

JavaScript logic

The main functionality for the examplePageViewTracker component is declared in the examplePageViewTracker.js file.

It manages initialization, listens for navigation events, and emits page view events. This logic ensures seamless integration with Salesforce Experience Cloud navigation and supports multiple page types:

Page type Identifier key Identifier value Content type

Record page

@sfid

Salesforce record ID

Knowledge Article page

@sfid

Salesforce Knowledge Article version ID

Knowledge

Other pages

@clickableuri

Full page URL

The following code shows this logic with annotations to clarify each major segment:

import {LightningElement, wire} from 'lwc';
import {CurrentPageReference} from 'lightning/navigation';
import {loadScript} from 'lightning/platformResourceLoader';
import COVEO_UA from '@salesforce/resourceUrl/coveoua';
import getHeadlessConfiguration from '@salesforce/apex/HeadlessController.getHeadlessConfiguration';
import getArticleId from '@salesforce/apex/PageViewTrackerHelper.getArticleId';

export default class ExamplePageViewTracker extends LightningElement {
  coveoUAInitialized = false;
  _initializationPromises;

  @wire(CurrentPageReference)
  trackPageChange({attributes, state, type}) { 1
    this.loadAndInitializeLibrary();
    this._initializationPromises.then(() => {
      this.triggerPageView({attributes, state, type});
    });
  }

  connectedCallback() { 2
    this.loadAndInitializeLibrary();
  }

  loadAndInitializeLibrary() { 3
    if (!this._initializationPromises) {
      this._initializationPromises = Promise.all([
        loadScript(this, COVEO_UA + '/coveoua.js'),
        getHeadlessConfiguration(), 4
      ])
        .then(([, endpointData]) => this.initCoveoUA(endpointData))
        .catch((error) => {
          console.error('Error loading coveoua library', error);
        });
    }
  }

  initCoveoUA(endpointData) { 5
    const {organizationId, accessToken} = JSON.parse(endpointData);
    window['coveoua'](
      'init',
      accessToken,
      `https://${organizationId}.analytics.org.coveo.com/rest/ua`
    );
    this.coveoUAInitialized = true;
  }

  triggerPageView({attributes, state, type}) { 6
    switch (type) {
      case 'standard__recordPage':
        this.coveouaSendView({
          contentIdKey: '@sfid',
          contentIdValue: attributes.recordId,
        });
        break;
      case 'standard__knowledgeArticlePage':
        getArticleId({urlName: attributes?.urlName}) 7
          .then((id) => {
            if (id) {
              this.coveouaSendView({
                contentIdKey: '@sfid',
                contentIdValue: id,
                contentType: 'Knowledge',
              });
            }
          })
          .catch((err) => {
            console.warn('Error searching for knowledge article by UrlName', err);
          });
        break;
      default:
        this.coveouaSendView({
          contentIdKey: '@clickableuri',
          contentIdValue: window.location.href,
        });
        break;
    }
  }

  coveouaSendView({contentIdKey, contentIdValue, contentType = undefined, additionalContext = {}}) { 8
    if (this.coveoUAInitialized) {
      window['coveoua']('send', 'view', {
        contentIdKey,
        contentIdValue,
        ...(contentType && {contentType}),
        ...(additionalContext && {customData: {...additionalContext}}), 9
      });
    } else {
      console.warn('Coveo UA called before initialized.');
    }
  }
}
1 Watches for Salesforce Experience Cloud page navigation changes, triggering tracking logic when one occurs.
2 Ensures initialization begins as soon as the component is inserted into the DOM.
3 Loads the Coveo UA static resource and retrieves UA configuration from Apex.
4 getHeadlessConfiguration is an Apex method that fetches your Coveo Usage Analytics credentials and organization ID. This is required to initialize the UA library and send analytics events.
5 Initializes the Coveo UA library using credentials from your organization.
6 Determines the type of page, PageReferenceType, and sends the appropriate tracking event.
7 For Knowledge Articles the article ID will be fetched by the PageViewTrackerHelper class.
8 Sends a page view event to Coveo UA with IDs, types, and any custom context.
9 The additionalContext parameter is included for extensibility. While it’s not used in the default implementation, you can pass custom data to enrich your view events if needed.

Apex helper class

The examplePageViewTracker component requires an Apex helper class, PageViewTrackerHelper.cls, to retrieve Knowledge Article IDs by URL name. This helper class works behind the scenes to provide additional information for tracking, especially when the page navigation alone can’t supply all required analytics context. In the examplePageViewTracker, the helper resolves Salesforce Knowledge Article record IDs from URL names, which is necessary for accurate Coveo UA event reporting.

The following sample shows a typical implementation for resolving a Knowledge Article ID from its URL name:

public with sharing class PageViewTrackerHelper {
  @AuraEnabled(cacheable=true)
  public static Id getArticleId(String urlName) { 1
    if (String.isBlank(urlName)) {
      return null;
    }

    Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
    if (!gd.containsKey('Knowledge__kav')) {
      // Knowledge not enabled in this org → gracefully do nothing
      return null;
    }

    String soql =
      'SELECT Id ' +
      'FROM Knowledge__kav ' +
      'WHERE UrlName = :urlName ' +
      '  AND PublishStatus = \'Online\' ' +
      'ORDER BY LastPublishedDate DESC ' +
      'LIMIT 1';
    List<SObject> rows = Database.query(soql, AccessLevel.USER_MODE); 2
    return rows.isEmpty() ? null : (Id) rows[0].get('Id'); 3
  }
}
1 Declares the LWC enabled method for retrieving a Knowledge Article’s record ID by its URL name. This allows your LWC to call it directly.
2 Executes a SOQL query to find the most recently published Knowledge Article Version, in an Online status, with the given URL name using user-level access.
3 Returns the record ID of the first matching article, or null if none are found.

This class is designed for reliability and clarity, ensuring your tracking logic works across a variety of organization configurations and only returns valid IDs for published articles.

Template

The template for the component is defined in the examplePageViewTracker.html file. This template defines the component’s markup and determines how it appears on the page.

Important

Salesforce requires that a Lightning Web Component contains at least one element in its template. If the template is completely empty, the component won’t be rendered and its code won’t execute. To make certain the component is present for tracking purposes but remains invisible to users, the template includes a single hidden div.

<template>
  <div class="slds-hidden"></div> 1
</template>
1 The slds-hidden class is what enables the div to be invisible, allowing this component to be included solely for its tracking logic.

Metadata configuration

The metadata configuration file is defined as examplePageViewTracker.js-meta.xml in the example repository. It exposes the LWC to the Experience Builder and specifies which page types the component can be added to using the <targets> tag.

The <targets> section lists the supported page types for drag-based components in the Experience Builder. In this example, the component is available for both Community pages and the Community default template. Including both targets here ensures the component can be added to any relevant area in your Experience Cloud site.

See targets, for more details on configuration tags and available targets.

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>64.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
</LightningComponentBundle>

Build steps

After finalizing your component and metadata configuration, you don’t need to perform a manual local build for Salesforce components. Instead, the Quantic repository build process automatically prepares all necessary files and resources.

When you build the Quantic project, the required Coveo Usage Analytics static resource, coveoua, is generated and placed in the staticresources folder.

Important

The Quantic build process applies a transformation step to the Coveo Usage Analytics library code to verify compatibility with Salesforce static resources. Always use the version produced by the Quantic build.

Follow the Quantic build instructions to generate the correct static resource file before deploying to Salesforce.

Deploy and use the examplePageViewTracker component

With the build process complete, the next step is to deploy all dependencies to your Salesforce organization. This includes uploading the Lightning Web Component source files, the Apex helper class, and the Coveo UA analytics library as a static resource named coveoua. It’s critical to verify that permission sets allow users access to the Apex class and the static resource. Missing permissions can lead to silent failures in tracking and data collection.

See Permission Sets for more information.

Tip

Being cautious at this stage lays the groundwork for a robust and reliable analytics integration, ensuring that user navigation events are captured consistently across your Experience Cloud site.

Add the component to your Experience Cloud site pages

Once everything is deployed and permissions are set, you can add the examplePageViewTracker component to your Experience Cloud site pages using the Experience Builder.

Important

For most Salesforce Experience Cloud communities, especially those built as single-page applications (SPAs), it’s best to add the examplePageViewTracker component to the top of the global template. This ensures the component is loaded once and remains active, continuously tracking navigation events as users move between pages.

Open Experience Builder, navigate to the global template, and then drag the examplePageViewTracker component to the top of the page layout. Since this component is used for tracking-purposes only, it won’t affect the page layout or user experience.

Tip

For the most comprehensive analytics, include the tracker in your global template so it’s loaded for every major page type users may visit. This approach captures a full range of navigation events across your site, regardless of how your community handles navigation.