Guides / Getting insights and analytics / Connectors / Segment

Supported Events

The Algolia connector for Segment is currently in public beta, and handling e-commerce related events. Please reach out to us at contact@algolia.com if you want to track events we do not support (yet).

Product List Viewed

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

  • products.$.objectID : the objectID of the record. Maps to objectIDs 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
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product List Viewed', {
  products: [
    {
      objectID: '507f1f77bcf86cd799439011',  // Algolia specific, required
      // ...
    },
    {
      objectID: '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
29
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 => ({
      objectID: hit.objectID, // Extra parameters required by Algolia
      product_id: hit.product_id,
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: hit.__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 => ({
        objectID: 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 => ({
      product_id: hit.product_id,
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: hit.__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
search.addWidget(
  instantsearch.widgets.refinementList({
    container: "#refinement-list",
    attribute: "brand"
  })
);

document.querySelector("#refinement-list").addEventListener("click", event => {
  const elem = event.target;
  if (elem.matches("input[type=checkbox]") && elem.checked) {
    // This sends an event when a filter is checked.
    const payload = {
      filters: [
        {
          type: "brand",
          value: elem.value
        }
      ],
      index: "..."
    };
    analytics.track("Product List Filtered", payload);
  }
});

Product Clicked

Segment parameters used by Algolia

  • position : the absolute position of the record. Maps to positions in the Insights event payload. The position starts with 1 (not 0).

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.
  • objectID : the objectID of the record. Maps to objectIDs 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', {
  objectID: '507f1f77bcf86cd799439011',  // Algolia specific, required
  position: 3,
  index: "<YOUR_ALGOLIA_INDEX>",  // Algolia specific, required
  queryID: "<YOUR_QUERY_ID>",  // Algolia specific, required for Analytics, optional 
  // ...
});

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
27
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", {
    objectID: hit.objectID, // Extra parameters required by Algolia
    product_id: hit.product_id,
    sku: hit.objectID,
    category: hit.categories[0],
    name: hit.name,
    brand: hit.brand,
    variant: undefined,
    price: hit.price,
    quantity: 1,
    coupon: undefined,
    position: 1, // 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
38
39
40
41
search.addWidget(
  instantsearch.widgets.configure({
    clickAnalytics: true, // This must be `true` to get the `__queryID` in the search results.
    enablePersonalization: true,
  })
);
search.addWidget(
  instantsearch.widgets.hits({
    container: "#hits",
    templates: {
      item: hit => `
            <article>
              <h3>${instantsearch.highlight({ attribute: "name", hit })}</h3>
              <button class="btn-favorite" data-product-clicked-payload='${
                encodeURIComponent(
                  JSON.stringify({
                    objectID: hit.objectID,
                    position: hit.__position,

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

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

Product Added

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.
  • objectID : the objectID of the record. Maps to objectIDs 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
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product Added', {
  objectID: '507f1f77bcf86cd799439011',  // Algolia specific, required
  index: "<YOUR_ALGOLIA_INDEX>",  // Algolia specific, required
  queryID: "<YOUR_QUERY_ID>",  // Algolia specific, required for Analytics, optional 
  // ...
});

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

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

Product Viewed

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

  • objectID : the objectID of the record. Maps to objectIDs 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
analytics.identify('user-1'); // only if user is logged in

analytics.track('Product Viewed', {
  objectID: '507f1f77bcf86cd799439011',  // Algolia specific, required
  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 Viewed",
  "userToken": "user-1",
  "index": "<YOUR_ALGOLIA_INDEX>",
  "objectIDs": [ "507f1f77bcf86cd799439011" ]
}

Order Completed

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.
  • producs.$.objectID : the objectID of the record. Maps to objectIDs 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: [
    {
      objectID: '507f1f77bcf86cd799439011', // Algolia specific, required
      // ...
    },
    {
      objectID: '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
42
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: "cvssd800083888004771002",
    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 => ({
      objectID: hit.objectID, // Extra parameters required by Algolia
      product_id: hit.product_id,
      sku: hit.objectID,
      category: hit.categories[0],
      name: hit.name,
      brand: hit.brand,
      variant: undefined,
      price: hit.price,
      quantity: 1,
      coupon: undefined,
      position: hit.__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
15
16
search.addWidgets([
  instantsearch.widgets.hits({
    // ...
    templates: {
      item(hit) {
        // Pass the related data to the product page.
        // Then, in the product page, you can send events by using `analytics.track()`.
        return `
          <a href="/product.html?objectID=${hit.objectID}&queryID=${hit.__queryID}&index=my-index">
            <h2>${hit.name}</h2>
          </a>
        `;
      },
    },
  })
]);

</section>

Did you find this page helpful?