UI libraries / Autocomplete / Guides

Sending Algolia Insights events

With Autocomplete, you can automatically send click and view events with the insights parameter.

Sending events lets Algolia recommend products, adjust the ranking dynamically (Dynamic Re-Ranking and Personalization), and lets you get better insights with Analytics and A/B Testing.

You can see a complete implementation in the Autocomplete playground.

Before you begin

Before you can send events, you need to add the Autocomplete library to your project. For more information, see Getting started with Autocomplete.

Create an Autocomplete instance

Get started by creating a new file index.js. Add the following code to create an Autocomplete instance that includes results from an Algolia index and Query Suggestions.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { h, Fragment } from 'preact';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
import { createQuerySuggestionsPlugin } from '@algolia/autocomplete-plugin-query-suggestions';
import algoliasearch from 'algoliasearch';

const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);

const querySuggestionsPlugin = createQuerySuggestionsPlugin({
  searchClient,
  indexName: 'instant_search_demo_query_suggestions',
  getSearchParams: () => ({ clickAnalytics: true }),
});

autocomplete({
  container: '#autocomplete',
  openOnFocus: true,
  plugins: [querySuggestionsPlugin],
  getSources({ query }) {
    return [
      {
        sourceId: 'products',
        getItems() {
          return getAlgoliaResults({
            searchClient,
            queries: [
              {
                indexName: 'instant_search',
                params: {
                  query,
                  clickAnalytics: true,
                },
              },
            ],
          });
        },
        templates: {
          item({ item, components, html }) {
            return html`<div class="aa-ItemWrapper">
              <div class="aa-ItemContent">
                <div class="aa-ItemIcon">
                  <img
                    src="${item.image}"
                    alt="${item.name}"
                    width="40"
                    height="40"
                  />
                </div>
                <div class="aa-ItemContentBody">
                  <div class="aa-ItemContentTitle">
                    ${components.Highlight({ hit: item, attribute: 'name' })}
                  </div>
                  <div class="aa-ItemContentDescription">
                    ${components.Snippet({
                      hit: item,
                      attribute: 'description',
                    })}
                  </div>
                </div>
              </div>
              <button
                class="aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly"
                type="button"
              >
                <svg
                  fill="currentColor"
                  viewBox="0 0 24 24"
                  width="20"
                  height="20"
                >
                  <path
                    d="M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"
                  ></path>
                </svg>
              </button>
            </div>`;
          },
        },
      },
    ];
  },
});

This code adds the Autocomplete menu to an element with the id autocomplete. To use a different selector, adjust the container parameter. The openOnFocus parameter ensures that the Autocomplete menu appears as soon as users focus the input. This searches an Algolia index of ecommerce products using the getAlgoliaResults function.

Enable the insights option

To automatically send events, turn the insights option to true in your autocomplete instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
// ...

autocomplete({
  container: '#autocomplete',
  placeholder: 'Search products',
  openOnFocus: true,
  insights: true,
  getSources({ query }) {
    // ...
  },
});

// ...

To identify users consistently, it’s best if you set your own userToken with setUserToken—for example, for authenticated users. The search-insights library can create anonymous user tokens and store them in cookie. To use cookie-based anonymous tokens, initialize the library with useCookie set to true:

1
2
3
4
5
6
insightsClient('init', { appId, apiKey });
insightsClient('setUserToken', yourUserToken);

// or

insightsClient('init', { appId, apiKey, useCookie: true });

In older versions of the search-insights library (earlier than version 2.0), cookie-based anonymous tokens are on by default.

Manage the Insights library

Autocomplete loads the search-insights library for you from jsDelivr. You don’t need to install it or set it up yourself.

If you’re using a Content Security Policy to protect your site and you want to let Autocomplete load search-insights for you, make sure to add https://cdn.jsdelivr.net in your list of trusted sources for JavaScript.

1
script-src https://cdn.jsdelivr.net/

If you prefer hosting your own version of search-insights, you can add it to your project:

  1. Install the Insights client
  2. Initialize the Insights client

Autocomplete doesn’t load search-insights when it detects it on the page.

Default events

After enabling the insights option, Autocomplete automatically sends the following events:

Event Description
Items Viewed View events for results shown in the autocomplete menu.
Items Selected Click events when users selects an item in the menu.

By default, Autocomplete doesn’t send any conversion events. You can send events from templates manually.

Customize events

You can customize the Insights plugin by using one of these hooks:

For example, you might want to use a different eventName. For more information, see the examples in the createAlgoliaInsightsPlugin documentation.

Send events from templates

By default, Autocomplete doesn’t send any conversion events. If your templates include calls to action, such as, an Add to cart button, you can track interactions with them as conversion events.

Autocomplete with an Add To Cart button

To send events from your templates, pass the Insights client to your templates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
autocomplete({
  // ...
  insights: true,
  templates: {
    item({ item, components, state, html }) {
      return createProductItemTemplate({
        hit: item,
        components,
        insights: state.context.algoliaInsightsPlugin.insights,
        html,
      });
    },
  },
});

function createProductItemTemplate() {
  // ...
}

Now, you can send events from your templates by using the Insights client’s methods. For example, to track a conversion event when users click the Add to cart button, use the convertedObjectIDsAfterSearch method:

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
43
44
45
46
function createProductItemTemplate({ hit, insights, components, html }) {
  return html`<div class="aa-ItemWrapper">
    <div class="aa-ItemIcon">
      <img src="${hit.image}" alt="${hit.name}" width="40" height="40" />
    </div>
    <div class="aa-ItemContent">
      <div class="aa-ItemContentTitle">
        ${components.Highlight({ hit, attribute: 'name' })}
      </div>
      <div class="aa-ItemContentDescription">
        ${components.Snippet({ hit, attribute: 'description' })}
      </div>
    </div>
    <div class="aa-ItemActions">
      <button
        class="aa-ItemActionButton"
        type="button"
        onClick="${(event) => {
          event.preventDefault();
          event.stopPropagation();
          insights.convertedObjectIDsAfterSearch({
            eventName: 'Added to cart',
            index: hit.__autocomplete_indexName,
            objectIDs: [hit.objectID],
            queryID: hit.__autocomplete_queryID,
          });
        }}"
      >
        <svg
          viewBox="0 0 24 24"
          width="20"
          height="20"
          fill="none"
          stroke="currentColor"
        >
          <path
            d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="2"
          />
        </svg>
      </button>
    </div>
  </div>`;
}

To see a complete implementation, check the Autocomplete playground.

Add-to-cart events

When your users add an item to their cart, send a special conversion event with the addToCart subtype.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
insights.convertedObjectIDsAfterSearch({
  eventName: 'Added to cart',
  index: hit.__autocomplete_indexName,
  objectIDs: [hit.objectID],
  queryID: hit.__autocomplete_queryID,
  // Special subtype
  eventSubtype: 'addToCart',
  // An array of objects representing each item added to the cart
  objectData: [
    {
      // The discount value for this item, if applicable
      discount: item.discount || 0,
      // The price value for this item (minus the discount)
      price: item.price,
      // How many of this item were added
      quantity: 2,
    },
  ],
  // The total value of all items
  value: item.price * 2,
  // The currency code
  currency: 'USD',
});

Fields representing monetary values accept both numbers and strings, in major currency units (for example, 5.45 or '5.45'). To prevent floating-point math issues, use strings, especially if you’re performing calculations.

Purchase events

When your users purchase an item, send a special conversion event with the purchase subtype.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
insights.convertedObjectIDsAfterSearch({
  eventName: 'Added to cart',
  index: hit.__autocomplete_indexName,
  objectIDs: [hit.objectID],
  queryID: hit.__autocomplete_queryID,
  // Special subtype
  eventSubtype: 'purchase',
  // An array of objects representing each purchased item
  objectData: [{
    // The discount value for this item, if applicable
    discount: item.discount || 0,
    // The price value for this item (minus the discount)
    price: item.price,
    // How many of this item were added
    quantity: 2,
  }],
  // The total value of all items
  value: item.price * 2,
  // The currency code
  currency: 'USD',
});

Fields representing monetary values accept both numbers and strings, in major currency units (for example, 5.45 or '5.45'). To prevent floating-point math issues, use strings, especially if you’re performing calculations.

Validate your events

Use the events debugger to verify that events are being sent.

Did you find this page helpful?