Sending Algolia Insights events

Learn how to send Algolia Insights events from your autocomplete menu.

note

Using this plugin requires an Algolia application with the Event Analytics feature enabled.

If you're using Algolia indices as sources in your autocomplete, Algolia provides Search Analytics out-of-the-box. Search Analytics includes metrics like top searches, top searches with no results, overall search counts, etc.

You may also want to capture Click and Conversion Analytics. These analytics take Algolia’s out-of-the-box Search Analytics further by providing insights into actions users take after performing a search. They're useful to better understand your user's behavior and what they need from your app. This information can ultimately drive your business.

Capturing these analytics requires sending events to Algolia when your users view, click, or convert on results. This tutorial explains how to automatically send events from your autocomplete using the autocomplete-plugin-algolia-insights package.

Prerequisites#

This tutorial assumes that you have:

  • an autocomplete using one or more Algolia indices for your sources
  • front-end development proficiency with HTML, CSS, and JavaScript
note

If you haven't implemented an autocomplete using Algolia as a source yet, follow the Getting Started guide first. For learning purposes, you can use the demo application credentials and index provided in this tutorial.

Getting started#

First, begin with some boilerplate for the autocomplete implementation. Create a file called index.js in your src directory, and add the boilerplate below:

index.js
import {
autocomplete,
getAlgoliaHits,
highlightHit,
} from '@algolia/autocomplete-js';
import algoliasearch from 'algoliasearch';
import { h, Fragment } from 'preact';
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
autocomplete({
container: '#autocomplete',
openOnFocus: true,
plugins: [],
getSources({ query }) {
return [
{
getItems() {
return getAlgoliaHits({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
params: {
clickAnalytics: true,
},
},
],
});
},
templates: {
item({ item }) {
return <ProductItem hit={item} />;
},
},
},
];
},
});
function ProductItem({ hit }) {
return (
<Fragment>
<div className="aa-ItemIcon">
<img src={hit.image} alt={hit.name} width="40" height="40" />
</div>
<div className="aa-ItemContent">
<div className="aa-ItemContentTitle">
{highlightHit({ hit, attribute: 'name' })}
</div>
<div className="aa-ItemContentDescription">
{highlightHit({ hit, attribute: 'description' })}
</div>
</div>
<button
className="aa-ItemActionButton aa-TouchOnly aa-ActiveOnly"
type="button"
title="Select"
>
<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>
</Fragment>
);
}

This boilerplate assumes you want to insert the autocomplete into a DOM element with autocomplete as an id. You should change the container to match your markup. Setting openOnFocus to true ensures that the dropdown appears as soon as a user focuses the input.

The autocomplete searches into an Algolia index of e-commerce products using the getAlgoliaHits function. Refer to the example in the Getting Started guide for more information.

note

You must set the clickAnalytics query parameter to true to send click and conversion events from your autocomplete.

For now, plugins is an empty array, but you'll learn how to add the Insights plugin next.

Sending Algolia Insights events#

The autocomplete-plugin-algolia-insights package provides the createAlgoliaInsightsPlugin function for creating an Insights plugin out-of-the-box.

It requires an Algolia Insights client initialized with an Algolia application ID and Search API key.

index.js
import {
autocomplete,
getAlgoliaHits,
highlightHit,
} from '@algolia/autocomplete-js';
import algoliasearch from 'algoliasearch';
import { h, Fragment } from 'preact';
import { createAlgoliaInsightsPlugin } from '@algolia/autocomplete-plugin-algolia-insights';
import insightsClient from 'search-insights';
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
insightsClient('init', { appId, apiKey });
const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ insightsClient });
autocomplete({
container: '#autocomplete',
placeholder: 'Search products',
openOnFocus: true,
plugins: [algoliaInsightsPlugin],
getSources({ query }) {
// ...
},
});
function ProductItem({ hit }) {
// ...
}

Now, whenever the autocomplete shows products in the dropdown, the plugin sends view events with the eventName "Items Viewed" for these products. If a user clicks a product, the plugin sends a click event, with the eventName "Item Selected" for that product. By default, the plugin doesn't send any conversion events.

Customizing events#

You can change any of the plugin's default behavior by using the onItemsChange, onSelect, or onActive hooks. For example, you may want to customize the eventName to match your naming conventions or send a different events on these actions.

Changing the eventName#

This snippet shows how to instantiate a plugin that sends a click event with "Product Selected from Autocomplete" as the eventName whenever a user selects an item. You may want to do this to differentiate between click events sent from your Autocomplete vs. other parts of your search implementation.

index.js
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
insightsClient('init', { appId, apiKey });
const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({
insightsClient,
onSelect({ insights, insightsEvents }) {
const events = insightsEvents.map((insightsEvent) => ({
...insightsEvent,
eventName: 'Product Selected from Autocomplete',
}));
insights.clickedObjectIDsAfterSearch(...events);
},
});

Sending different events for different result types#

If you're using multiple different Algolia indices in the same autocomplete, for example one for products and one for suggestions, you may want to use different eventNames for each section. You can change this (and other parts of the event) conditionally based on the source index name:

index.js
const appId = 'latency';
const apiKey = '6be0576ff61c053d5f9a3225e2a90f76';
const searchClient = algoliasearch(appId, apiKey);
insightsClient('init', { appId, apiKey });
const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({
insightsClient,
onSelect({ insights, insightsEvents }) {
const events = insightsEvents.map((insightsEvent) => {
switch (insightsEvent.index) {
case 'instant_search_demo_query_suggestions': {
return {
...insightsEvent,
eventName: 'Suggestion Selected from Autocomplete',
};
}
case 'instant_search': {
return {
...insightsEvent,
eventName: 'Product Selected from Autocomplete',
};
}
default: {
return {
...insightsEvent,
eventName: 'Item Selected from Autocomplete',
};
}
}
});
insights.clickedObjectIDsAfterSearch(...events);
},
});

Sending events from templates#

Though the default Insights plugin doesn't send any conversion events, you may want to. For example, you may have created a template with an "Add to cart" button.

Autocomplete with add to cart button

If a user adds an item to their shopping cart directly from the autocomplete, you can send a conversion event from your template. This is possible since the Insights plugin stores the Insights client in context. You can pass it to your templates like this:

index.js
autocomplete({
// ...
plugins: [algoliaInsightsPlugin],
templates: {
item({ item, state }) {
return (
<ProductItem
hit={item}
insights={state.context.algoliaInsightsPlugin.insights}
/>
);
},
},
});

Once available to your templates, you can use it to send events using Insights client methods. In this example, clicking the "Add to cart button" fires the convertedObjectIDsAfterSearch method, sending a conversion event.

ProductItem.jsx
function ProductItem({ hit, insights }) {
return (
<Fragment>
<div className="aa-ItemIcon">
<img src={hit.image} alt={hit.name} width="40" height="40" />
</div>
<div className="aa-ItemContent">
<div className="aa-ItemContentTitle">
{snippetHit({ hit, attribute: 'name' })}
</div>
<div className="aa-ItemContentDescription">
{snippetHit({ hit, attribute: 'description' })}
</div>
</div>
<div className="aa-ItemActions">
<button
className="aa-ItemActionButton"
type="button"
title="Add to cart"
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"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
/>
</svg>
</button>
</div>
</Fragment>
);
}

For more information on the methods and event types you can send using the Insights API, consult the Algolia Insights documentation.

Validating events#

To ensure that you're sending events as you expect, you can check your Algolia Insights logs or work with the Insights Validator Chrome extension. Check out the guide on validating events for more details.