Integrations / Platforms / Shopify / Click and Conversion Analytics

Click and Conversion Analytics

The Algolia for Shopify plugin has out-of-the-box support for click analytics, and with some minor development effort, it’s possible to track conversions too.

Prerequisite

Your Algolia plan must include Click and Conversion Analytics to track these events in your Shopify store. Please refer to the pricing page for more details.

This guide assumes you use the default widgets the extension provides. If that’s not the case, you have to manually implement Click and Conversion Analytics.

Click analytics

To enable click analytics, all you have to do is tick the “Use click analytics” checkbox found in the Settings tab of your Shopify admin, and click “Save”.

The Analytics section in the Shopify admin

With this enabled, the code within your algolia_instant_search.js.liquid and algolia_autocomplete.js.liquid files will send click events whenever a product is clicked from the search results and the autocomplete.

Conversion analytics

To start tracking conversions, please make sure to:

  1. Enable Click Analytics.
  2. Uncomment calls to the saveForConversionTracking method in your algolia_instant_search.js.liquid and algolia_autocomplete.js.liquid files.
  3. Add the following to the algolia_analytics.js.liquid file to send a conversion event when a user clicks on the ‘add to cart’ button:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * Try to get the details from local storage for conversion tracking.
 * We're using a try...catch here to handle any possible exceptions resulting
 * from local storage or JSON parsing.
 */
function trackConversion() {
  try {
    // Get any previously stored data.
    const previousClickItemsString = localStorage.getItem(localStorageKey)
    // If data was found, send a conversion event for those products.
    if (!!previousClickItemsString) {
      const previousClickItems = JSON.parse(previousClickItemsString)
      previousClickItems.forEach((data) => {
        aa('convertedObjectIDsAfterSearch', data)
      })
    }
  } catch (error) {
    // No need to do anything in this scenario.
  }

  // Try to remove the items from local storage.
  try {
    localStorage.removeItem(localStorageKey)
  } catch (error) {
    // No need to do anything in this scenario.
  }
}

// Track a conversion event when clicking the 'add to cart' button.
// Change the query selector to be the correct one for your theme.
const addToCartBtn = document.querySelector('YOUR_ADD_TO_CART_SELECTOR')
if (addToCartBtn) {
  addToCartBtn.addEventListener('click', function (e) {
    trackConversion()
  })
}

You must replace YOUR_ADD_TO_CART_SELECTOR in the script with the relevant CSS selector for your ‘add to cart’ button.

Personalization

To leverage the Personalization features, you need to link events to your users. Update your Algolia-enabled theme:

In the theme.liquid file, change the way the search-insights script is added to the site.

First, remove the inclusion of the search-insights JavaScript file:

1
- <script src="https://cdn.jsdelivr.net/npm/search-insights@1.6.3/dist/search-insights.min.js" integrity="sha256-8r3eU2ketKjC+f59eAY6ejwSsgPjNY5Ca1yt67nz2TM=" crossorigin="anonymous"></script>

Then, add the following script after all the other Algolia scripts have been added and before the </head>:

1
2
3
4
5
6
7
8
<script>
  var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@2.0.3";

  !function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e[s]=e[s]||function(){
  (e[s].queue=e[s].queue||[]).push(arguments)},i=a.createElement(t),c=a.getElementsByTagName(t)[0],
  i.async=1,i.src=n,c.parentNode.insertBefore(i,c)
  }(window,document,"script",ALGOLIA_INSIGHTS_SRC,"aa");
</script>

Edit the algolia_externals.js file:

1
2
3
4
  autocomplete: window.autocomplete,
-  aa: window.AlgoliaAnalytics.default,

  // Export the required widgets

Edit the algolia_analytics.js.liquid file and make the following changes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  'use strict';
-  var aa = algolia.externals.aa;

  var enabled = algolia.config.analytics_enabled;
  if (!enabled) return;

-  aa.init({
-    appId: algolia.config.app_id,
-    apiKey: algolia.config.search_api_key,
-  });
+  window.aa('init', {
+    appId: algolia.config.app_id,
+    apiKey: algolia.config.search_api_key,
+  });
+
+  // Uncomment the following line and replace `yourUniqueUserToken` with a unique userToken to link events to a user.
+  //window.aa('setUserToken', 'yourUniqueUserToken');

Uncomment the call to window.aa('setUserToken') and pass it your user’s unique token to do so.

If you track conversion events, update the algolia_analytics.js.liquid file:

1
2
3
4
5
6
7
      if (!!previousClickItemsString) {
        const previousClickItems = JSON.parse(previousClickItemsString);
        previousClickItems.forEach(data => {
-          aa('convertedObjectIDsAfterSearch', data);
+          window.aa('convertedObjectIDsAfterSearch', data);
        });
      }

If you added your own tracking of conversion events, you need to update your code:

1
2
-    aa('convertedObjectIDsAfterSearch', data);
+    window.aa('convertedObjectIDsAfterSearch', data);

You must replace data with the relevant variable or JSON object of data used in this conversion event.

Edit the algolia_instant_search.js.liquid file:

1
2
3
4
5
6
7
  var connectRatingMenu =
    algolia.externals.connectors.connectRatingMenu;
-  var aa = algolia.externals.aa;

  var collectionPageEnabled =
    algolia.is_collection_results_page &&
    algolia.config.instant_search_enabled_on_collection;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    var clickData = {
      index: hit.dataset.algoliaIndex,
      eventName: 'click',
      queryID: hit.dataset.algoliaQueryid,
      objectIDs: [hit.dataset.algoliaObjectid],
      positions: [Number(hit.dataset.algoliaPosition)],
    };
    // Send the click event
-    aa.clickedObjectIDsAfterSearch(clickData);
+    window.aa('clickedObjectIDsAfterSearch', clickData);
    /**
     * Uncomment the following function call to start storing data in
     * local storage for conversion tracking
     */

Edit the algolia_autocomplete.js.liquid file:

1
2
3
  var autocomplete = algolia.externals.autocomplete;
-  var aa = algolia.externals.aa;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  var clickData = {
    index: datum._index,
    eventName: 'click',
    queryID: datum._queryID,
    objectIDs: [datum.objectID],
    positions: [datum._position],
  };

  // Send the click event
-  aa.clickedObjectIDsAfterSearch(clickData);
+  window.aa('clickedObjectIDsAfterSearch', clickData);
  /**
   * Uncomment the following function call to start storing data in
   * local storage for conversion tracking
   */

Widget updates

The latest versions of our widgets include the code that’s required to support conversion tracking. More specifically, the algolia_analytics.js.liquid now contains the following method:

  • saveForConversionTracking This method saves details in localStorage about objects that were clicked from the search results.

The algolia_instant_search.js.liquid and algolia_autocomplete.js.liquid have been updated to include calls to saveForConversionTracking, but these are commented out by default. To enable conversion tracking, you have to uncomment these lines for your store.

algolia_analytics.js.liquid

The algolia_analytics.js.liquid file contains the following updates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@@ -9,4 +9,68 @@
     appId: algolia.config.app_id,
     apiKey: algolia.config.search_api_key,
   });
+
+  const localStorageKey = 'algolia_analytics_clicked_objects';
+
+  /**
+   * Saves details in local storage for conversion tracking
+   */
+  algolia.saveForConversionTracking = function (data) {
+    /**
+     * We're using a try, catch here to handle any possible exceptions
+     * resulting from local storage or JSON parsing.
+     */
+    try {
+      // Get any data previously stored
+      const previousClickItemsString = localStorage.getItem(localStorageKey) || '[]';
+      const previousClickItems = JSON.parse(previousClickItemsString);
+
+      var conversionData = data;
+
+      // Changing the event to 'convert' from 'click'
+      conversionData.eventName = 'convert';
+      // Removing the `positions` property
+      delete conversionData.positions;
+
+      // Add the current products data to local storage
+      previousClickItems.push(conversionData)
+      localStorage.setItem(localStorageKey, JSON.stringify(previousClickItems))
+    } catch (error) {
+      // No need to do anything in this scenario
+    }
+  };
 })(window.algoliaShopify);

algolia_autocomplete.js.liquid

The algolia_autocomplete.js.liquid file contains the following updates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@@ -280,13 +280,21 @@
   // Event listeners
   autocompleteInstance.on('autocomplete:selected', function(obj, datum, name) {
     if (algolia.config.analytics_enabled) {
-      aa.clickedObjectIDsAfterSearch({
+      var clickData = {
         index: datum._index,
         eventName: 'click',
         queryID: datum._queryID,
         objectIDs: [datum.objectID],
         positions: [datum._position],
-      });
+      };
+
+      // Send the click event
+      aa.clickedObjectIDsAfterSearch(clickData);
+      /**
+       * Uncomment the following function call to start storing data in
+       * local storage for conversion tracking
+       */
+      // algolia.saveForConversionTracking(clickData);
     }
     switch (name) {
       case 'products': {

algolia_instant_search.js.liquid

The algolia_instant_search.js.liquid file contains the following updates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@@ -617,13 +617,21 @@
             link += '?variant=' + variant_id;
           }
           if (algolia.config.analytics_enabled) {
-            aa.clickedObjectIDsAfterSearch({
+            var clickData = {
               index: hit.dataset.algoliaIndex,
               eventName: 'click',
               queryID: hit.dataset.algoliaQueryid,
               objectIDs: [hit.dataset.algoliaObjectid],
               positions: [Number(hit.dataset.algoliaPosition)],
-            });
+            };
+
+            // Send the click event
+            aa.clickedObjectIDsAfterSearch(clickData);
+            /**
+             * Uncomment the following function call to start storing data in
+             * local storage for conversion tracking
+             */
+            // algolia.saveForConversionTracking(clickData);
           }
           window.location.href = link;
         });
Did you find this page helpful?