Google Tag Manager (GTM) and Matomo

Matomo (formerly PiWik) is an excellent alternative to Google Analytics. And as with Google Analytics it may be implemented with a tag manager to implement a variety of elements reducing the need for developers.  We have found that implementing Matomo with Google Tag Manager (GTM) is particularly valuable as the configuration can take advantage of the knowledge, simplicity, and pre-built functions within GTM. We have found this particularly useful when Google Analytics and Matomo are utilized concurrently.  

While Matomo now offers their own tag manager, this is similar to others that are more granular and offer fewer built-in functions than GTM.  For this reason, we prefer the use of GTM for Matomo tag management.


This guide provides a series of detail related to the use of GTM for Matomo and is based upon an assumption that the reader is comfortable with GTM, its datalayer, and Matomo JavaScript. The following resources provide for a good background and will be refenced regular during your implementation.


When developing the tags and using the GTM debug and Preview modes you will see the variety of dataLayer interactions and notices that the script tag has fired.  You will not see the Matomo code itself firing with the GTM debug tools or console. It is best then to debug with a Matomo Site ID that is used for development and can then be switched later to a production Site ID. As Matomo obtains and presents data without delay (unlike Google Analytics) you can test by looking for the data as it appears within Matomo.

The Tags

There are a few sets of basic tags that you will likely use in your implementation.

The Primary Page View Tag

The primary tag contains the main tracking code to be fired on all pages. The code is developed as you would the Matomo code that would be placed on a page and is instead placed within the Custom HTML tag. There are no special items needed for GTM.

In the example you will notice that we utilize GTM variables. GTM will insert the proper value for each variable when the script is executed.

<!-- Matomo -->

<script type="text/javascript">

  var _paq = _paq || [];

  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */

  _paq.push(["setDocumentTitle", document.domain + "/" + document.title]);

  _paq.push(["setCookieDomain", "*"]);


  _paq.push(["setDomains", ["*"]]);




  _paq.push(['setCustomDimension', customDimensionId = 9, customDimensionValue = '{{Page Hostname}}']);


  (function() {

    var u="//";

    _paq.push(['setTrackerUrl', u+'piwik.php']);

    _paq.push(['setSiteId', '{{Lookup - Hostname to MA SiteID}}']);

    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];

    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);



<noscript><p><img src="//{{Lookup - Hostname to MA SiteID}}&rec=1" style="border:0;" alt="" /></p></noscript>

<!-- End Matomo Code -->


Matomo events are passed via the trackEvent code.  If you have setup Google Analytics events then you can use the same values for the Category, Action and Value.

For example, your tag for Google Analytics might look as follows:

Your Matomo script would then be:


  var _paq = _paq || [];

_paq.push(['trackEvent', 'Anchor Link Click', '{{Click Text}}', '{{Click URL}}']);



Notice that in the Matomo script we have the first line with:

var _paq = _paq || [];


This is needed in all the Matomo scripts.

Custom Dimensions

Custom Dimensions in Matomo may be added to the Event code or placed in as it's dedicated code.  We have found that the code when combined with the trackEvent does not register the Custom Dimensions in Matomo.  Instead, we separate the two as their own lines.


  var _paq = _paq || []; 

_paq.push(['setCustomDimension', customDimensionId = 3, customDimensionValue = '{{JS - GA clientId Capture}}']);

_paq.push(['trackEvent', 'GA Client ID', 'GA Client ID', '{{JS - GA clientId Capture}}']);



You must ensure that the trackEvent code follows the Custom Dimension line.  This is because Matomo needs a trackPage or a trackEvent line to push the custom dimension code into the platform.  You do not want to use a trackPage as the main tag is already recording the page view. The trackEvent is then used.  This also means you will always need a trackEvent with you have a custom dimension.


The ecommerce code is put in place similar to the Custom Dimension code and then followed by the trackEvent for the push.  Notice that we do not use the simplified code from Matomo to combine dimensions and events into a single push statement.


var _paq = _paq || []; 

_paq.push(['addEcommerceItem','{{JS - ecommerce - planType}}', '{{JS - ecommerce - planType}}', '{{JS - ecommerce - planLength}}', '{{JS - ecommerce - transactionTotal- todayPrice}}', 1]);

_paq.push(['setCustomDimension', customDimensionId = 7, customDimensionValue = '{{JS - ecommerce - planType}} - {{JS - ecommerce - planLength}}']);

_paq.push(['trackEvent', 'Ecommerce', 'Save and Review - addToCart', '{{JS - ecommerce - planType}} - {{JS - ecommerce - planLength}}','{{JS - ecommerce - transactionTotal- todayPrice}}']);


Ecommerce Triggers

The ecommerce trigger is associated with the value of the ecommerce event in the fr push.  When GTM executes the dataLayer push it sees that the ecommerce event is within the push. It then fires any tags associated with the ecommerce event associated with a Custom Event trigger.

Questions? Contact us.

Let’s talk.