Concepts / Getting insights and analytics / Supported events

Supported Events

The Algolia connector for Segment is currently in private beta. It is not yet ready for production use. If you would like to be part of our beta test, please reach out to us.

Product List Viewed

Segment parameters used by Algolia

  • products.$.product_id : the objectID of the record. Maps to objectIDs in the Insights event payload.

Segment contextual parameters used by Algolia

  • userId: an identifier for logged-in users. Can be set through analytics.identify. Maps to userToken in the Insights event payload.

  • anonymousId: an identifier for non logged-in users. Maps to userToken in the Insights event payload when userId was not set through analytics.identify.

You can read more about Segments Identities.

Extra parameters required by Algolia

  • index: Name of the targeted index. Maps to index in the Insights event payload.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product List Viewed', {
  products: [
    {
      product_id: '507f1f77bcf86cd799439011',
      // ...
    },
    {
      product_id: '505bd76785ebb509fc183733',
      // ...
    }
  ],
  index: "<YOUR_ALGOLIA_INDEX>",  // Algolia specific, required
  // ...
});

This code sends the following payload to the Insights REST API:

1
2
3
4
5
6
7
{
  "eventType": "view",
  "eventName": "Product List Viewed",
  "userToken": "user-1",
  "index": "<YOUR_ALGOLIA_INDEX>",
  "objectIDs": [ "507f1f77bcf86cd799439011", "505bd76785ebb509fc183733" ]
}

We want to trigger the Product List Viewed event every time a user receives a new set of results.

To achieve this with InstantSearch, we combine a debounce function with the hits connector and send Product List Viewed every time new results are presented to the user.

Note that the browser library and the Node.js library from Segment have different interfaces.

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
index.search({ query: "my query", clickAnalytics: true }, (err, result) => {
  // Let's assume that `result.hits` are rendered
  // and our user has viewed the list.

  // ...

  // The following code will send an event to Segment
  // along with the information of the list.
  analytics.track("Product List Viewed", {
    list_id: undefined,
    category: undefined,
    products: result.hits.map((hit, position) => ({
      product_id: hit.objectID, // Segment parameters used by Algolia
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: position,
      url: undefined,
      image_url: hit.image
    })),
    index: indexName // Extra parameters required by Algolia
  });
});
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
function debounce(fn, delay) {
  let timerId;
  return function(...args) {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = setTimeout(() => {
      fn(...args);
      timerId = null;
    }, delay);
  };
}

search.addWidget(
  instantsearch.connectors.connectHits(
    // debouncing is optional
    debounce(({ hits }) => {
      const products = hits.map(hit => ({
        product_id: hit.objectID,
        // ...
      }));
      products.length > 0 &&
        analytics.track("Product List Viewed", {
          products
        });
    }, 500)
  )()
);

Product List Filtered

Segment parameters used by Algolia

  • filters.$.type: the facet name in the filter applied
  • filters.$.value: the facet value in the filter applied

filters map to filters in the Insights event payload.

Segment contextual parameters used by Algolia

  • userId: an identifier for logged-in users. Can be set through analytics.identify. Maps to userToken in the Insights event payload.

  • anonymousId: an identifier for non logged-in users. Maps to userToken in the Insights event payload when userId was not set through analytics.identify.

You can read more about Segments Identities.

Extra parameters required by Algolia

  • index: Name of the targeted index. Maps to index in the Insights event payload.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product List Filtered', {
  filters: [
    {
      type: 'department',
      value: 'beauty'
    },
    {
      type: 'price',
      value: 'under-$25'
    },
  ],
  index: '<YOUR_ALGOLIA_INDEX>', // Algolia specific, required
  // ...
});

This code sends the following payload to the Insights REST API:

1
2
3
4
5
6
7
{
  "eventType": "click",
  "eventName": "Product List Filtered",
  "userToken": "user-1",
  "index": "<YOUR_ALGOLIA_INDEX>",
  "filters": [ "department:beauty", "price:under-$25" ]
}

We want to trigger Product List Filtered every time a user has interacted with a refinement widget. For example: refinementList, rangeSlider (the full list of refinement widgets is available here).

To hook a Product List Filtered event trigger to an InstantSearch refinement widget, we recommend using their connector form. Here is an example using the refinementList.

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
index.search({ query: "my query", clickAnalytics: true }, (err, result) => {
  // Let's assume that `result.hits` are rendered
  // and our user has filtered the list.

  // And let's assume that `filters` contains what user filtered with.
  const filters = [
    {
      type: "brand",
      value: "..."
    }
  ];

  // The following code will send an event to Segment
  // along with the information of the list and the filters.
  analytics.track("Product List Filtered", {
    list_id: undefined,
    filters: filters, // Segment parameters used by Algolia
    products: result.hits.map((hit, position) => ({
      product_id: hit.objectID, // Segment parameters used by Algolia
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: position,
      url: undefined,
      image_url: hit.image
    })),
    index: indexName // Extra parameters required by Algolia
  });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
search.addWidget(
  instantsearch.widgets.refinementList({
    container: "#refinement-list",
    attribute: "brand"
  })
);

document.querySelector("#refinement-list").addEventListener("change", event => {
  const elem = event.target;
  if (elem.matches("input[type=checkbox]")) {
    const payload = {
      filters: [
        {
          type: "brand",
          value: elem.value
        }
      ],
      index: "..."
    };
    analytics.track("Product List Filtered", payload);
  }
});

Product Clicked

Segment parameters used by Algolia

  • product_id : the objectID of the record. Maps to objectIDs in the Insights event payload.
  • position : the absolute position of the record. Maps to positions in the Insights event payload.

Segment contextual parameters used by Algolia

  • userId: an identifier for logged-in users. Can be set through analytics.identify. Maps to userToken in the Insights event payload.

  • anonymousId: an identifier for non logged-in users. Maps to userToken in the Insights event payload when userId was not set through analytics.identify.

You can read more about Segments Identities.

Extra parameters required by Algolia

  • queryID: Required only for Click Analytics. Algolia queryID that can be found in the search response when using clickAnalytics. Maps to queryID in the Insights event payload.
  • index: Name of the targeted index. Maps to index in the Insights event payload.
1
2
3
4
5
6
7
8
9
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product Clicked', {
  product_id: '507f1f77bcf86cd799439011',
  position: 3,
  index: "<YOUR_ALGOLIA_INDEX>", 
  queryID: "<YOUR_QUERY_ID>",   
  // ...
});

This code sends the following payload to the Insights REST API:

1
2
3
4
5
6
7
8
9
{
  "eventType": "click",
  "eventName": "Product Clicked",
  "userToken": "user-1",
  "index": "<YOUR_ALGOLIA_INDEX>",
  "queryID": "<YOUR_QUERY_ID>",
  "objectIDs": [ "507f1f77bcf86cd799439011" ],
  "positions": [ 3 ]
}

objectID and queryID are both available for each hit exposed in the hits and infiniteHits widgets for InstantSearch.

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
index.search({ query: "my query", clickAnalytics: true }, (err, result) => {
  // Let's assume that `result.hits` are rendered
  // and our user has clicked the first item.

  // ...

  // The following code will send an event to Segment
  // along with the information of the first item.
  const hit = result.hits[0];
  analytics.track("Product Clicked", {
    product_id: hit.objectID, // Segment parameters used by Algolia
    sku: hit.objectID,
    category: hit.categories[0],
    name: hit.name,
    brand: hit.brand,
    variant: undefined,
    price: hit.price,
    quantity: 1,
    coupon: undefined,
    position: 0, // Segment parameters used by Algolia
    url: undefined,
    image_url: hit.image,
    index: indexName, // Extra parameters required by Algolia
    queryID: result.queryID // Extra parameters required by Algolia
  });
});
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
37
search.addWidget(
  instantsearch.widgets.hits({
    clickAnalytics: true,
    enablePersonalization: true,
  })
);
search.addWidget(
  instantsearch.widgets.hits({
    container: "#hits",
    templates: {
      item: hit => `
            <article>
              <h3>${instantsearch.highlight({ attribute: "name", hit })}</h3>
              <button class="btn-add-to-cart" data-product-clicked-payload='${JSON.stringify(
                {
                  product_id: hit.objectID,
                  position: hit.__position,

                  index: '...',
                  queryID: hit.__queryID
                }
              )}'>Add to cart</button>
            </article>
          `
    }
  })
);

document.addEventListener("click", event => {
  const elem = event.target;
  if (elem.matches(".btn-add-to-cart")) {
    const payload = JSON.parse(
      elem.getAttribute("data-product-clicked-payload")
    );
    analytics.track("Product Clicked", payload);
  }
});

Order Completed

Segment parameters used by Algolia

  • producs.$.product_id : the objectID of the record. Maps to objectIDs in the Insights event payload.

Segment contextual parameters used by Algolia

  • userId: an identifier for logged-in users. Can be set through analytics.identify. Maps to userToken in the Insights event payload.

  • anonymousId: an identifier for non logged-in users. Maps to userToken in the Insights event payload when userId was not set through analytics.identify.

You can read more about Segments Identities.

Extra parameters required by Algolia

  • queryID: Required only for Click Analytics. Algolia queryID that can be found in the search response when using clickAnalytics. Maps to queryID in the Insights event payload.
  • index: Name of the targeted index. Maps to index in the Insights event payload.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
analytics.identify('user-1'); // only if user is logged in

analytics.track('Order Completed', {
  products: [
    {
      product_id: '507f1f77bcf86cd799439011',
      // ...
    },
    {
      product_id: '505bd76785ebb509fc183733',
      // ...
    }
  ],
  index: '<YOUR_ALGOLIA_INDEX>', // Algolia specific, required
  queryID: "<YOUR_QUERY_ID>", // Algolia specific, required for Analytics, optional for Personalization
  // ...
});

This code sends the following payload to the Insights REST API:

1
2
3
4
5
6
7
{
  "eventType": "conversion",
  "eventName": "Order Completed",
  "userToken": "user-1",
  "index": "<YOUR_ALGOLIA_INDEX>",
  "objectIDs": [ "507f1f77bcf86cd799439011", "505bd76785ebb509fc183733" ]
}

Since Order Completed usually occurs outside the context of InstantSearch, you have to persist the objectID, queryID and index of the records ordered. This will allow Algolia to bind a conversion event to its specific query.

objectID and queryID are both available for each hit exposed in the hits and infiniteHits widgets for InstantSearch. For example if you need to pass them through the URL you can do the following:

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
37
38
39
40
41
index.search({ query: "my query", clickAnalytics: true }, (err, result) => {
  // Let's assume that `result.hits` are rendered,
  // user added the first two items to their cart,
  // and they completed the order.

  // ...

  // The following code will send an event to Segment
  // along with the information of the two items.
  const cartItems = [result.hits[0], result.hits[1]];

  analytics.track("Order Completed", {
    checkout_id: "fksdjfsdjfisjf9sdfjsd9f",
    order_id: "50314b8e9bcf000000000000",
    affiliation: "Google Store",
    total: 27.50,
    subtotal: 22.50,
    revenue: 25.00,
    shipping: 3,
    tax: 2,
    discount: 2.5,
    coupon: "hasbros",
    currency: "USD",
    products: cartItems.map((hit, position) => ({
      product_id: hit.objectID, // Segment parameters used by Algolia
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: position,
      url: undefined,
      image_url: hit.image
    })),
    index: indexName, // Extra parameters required by Algolia
    queryID: result.queryID // Extra parameters required by Algolia
  });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
search.addWidgets([
  instantsearch.widgets.hits({
    // ...
    templates: {
      item(hit) {
        return `
          <a href="/product.html?objectID=${hit.objectID}&queryID=${hit.__queryID}&index=my-index">
            <h2>${hit.name}</h2>
          </a>
        `;
      },
    },
  })
]);

</section>

Renaming Events

If you’re already sending events which names don’t respect the specification, you need to rename them for them to work with Algolia. If you can’t edit your code directly, you can do it in Segment.

In Segment, go to the destination settings and click Rename Events.

5 destination settings

There, you can set your current event names on the left column, and the new ones on the right.

6 rename events

Did you find this page helpful?