Google Tag Manager with built in filters (specifically data-insights-filter) using instantsearch

Hello! :slight_smile:

So I’m trying to tie in events to my search. I’m using the Google Tag Manager implementation, and the documentation says I need to add a data-insights-filter attribute to the items in the filter.

I use instantsearch.js and am using the refinementList and hierarchicalMenu filters. In order to add this attribute, it looks like I need to override, and try and re-implement the logic done in the ‘item’ template function. The example in the documentation does not match the output I’m currently see on my page. Feels like trying to guess the logic used just to add an attribute is a bit overkill, and fragile/prone to issues.

I’m hoping I’m missing something, and there is either some hook where I can easily add an attribute to an item. Or there is built in support already for adding data-insights-filter. Or some other way I’m missing? Perhaps I could add it in via javascript if I can get notification when filters change?

Thanks for your time!
Nick

So I’ve developed a dynamic solution for GTM that doesn’t require any duplication of instantsearch logic.

Here is the solution for ‘filters viewed’:

Just adding 1 attribute, 1 class and then 2 GTM Tags.

The attribute is data-insights-filter-key and should be set to the attribute you are filter on and in a container wrapping the whole filter.

<div id="filter_brand" data-insights-filter-key="brand"></div>

The class is insights-filter-value, and should be applied to the css for labelText

    widgets.refinementList({
        container: '#filter_brand',
        attribute: 'brand',
        searchable: true,
        cssClasses: {
          labelText: 'insights-filter-value',
        },
    }),

Then add 2 GTM Variables:

Algolia Get Data Attributes (for Element)
Custom Javascript

function () {
  function findClosest(target, selector) {
    while (!target.matches(selector) && !target.matches('body')) {
      target = target.parentElement;
    }
    return target.matches(selector) ? target : undefined;
  }
  
  // Copied and pasted from Algolia Get Data Attributes, changing only the next 2 lines (clickedElement)
  return function (clickedElement, attributeName, containerQuerySelector) {
    // var clickedElement = {Click Element};  // Had to remove one set of {} for GTM error
    // search for children of the selector
    var elements = clickedElement
      ? [findClosest(clickedElement, '[' + attributeName +']')]
      : Array.from(document.querySelectorAll((containerQuerySelector || '') + ' [' + attributeName + ']')).filter(Boolean);

    if (elements.length === 0 && containerQuerySelector) {
      // see if it matches the container itself
      // for example, `#app[data-insights-index]`
      elements = Array.from(document.querySelectorAll(containerQuerySelector + '[' + attributeName + ']')).filter(Boolean);
    }
    var attributes = elements.map(function (element) {
      return element.getAttribute(attributeName);
    });
    return attributes;
  }
}

Algolia Insights Viewed Filters (dynamic)
Custom Javascript

function() {
  var className = 'insights-filter-value';
  var elements = Array.from(document.querySelectorAll('.' + className ));
  var attributes = elements.map(function (element) {
    return {{Algolia Get Data Attributes (for Element)}}(element,'data-insights-filter-key') + ':' + element.textContent;
  });
  return attributes;
}

How just reference Algolia Insights Viewed Filters (dynamic) in the viewed filters tag, and everything should work! = )