How to add LunaMetrics AJAX listener to Single-Page Apps
There are several tutorials on how to set up LunaMetrics Ajax Event Listener. With most websites, the standard practice works as expected. However, you might run into a few problems on Single-Page apps.

There are two main reasons why the Ajax Listener doesn’t work as expected. Both of them are more commonly seen with single-page apps but they can happen with multi-page websites as well.
You are using incorrect trigger
The standard way of setting up the tag is by using Custom HTML tag and triggering it on All Pages.

This works well for applications where the page is reloaded every time you navigate to a different link. However, in the past few years, the way websites are built has changed. Now with more popular single-page apps the page is almost never reloaded during navigation and All Pages
trigger is fired only once.
If this is the case for you then you probably use History Change
trigger instead of All Pages
to track your views. For example, to track page views in Google Analytics you have the tag set up with the following trigger:

This might lead you to think that you have to set up AJAX Listener
tag with the same trigger. Except once you implement it you’ll notice that your ajaxComplete
event is sometimes fired multiple times with the same content.
This is caused by how AJAX Listener
script works. Once the custom script is added to the page it will start listening for AJAX requests and never stop. If a request is made then the script will push ajaxComplete
event to the data layer and keep listening for another one.
Now, remember, with single page apps the page doesn’t reload with navigation. This means that every script you add to the application will stay there (unless knowingly removed). When you navigate to a sub-link on your page and History Change
trigger is fired then the second AJAX Listener
script is added to the page. And now you have 2 listeners on your page firing the same event on the same AJAX request. The more links you click the more listeners you have and the more duplicate events are fired.
Set the correct trigger
Fixing the issue is as simple as changing the trigger that fires the AJAX Listener
tag. Instead of the History Change
use Page View — DOM Ready
. It will make sure the tag is fired only once.

Why Page View — DOM Ready
and not Page View
you ask? Ajax Listener tag depends on an external library called JQuery. Depending on how the application is built it’s possible that loading jquery library is stalled until the page has completely finished loading. By using Dom Ready
we make sure the page is finished loading (hence jquery is loaded) before adding the tag to the page.
It’s still possible that the tag is fired before JQuery library is loaded. This leads us to the second issue with the Ajax Listener.
What if a tag is added, but ajaxComplete event is not pushed?
If you have AJAX listener tag setup correctly, but you’re not seeing any ajaxCompleted
events pushed to the data layer then it’s possible your website lacks a JQuery dependency. JQuery is a very popular library that exists on most websites today. However, with single-page websites, the library is not as important anymore for development and it is excluded from websites more and more.
The easiest way to find out if your website has jquery enabled is to ask the developers. Another option is to use a browser console.
If you have identified that jQuery is missing from the website then the best option is to use a jquery free ajax listener tag. It‘s built to work exactly as the Lunametrics listener, but it doesn’t depend on any third-party technologies.
Summary
Keep an eye out for these issues and if you see duplicate events firing then make sure you use PageView — DOM Ready
trigger. Or if you have an opposite problem and no events are fired then talk with your developers if JQuery library is included in the project. Alternatively, switch your GTM to use a dependency free tag that doesn’t depend on any libraries.
Hopefully, this will save you some time when implementing AJAX listener.