API Reference / InstantSearch.js Widgets / insights
Widget signature
instantsearch.middlewares.createInsightsMiddleware({
  insightsClient: null | InsightsClient,
  onEvent?: (event: InsightsEvent, aa: null | InsightsClient) => void,
});

// or

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

createInsightsMiddleware({
  // ...
});

About this widget

The insights middleware helps you achieve the following:

  1. Set the userToken for insights purposes (Click Analytics, Personalization, etc.)
  2. Automatically send events from built-in widgets (you can disable it)
  3. Lets you send events from your own custom widgets

Requirements

Examples

1
2
3
4
5
6
const insightsMiddleware = instantsearch.middlewares.createInsightsMiddleware({
  insightsClient,
  onEvent,
});

search.use(insightsMiddleware);

Options

insightsClient
type: null|InsightsClient
Required

The middleware leverages insightsClient to sync the userToken between search and analytics calls. If you want to disable userToken sync and automatic event sending, you can set this to null.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
  /*
    A snippet to include `search-insights`
    You can find it here
    https://github.com/algolia/search-insights.js
  */
</script>

<script>
  const insightsMiddleware = instantsearch.middlewares.createInsightsMiddleware({
    insightsClient: window.aa,
  });

  search.use(insightsMiddleware);

  const userToken = // Get the user token (synchronously or asynchronously).

  // The `insights` middleware receives a notification
  // and attaches the `userToken` to search calls onwards.
  window.aa('setUserToken', userToken);
</script>
onEvent
type: (event: InsightsEvent, aa: null | InsightsClient) => void
default: undefined
Optional

By default, the middleware sends events to Algolia using the provided insightsClient. You can also control events and send them yourself by implementing an onEvent method for the middleware to call instead. The method lets you access data, and filter or modify the payload. You can also use it to send events to third-party trackers.

If you want to use onEvent to send events to third-party trackers, but don’t want to send them to Algolia, you can set insightsClient to null, and you don’t need the search-insights library in your application.

The event parameter has the following properties:

  • insightsMethod?: string: The Insights method (e.g., 'viewedObjectIDs', 'clickedObjectIDsAfterSearch', etc.). You can find more in the Insights API reference.
  • payload: { [key: string]: any }: The event payload.
  • widgetType: string: The widget type given by connectors (e.g., 'ais.refinementList', 'ais.hits', etc.)
  • eventType: string: The event type (e.g., 'view', 'click', 'conversion', or anything else if you customized it).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
createInsightsMiddleware({
  insightsClient: window.aa,
  onEvent: (event, aa) => {
    const { insightsMethod, payload, widgetType, eventType } = event;

    // Send the event to Algolia
    aa(insightsMethod, payload);

    // Send the event to a third-party tracker
    if (widgetType === 'ais.hits' && eventType === 'click') {
      thirdPartyTracker.send('Product Clicked', payload);
    }
  }
});

Custom events

Connectors

Many of the InstantSearch connectors expose the sendEvent method. If you use these connectors to create custom widgets, you can leverage the method to send custom events.

Here’s a list of connectors that expose sendEvent.

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
const renderRefinementList = (renderOptions, isFirstRendering) => {
  const { sendEvent } = renderOptions;

  // `sendEvent` from `connectRefinementList` can send `click` events.
  const clickedFacetValue = 'Apple';
  
  // This sends an event like the following:
  /*
    {
      eventType: 'click',
      insightsMethod: 'clickedFilters',
      payload: {
        eventName: 'Filter Applied',
        filters: ['brand:"Apple"'],
        index: '<your-index-name>',
      },
      widgetType: 'ais.refinementList',
    }
  */
  sendEvent('click', clickedFacetValue);

  // Or, you can send a custom payload
  sendEvent({
    eventType: 'click',
    insightsMethod: 'clickedFilters',
    payload: {
      eventName: 'Filter Applied',
      filters: [`brand:${JSON.stringify(clickedFacetValue)}`],
      index: '<your-index-name>',
    },
    widgetType: 'ais.refinementList',
  });
}

const customRefinementList = instantsearch.connectors.connectRefinementList(
  renderRefinementList
);
Hits

The hits and infiniteHits widgets provide templates, which use a centralized event listener. You therefore need to use the exposed bindEvent function.

The bindEvent(eventType, eventName) function returns a data attribute, such as:

1
2
3
<button click="button" data-insights-event="...">
  ...
</button>

When clicking the button, InstantSearch automatically catches the event and sends it to Algolia, or forwards it to onEvent if provided.

  • eventType: 'click' | 'conversion'
  • eventName: string
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
instantsearch.widgets.hits({  // or `infiniteHits`
  // ...
  templates: {
    item: (hit, bindEvent) => {
      return `
        <div>
          <p>${instantsearch.highlight({ attribute: 'title', hit })}</p>
          <button type="button" ${bindEvent('conversion', 'Product Added')}>
            Add to cart
          <button>
        </div>
      `;
    }
  },
});

Did you find this page helpful?

InstantSearch.js v4