Concepts / Getting insights and analytics / Google Tag Manager
Jan. 10, 2020

Google Tag Manager

Overview

If you already have integrated Google Tag Manager (GTM) on your website, you can leverage this solution to send events to Algolia.

Setup

1. Import the template

The Algolia Search Insights template needs to be imported in GTM before sending events.

You can close the overlay.

2. Create variables

For events to be sent with the correct information (userToken, objectIDs, queryID, etc.), you need to add variables in the User-Defined Variables section.

  1. Click New in the Variables panel
  2. Refer to the Variables section.

3. Create tags

Tags will specify which Insights methods to send when it’s triggered.

  1. Click New in the Tags panel.
  2. Select the Algolia Search Insights tag type.
  3. Choose the Insights method and provide the options.
  4. Refer to the Tags section.

4. Create triggers

Triggers will listen to events happening on the app to trigger tags.

  1. Click New in the Triggers panel
  2. Select the element to interact with

Tags

Each Insights method is represented by a tag in GTM.

Init

This method is necessary for initializing the connection with the Insights API.

Configuration

You need to define some variables to use this method:

  • App ID
  • API key

Trigger

We recommend triggering this tag on the “Page View” event.

This method refers to Clicked Object IDs After Search from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
<article
 data-insights-object-id="{{objectID}}"
 data-insights-position="{{__position}}"
 data-insights-query-id="{{__queryID}}"
>
  <!-- ... -->
</article>
`
  }
})

Clicked Object IDs

This method refers to Clicked Object IDs from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

1
2
3
4
5
6
7
8
9
10
11
12
13
instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
<article
 data-insights-object-id="{{objectID}}"
 data-insights-position="{{__position}}"
>
  <!-- ... -->
</article>
`
  }
})

Clicked Filters

This method refers to Clicked Filters from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

Replace brand with the attribute to track.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
instantsearch.widgets.refinementList({
  container: '#brands',
  attribute: 'brand',
  templates: {
    item: `
<label
  class="ais-RefinementList-label"
  data-insights-filter="brand:{{value}}"
>
  <input type="checkbox" class="ais-RefinementList-checkbox" value="{{value}}">
  <span class="ais-RefinementList-labelText">{{label}}</span>
  <span class="ais-RefinementList-count">{{count}}</span>
</label>
`
  }
})

This method refers to Converted Objects IDs After Search from the Insights API.

Configuration

You need to define some variables to use this method:

Trigger

We recommend triggering this tag when a search result is clicked.

Templates

1
2
3
4
5
6
7
8
9
10
11
12
13
14
instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
<article
 data-insights-object-id="{{objectID}}"
 data-insights-position="{{__position}}"
 data-insights-query-id="{{__queryID}}"
>
  <!-- ... -->
</article>
`
  }
})

Converted Objects IDs

This method refers to Converted Objects IDs from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

1
2
3
4
5
6
7
8
9
10
instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
<article data-insights-object-id="{{objectID}}">
  <!-- ... -->
</article>
`
  }
})

Converted Filters

This method refers to Converted Filters from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

Replace brand with the attribute to track.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
instantsearch.widgets.refinementList({
  container: '#brands',
  attribute: 'brand',
  templates: {
    item: `
<label
  class="ais-RefinementList-label"
  data-insights-filter="brand:{{value}}"
>
  <input type="checkbox" class="ais-RefinementList-checkbox" value="{{value}}">
  <span class="ais-RefinementList-labelText">{{label}}</span>
  <span class="ais-RefinementList-count">{{count}}</span>
</label>
`
  }
})

Viewed Object IDs

This method refers to Viewed Object IDs from the Insights API.

Configuration

You need to define some variables to use this method:

Templates

1
2
3
4
5
6
7
8
9
10
instantsearch.widgets.hits({
  container: '#hits',
  templates: {
    item: `
<article data-insights-object-id="{{objectID}}">
  <!-- ... -->
</article>
`
  }
})

Viewed Filters

This method refers to Viewed Filters from Insights API.

Configuration

You need to define some variables to use this method:

Templates

Replace brand with the attribute to track.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
instantsearch.widgets.refinementList({
  container: '#brands',
  attribute: 'brand',
  templates: {
    item: `
<label
  class="ais-RefinementList-label"
  data-insights-filter="brand:{{value}}"
>
  <input type="checkbox" class="ais-RefinementList-checkbox" value="{{value}}">
  <span class="ais-RefinementList-labelText">{{label}}</span>
  <span class="ais-RefinementList-count">{{count}}</span>
</label>
`
  }
})

Variables

userToken

You can forward the user token to GTM via a Data Layer.

In you application code, store the userToken in the Data Layer:

1
2
3
4
window.dataLayer = window.dataLayer || []
window.dataLayer.push({
  userToken: 'USER_1'
})

In GTM, create a variable called UserToken of type “Data Layer Variable” with the name userToken (same name as the JavaScript key you pushed to the Data Layer).

In the GTM interface, a new variable called {{UserToken}} is available.

objectIDs, positions, queryID

You can forward the objectIDs, positions, queryID variables to GTM via data attributes.

The following example uses InstantSearch.js and assumes that data attributes are set in the templates.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const search = instantsearch({
  searchClient,
  indexName: 'products'
})

search.addWidgets([
  instantsearch.widgets.hits({
    container: '#hits',
    templates: {
      item: `
<article
 data-insights-object-id="{{objectID}}"
 data-insights-position="{{__position}}"
 data-insights-query-id="{{__queryID}}"
>
  <!-- ... -->
</article>
`
    }
  })
])

search.start()

__queryID and __position are available in hits and infiniteHits from InstantSearch.js 3.4.0.

Once these values are available in the hits template, you can retrieve them in GTM.

First, you need to create a utility variable to target elements based on their selector. Select Custom JavaScript variable and name it Find closest:

1
2
3
4
5
6
7
8
9
function() {
  return function(target, selector) {
    while (!target.matches(selector) && !target.matches('body')) {
      target = target.parentElement;
    }

    return target.matches(selector) ? target : undefined;
  }
}

Element.matches needs to be polyfilled to support IE11.

In the GTM interface, a new variable called {{Find closest}} is available and contains the nearest element matching the selector.

objectID

Create a Custom JavaScript variable and name it HitObjectID:

1
2
3
4
5
6
7
function() {
  var element = {{Find closest}}({{Click Element}}, '[data-insights-object-id]');

  return typeof element !== 'undefined'
    ? element.getAttribute('data-insights-object-id')
    : undefined;
}

In the GTM interface, a new variable called {{HitObjectID}} is available and gives you the object ID of the hit.

We use getAttribute to add compatibility for IE, which doesn’t support JavaScript access to dataset.

positions

Create a Custom JavaScript variable and name it HitPosition:

1
2
3
4
5
6
7
function() {
  var element = {{Find closest}}({{Click Element}}, '[data-insights-position]');

  return typeof element !== 'undefined'
    ? element.getAttribute('data-insights-position')
    : undefined;
}

In the GTM interface, a new variable called {{HitPosition}} is available and gives you the absolute position of the hit.

queryID

From InstantSearch

Create a Custom JavaScript variable and name it HitQueryID:

1
2
3
4
5
6
7
function() {
  var element = {{Find closest}}({{Click Element}}, '[data-insights-query-id]');

  return typeof element !== 'undefined'
    ? element.getAttribute('data-insights-query-id')
    : undefined;
}

In the GTM interface, a new variable called {{HitQueryID}} is available and gives you the query ID related to the hit. This is the identifier of the search query that returned the hit.

From the URL

Create a “URL” variable named URLQueryID of type “Query” and with the query parameter name of the queryID as key.

In the GTM interface, a new variable called {{URLQueryID}} is available and gives you the query ID related to the URL.

filters

You can forward the filters variable to GTM via data attributes.

The following example uses InstantSearch.js and assumes that data attributes are set in the templates.

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
const search = instantsearch({
  searchClient,
  indexName: 'products'
})

search.addWidgets([
  instantsearch.widgets.refinementList({
    container: '#brands',
    attribute: 'brand',
    templates: {
      item: `
<label
  class="ais-RefinementList-label"
  data-insights-filter="brand:{{value}}"
>
  <input type="checkbox" class="ais-RefinementList-checkbox" value="{{value}}">
  <span class="ais-RefinementList-labelText">{{label}}</span>
  <span class="ais-RefinementList-count">{{count}}</span>
</label>
`
    }
  })
])

search.start()

Once these values are available in the hits template, you can retrieve them in GTM.

Create a Custom JavaScript variable and name it Filters:

1
2
3
4
5
6
7
function() {
  var element = {{Find closest}}({{Click Element}}, '[data-insights-filter]');

  return typeof element !== 'undefined'
    ? element.getAttribute('data-insights-filter')
    : undefined;
}

In the GTM interface, a new variable called {{Filters}} is available and gives you the filters.

Did you find this page helpful?