Guides / Building Search UI / Going further

If you’re using InstantSearch and want to send Insights events, it’s best to do so directly from your InstantSearch.js implementation. This guide describes how to send click, conversion, and view events with InstantSearch.js.

Algolia uses valid search-related events for Click and Conversion Analytics. Click and Conversion Analytics form the foundation for more advanced features like A/B Testing and Dynamic Re-Ranking. Algolia uses all valid events for Personalization. Even if you aren’t planning on implementing Personalization right away, it’s helpful to consider sending events as if you were. This lets you implement Personalization later on with a robust corpus of well-formatted user data.

To learn more about why you would want to send events and which events Algolia uses for which features, please read the guide on capturing user behaviors as events. To make sure you’re following InstantSearch best practices, please read the Getting Started guide before sending events.

Requirements

Installing the search-insights library

To send events in InstantSearch, you must first add the search-insights library to your application.

You can load the search-insights library either via the jsDelivr CDN or from your own static file server. If you choose the latter, you have to update the ALGOLIA_INSIGHTS_SRC variable to point to the file URL on your file server.

You can load the library by adding this snippet in the <head> of your HTML file.

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

  !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>

jsDelivr is a third-party CDN. We are not able to provide support regarding third party services.

Using insights with Node.js

Since version 1.3.0, you can use search-insights with NodeJS.

With NPM:

$
npm install search-insights

with Yarn:

$
yarn add search-insights

You can now use require or import to import the package in your code.

1
2
3
4
5
const aa = require('search-insights');
// or
import aa from 'search-insights';

// The rest is the same.

Creating the insights middleware

1
2
3
4
5
6
7
8
9
10
11
12
13
const insightsMiddleware = instantsearch.middlewares.createInsightsMiddleware({
  insightsClient: window.aa,
});

// or

import {
  createInsightsMiddleware,
} from 'instantsearch.js/es/middlewares';

const insightsMiddleware = createInsightsMiddleware({
  insightsClient: aa,
});

Connecting InstantSearch with the insights middleware

1
2
3
4
5
6
const search = instantsearch({
  searchClient,
  indexName: 'INDEX_NAME',
});

search.use(insightsMiddleware);

When sending a search-related event to Algolia, you need to include the queryID of the most recent search.

By default, the search response doesn’t contain a queryID. To retrieve it, you need to set the clickAnalytics parameter to true. The insights middleware handles this for you.

Setting the userToken

By default, search-insights library sets an anonymous token and stores it in a cookie. It’s best to set the userToken yourself using an internal user identifier. This lets you reliably identify users.

If you use search-insights >= 2.0.0, it doesn’t set anonymous token automatically and no longer uses cookies by default. If you want to enable it, refer to the insightsInitParams.

1
aa('setUserToken', yourUserToken);

If you don’t have access to that information right away, you can set it later from your code. As soon as you’ve set it, the insights middleware ensures that every subsequent search includes a userToken.

Sending default events

When using any of the following connectors, the insights middleware automatically sends default for some user behaviors like selecting a facet or viewing a result.

Sending events from refinement widgets

If you customize a widget using connectors, the insights middleware also sends events. You can turn off this behavior or change the default payload.

Sending events from results widgets

When using any of the following connectors, the insights middleware automatically sends default view events when hits are rendered.

If you customize a widget using connectors, the insights middleware also sends events. You can turn off this behavior or change the default payload.

The hits and infiniteHits widgets also expose a bindEvent function, so that you can hook user behavior to custom click or conversion events at the template level.

Sending events

Usually, you want to send events when the user interacts with search results. This means you want to send the events from either the hits or the infiniteHits widget.

This example sets up the hits widget:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
search.addWidget(
  instantsearch.widgets.hits({
    container: '#hits',
    templates: {
      item(hit, bindEvent) {
        return `
            <article>
              <h3> ${instantsearch.highlight({ attribute: 'name', hit })} </h3>
            </article>
          `;
      }
    }
  })
);

Now for the payoff: sending the event.

The item template exposes a bindEvent function which returns a data attribute on clickable items.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<button
  type="button"
  ${bindEvent('click', hit, 'Product Added')}
>
  Add to cart
  <!-- this button will send a click event when user clicks -->
</button>

<button
  type="button"
  ${bindEvent('conversion', hit, 'Product Ordered')}
>
  Order
  <!-- this button will send a conversion event when user clicks -->
</button>

Insights events (view, click, and conversion) don’t take immediate effect. The delay can range from a few minutes to an hour, depending on whether they are sent after a search or not, and how long after a search they are sent. For precise timeframes, see our page on when Insights events take effect.

Based on the event type you send, you need different data. For example, a conversion event doesn’t need the positions attribute, but the click event does. This is because positions determines the average click position. The integration with InstantSearch handles all this for you: InstantSearch injects all the necessary data based on the event to send and the context of the current query.

If you’re sending these events with the Personalization feature in mind, it’s important to first decide which events to send, and when to send them. Please read the guide on capturing user actions as events if you’re unsure about what events to send.

Conversion events don’t always happen on a search results page. For example, a user could buy an item from a product detail page. That means you need to pass the queryID to the detail page. The keeping track of queryID guide shows how to use query parameters to track the queryID.

Putting everything together

Here’s a full code snippet for sending click and conversion events from within a hits widget.

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
search.addWidget(
  instantsearch.widgets.hits({
    container: '#hits',
    templates: {
      item(hit, bindEvent) {
        return `
            <article>
              <h3>
                ${instantsearch.highlight({ attribute: 'name', hit })}
              </h3>

              <button
                type="button"
                ${bindEvent('click', hit, 'Product Added')}
              >
                Add to cart
              </button>
              
              <button
                type="button"
                ${bindEvent('conversion', hit, 'Product Ordered')}
              >
                Order
              </button>
            <article>
          `;
      }
    }
  })
);

Advanced insights middle customizations

The insights middleware lets you turn off default events, change the default event payloads, send events from your own custom widgets, and send events to third-party trackers. Please check the insights middleware documentation to learn how to do so.

Did you find this page helpful?