Skip to content
Solution for caching data of events in localStorage and sending it recursively to Google Tag Manager.
JavaScript HTML
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
demo added sample of usage jQuery event listener Aug 8, 2017
test added QUnit tests Aug 13, 2017
LICENSE Initial commit Jun 8, 2017 Initial commit Jun 8, 2017


Idea of this solution is based on HTML5 Local Storage. I did not want to send data to Google Tag Manager immediately after the event is triggered on my website.

Problems with regular solution

On the Developer Guide you can see the sample of usage:

<a href="page.html" onclick="dataLayer.push({'event': 'button-click'});">My button</a>

where method dataLayer.push() starts immediately after clicking on the link. And here you can have the problem with sending data to GTM because you have to trust that sending will be faster than page reloading to page.html. You can use also event callback datalayer variable but cache (GTM-Storage) is better...

GTM-Storage solution

GTM-Storage is independent of GTM and dataLayer object. It just creates numerous elements which the event was made on. In your code you can use storaged data to recursive reading it and sending to GTM in given interval time.

Saving data to storage and reading it is safe because no javascript error will stop the default website event like page reloading based on callback event.

Quick start

Copy the following link to the main GTM-Storage file and paste it to the <head> tag on every page of your website:

<script src="gtmstorage.js"></script>

Put the following link to the script at the bottom of your markup right after jQuery:

<script src="jquery.js"></script>
<script src="script.js"></script>


Use HTML event attributes to set the event in the HTML tag and call the gtmStorage.push() method with this argument (HTML DOM element).

Use HTML tag attribute data-gtm to set data to send to GTM. The attribute data-gtm needs to get value in JSON format with one required property:

  • event - custom event name [required]
  • data - custom data with any format (object, string, number, bool)

Here is an example: in order to set an event when a user clicks a link, you might modify the link to call the push() and enter data by data-gtm as follows:

<a href="#url"
   data-gtm='{"event":"customEventName", "data":{"any":"data","you":"need"}}'>link anchor</a>

Feel free to modify script.js file and create any solution you need. For example conditional statements on handling Ecommerce object format like Measuring Product Clicks with required ecommerce property.

Why DOM Level 0 event model?

In the previous example I used DOM Level 0 event model. It means triggering of event in HTML tag property, eg. <span onclick="gtmStorage.push(this)" />.

I have chosen this event model because it works faster. For example, if you want to use DOM Level 2 event model based on jQuery, event listeners start working after DOM is ready. And if your website has 100K lines of code, it is possible that the user will start using the website before it is ready, and you lose some events and stats. If you paste the gtmstorage.js file in <head> and you use DOM Level 0 event model - you do not lose the events.

This solution is ready also in content loaded by AJAX.


Code released under the MIT license.

You can’t perform that action at this time.