{"id":101001,"date":"2025-02-21T06:57:11","date_gmt":"2025-02-21T06:57:11","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/true-view-ecommerce-impressions-with-google-tag-manager\/"},"modified":"2025-02-21T06:57:11","modified_gmt":"2025-02-21T06:57:11","slug":"true-view-ecommerce-impressions-with-google-tag-manager","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=101001","title":{"rendered":"True View Ecommerce Impressions With Google Tag Manager"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<blockquote>\n<p><strong>Last updated 9 October 2020<\/strong>: <code>customTask<\/code> updated to a more stable version.<\/p>\n<\/blockquote>\n<p>I\u2019m a big fan of <a href=\"https:\/\/www.simoahava.com\/analytics\/enhanced-ecommerce-guide-for-google-tag-manager\/\">Enhanced Ecommerce<\/a> in <a href=\"https:\/\/analytics.google.com\/\">Google Analytics<\/a>. In fact, I think it\u2019s the <strong>only<\/strong> valid way to deploy Ecommerce tracking today, especially when using <a href=\"https:\/\/tagmanager.google.com\/\">Google Tag Manager<\/a>. The ability to use a <a href=\"https:\/\/www.simoahava.com\/analytics\/enhanced-ecommerce-guide-for-google-tag-manager\/#send-the-data-to-google-analytics-using-a-custom-javascript-variable\">Custom JavaScript variable<\/a> and the possibility to tackle the <em>full<\/em> ecommerce funnel are some of the benefits of using Enhanced Ecommerce.<\/p>\n<p>However, tracking certain view-based events, <strong>impressions<\/strong> in particular, has a significant problem when it comes to how Google Analytics processes events. In a nutshell, when implemented by the book, <strong>impressions are sent for all the product impressions on the page when the page is loaded<\/strong>. In other words, you are collecting hits from impressions the user <em>might not actually have seen<\/em>.<\/p>\n<p>This also compounds into a number of problems:<\/p>\n<ul>\n<li>\n<p>Google Analytics has a maximum <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/analyticsjs\/limits-quotas#universal_properties\">hits per session<\/a> of 500. And this is a hard limit. Anything past 500 will simply <strong>not be recorded<\/strong> in the session (though if you\u2019re using the paid GA360 you\u2019ll still be billed for them!). If you send each impression separately, or even if you send them in batches but don\u2019t discard the ones the user never saw, you might be approaching or going past this quota limit.<\/p>\n<\/li>\n<li>\n<p>The <a href=\"https:\/\/www.simoahava.com\/analytics\/automatically-reduce-google-analytics-payload-length\/\">maximum payload length<\/a> is <strong>8192 bytes<\/strong> for any GA request. This is easily surpassed if you\u2019re sending 50-60 impressions in a single hit.<\/p>\n<\/li>\n<\/ul>\n<p>In this article, I want to tackle both of these problems by introducing a way of tracking <strong>only those impressions that were viewable in the browser viewport<\/strong>.<\/p>\n<div style=\"aspect-ratio: 2408 \/ 2078;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/true-view-impressions-google-tag-manager.jpg\" title=\"true view impressions google tag manager\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"2078\" width=\"2408\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/true-view-impressions-google-tag-manager.jpg#ZgotmplZ\" alt=\"true view impressions google tag manager\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>This solution is written for <strong>Google Tag Manager<\/strong>, as it utilizes a number of features that are built natively into the platform.<\/p>\n<p>I\u2019m also going to use <a href=\"https:\/\/www.simoahava.com\/analytics\/customtask-the-guide\/\"><code>customTask<\/code><\/a>, because I want to write the whole solution <a href=\"https:\/\/www.simoahava.com\/analytics\/trigger-javascript-without-using-custom-html-tag\/\">without using a Custom HTML tag<\/a>.<\/p>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"how-it-works\">How it works<\/h2>\n<p>The solution relies on the <a href=\"https:\/\/www.simoahava.com\/analytics\/element-visibility-trigger-google-tag-manager\/\"><strong>Element Visibility trigger<\/strong><\/a> to identify impressions in the viewport and push them into a <strong>batch queue<\/strong>. A <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/timer-trigger\/\"><strong>Timer trigger<\/strong><\/a> is also used to purge the batch queue in case the user is inactive. Finally, if a user <strong>clicks<\/strong> on an impression, all the items in the batch queue are sent, as are they if the user leaves the page.<\/p>\n<p>A <strong>batch queue<\/strong> is what we\u2019ll use to group the viewed impressions together into units of certain size, so that the request to GA is neither too crowded (risking going past the payload length limit) or too sparse (risking having too many hits in the session).<\/p>\n<div style=\"aspect-ratio: 1768 \/ 1718;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/batched-impressions.jpg\" title=\"Impressions in batches\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1718\" width=\"1768\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/batched-impressions.jpg#ZgotmplZ\" alt=\"Impressions in batches\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here\u2019s a simple flow of how the solution works:<\/p>\n<ol>\n<li>\n<p>When the page is first loaded, an inventory of impression objects is built by identifying an <code>ecommerce.impressions<\/code> object in the <code>dataLayer<\/code>.<\/p>\n<\/li>\n<li>\n<p>Every single product impression on the page itself will need to have an identifying attribute that links the product impression with the corresponding object in the <code>ecommerce.impressions<\/code> array in <code>dataLayer<\/code>. This should be something like <code>data-productid=\"impression1\"<\/code> where <code>impression1<\/code> is the ID of the impression.<\/p>\n<\/li>\n<li>\n<p>The <strong>Element Visibility<\/strong> trigger waits for items with this <code>data-productid<\/code> to become visible on the page, adding each into a batch array of viewed impressions.<\/p>\n<\/li>\n<li>\n<p>When the array length reaches the batch maximum you define, the impressions in the batch array are sent to GA and then deleted from the array (so that you don\u2019t end up sending them again).<\/p>\n<\/li>\n<li>\n<p>If the user <strong>clicks<\/strong> a product impression on the page, a Product Click event is sent with that impression data together with <strong>all<\/strong> the items in the current batch queue.<\/p>\n<\/li>\n<li>\n<p>Every 60 seconds (configurable), the batch queue is also emptied and sent to GA to avoid the impressions from being stuck in the queue for a long period of time if the user is inactive.<\/p>\n<\/li>\n<li>\n<p>When the user leaves the current page, a custom <a href=\"https:\/\/www.simoahava.com\/analytics\/fire-trigger-when-user-about-to-leave-page\/\"><code>beforeunload<\/code> listener<\/a> will also send any impressions left in the batch queue.<\/p>\n<\/li>\n<\/ol>\n<p>The end result is that as impressions are viewed by the visitor, items are added to the batch queue and sent whenever the queue fills up. There are safeguards (timer, <code>beforeunload<\/code>) which ensure that items are never forgotten in the queue.<\/p>\n<p>It\u2019s not trivial to set up, so let\u2019s get to it.<\/p>\n<h2 id=\"what-you-need\">What you need<\/h2>\n<p>First of all, you need a fairly solid understanding of what Enhanced Ecommerce impressions are, how they are (traditionally) tracked, and how they appear in your GA reports. This guide will <strong>not<\/strong> go over the basics. Check out my <a href=\"https:\/\/www.simoahava.com\/analytics\/enhanced-ecommerce-guide-for-google-tag-manager\/\">Enhanced Ecommerce guide<\/a>, as well as Google\u2019s <a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/analyticsjs\/enhanced-ecommerce\">official support documentation<\/a> for more information.<\/p>\n<p>For the solution to work \u201cout-of-the-box\u201d, you will need a <strong>properly formatted<\/strong> <code>ecommerce.impressions<\/code> object in the <code>dataLayer<\/code> deployed into the page template preferably <strong>before the GTM container snippet<\/strong>. This is what you should already have if you\u2019ve implemented Enhanced Ecommerce impressions <a href=\"https:\/\/developers.google.com\/tag-manager\/enhanced-ecommerce#product-impressions\">by the book<\/a>.<\/p>\n<div style=\"aspect-ratio: 1778 \/ 756;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impressions-in-datalayer.jpg\" title=\"Enhanced Ecommerce impressions in dataLayer\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"756\" width=\"1778\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impressions-in-datalayer.jpg#ZgotmplZ\" alt=\"Enhanced Ecommerce impressions in dataLayer\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>It\u2019s possible to modify the code so it works with objects with a different composition, and it\u2019s also possible to modify it to work with impressions scraped from the page. However, this guide will not tackle these edge cases. If you want to make these modifications yourself, feel free to do so (let me know in the comments if you need help).<\/p>\n<p>Another thing you\u2019ll need is a way to tag all the HTML elements that contain impressions with the custom attribute that will link the impression to the corresponding <code>dataLayer<\/code> object. For example, this is what the first seven products on the page would look like if using the <code>impressions<\/code> data from the screenshot above:<\/p>\n<div style=\"aspect-ratio: 1398 \/ 466;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/data-productid-html.jpg\" title=\"data-productid\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"466\" width=\"1398\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/data-productid-html.jpg#ZgotmplZ\" alt=\"data-productid\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As you can see, the value in <code>data-productid<\/code> corresponds with the individual <code>id<\/code> values in the <code>ecommerce.impressions<\/code> object.<\/p>\n<p>You could add these dynamically using a Custom HTML tag and some DOM manipulation magic, but I do recommend doing this <strong>correctly<\/strong> from the start. Adding the attributes directly into template code prevent any race conditions from emerging, such as the Element Visibility trigger not identifying the items to which you dynamically added the new attributes.<\/p>\n<p>Once you have the <code>dataLayer<\/code> object and the data attributes in place, you can get to work on the Google Tag Manager tags, triggers, and variables.<\/p>\n<h2 id=\"create-the-variables\">Create the variables<\/h2>\n<p>We\u2019re going to need a handful of variables. Two <strong>Lookup Table<\/strong> variables will handle some of the event tag logic. A <strong>Custom JavaScript<\/strong> variable for the <code>customTask<\/code> will be where most of the magic happens. Then, we\u2019ll also need a <strong>Custom JavaScript<\/strong> variable to handle the Enhanced Ecommerce object compilation.<\/p>\n<p>There are many moving parts here, so let\u2019s get to work.<\/p>\n<h3 id=\"lookup---get-impression-label\">{{Lookup &#8211; Get Impression Label}}<\/h3>\n<p>This <strong>Lookup Table variable<\/strong> will be used to populate the <strong>Event Label<\/strong> field of the tag we\u2019ll create label. As the label, i\u2019m using either \u201cImpression View\u201d or \u201cImpression Click\u201d, depending on what type of event caused the tag to fire. As you can guess, the tag will fire for both impressions views and clicks.<\/p>\n<p>This is what the Lookup Table variable should look like:<\/p>\n<div style=\"aspect-ratio: 1856 \/ 822;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/lookup-impression-label.jpg\" title=\"Lookup - impression label\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"822\" width=\"1856\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/lookup-impression-label.jpg#ZgotmplZ\" alt=\"Lookup - impression label\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"lookup---get-impression-interaction\">{{Lookup &#8211; Get Impression Interaction}}<\/h3>\n<p>This <strong>Lookup Table variable<\/strong> will return either <code>true<\/code> or <code>false<\/code>, depending on whether the hit was <em>non-interaction<\/em> or not. We\u2019ll create all <strong>impression views<\/strong> as non-interactive, and the <strong>product impression click<\/strong> will be interactive.<\/p>\n<div style=\"aspect-ratio: 1848 \/ 812;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/lookup-impression-interaction.jpg\" title=\"Lookup - impression noninteractive\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"812\" width=\"1848\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/lookup-impression-interaction.jpg#ZgotmplZ\" alt=\"Lookup - impression noninteractive\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"js---function---true-view-impression-handler\">{{JS &#8211; Function &#8211; True view impression handler}}<\/h3>\n<p>This is the main driving force of the solution. It\u2019s a <a href=\"https:\/\/www.simoahava.com\/analytics\/customtask-the-guide\/\"><code>customTask<\/code><\/a> variable, designed to build the batch queue, to create the <code>beforeunload<\/code> handler, to allow hits to fire (when the batch queue is full or a product is clicked), and to block GA hits from being dispatched (if the impression was simply added to the queue).<\/p>\n<p>Here\u2019s what the code in the <strong>Custom JavaScript<\/strong> variable should look like:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#aaa;font-style:italic\">\/\/ Configure the following\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> maxBatch           = <span style=\"color:#099\">10<\/span>,\n      batchVariableName  = <span style=\"color:#a50\">'_impressions_batch'<\/span>,\n      productIdAttribute = <span style=\"color:#a50\">'data-productid'<\/span>;\n  \n  <span style=\"color:#aaa;font-style:italic\">\/\/ Do not touch anything below this\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> targetElement = {{Click Element}},\n      event         = {{Event}};\n\n  <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) {\n    <span style=\"color:#00a\">while<\/span> (!targetElement.getAttribute(productIdAttribute) &amp;&amp; targetElement.tagName !== <span style=\"color:#a50\">'BODY'<\/span>) {\n      targetElement = targetElement.parentElement;\n    }\n  }\n\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#00a\">function<\/span>(customModel) {\n\n    <span style=\"color:#aaa;font-style:italic\">\/\/ Set up the beforeunload listener only when the tag is first run.\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">if<\/span> (<span style=\"color:#00a\">typeof<\/span> <span style=\"color:#0aa\">window<\/span>[batchVariableName] === <span style=\"color:#a50\">'undefined'<\/span>) {\n      <span style=\"color:#0aa\">window<\/span>.addEventListener(<span style=\"color:#a50\">'beforeunload'<\/span>, <span style=\"color:#00a\">function<\/span>() {\n\t\t<span style=\"color:#0aa\">window<\/span>.dataLayer.push({\n          event: <span style=\"color:#a50\">'sendFinalBatch'<\/span>\n        });\n      });\n    }\n    \n    <span style=\"color:#00a\">var<\/span> shouldFire = <span style=\"color:#00a\">false<\/span>,\n        batch      = <span style=\"color:#0aa\">window<\/span>[batchVariableName] = <span style=\"color:#0aa\">window<\/span>[batchVariableName] || [],\n        impressionId, \n        ost;\n        \n    <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.elementVisibility'<\/span>) {\n      impressionId = targetElement.getAttribute(productIdAttribute);\n      batch.push(impressionId);\n      <span style=\"color:#00a\">if<\/span> (batch.length === maxBatch) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n    }\n    \n    <span style=\"color:#00a\">if<\/span> ([<span style=\"color:#a50\">'sendFinalBatch'<\/span>, <span style=\"color:#a50\">'gtm.timer'<\/span>].indexOf(event) &gt; -<span style=\"color:#099\">1<\/span> &amp;&amp; batch.length &gt; <span style=\"color:#099\">0<\/span>) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n    \n    <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n    \n    <span style=\"color:#00a\">if<\/span> (shouldFire) {\n      ost = customModel.get(<span style=\"color:#a50\">'sendHitTask'<\/span>);\n      customModel.set(<span style=\"color:#a50\">'sendHitTask'<\/span>, <span style=\"color:#00a\">function<\/span>(sendModel) {\n        ost(sendModel);\n        <span style=\"color:#0aa\">window<\/span>[batchVariableName] = [];\n      });\n    } <span style=\"color:#00a\">else<\/span> {\n\t  customModel.set(<span style=\"color:#a50\">'sendHitTask'<\/span>, <span style=\"color:#00a\">null<\/span>);\n    }\n  };\n}\n<\/code><\/pre>\n<\/div>\n<p>First, modify the three variables in the beginning of the returned <code>function<\/code>.<\/p>\n<ul>\n<li>\n<p>Set <code>maxBatch<\/code> to the maximum length of the batch queue. The default value of <code>10<\/code> is probably enough in most cases.<\/p>\n<\/li>\n<li>\n<p>Set <code>batchVariableName<\/code> to what the global variable that stores the batch queue should be named. The default value is, again, probably OK, but you\u2019ll want to rename it in the rare case that a global variable named <code>_impressions_batch<\/code> already exists and is in use.<\/p>\n<\/li>\n<li>\n<p>Set <code>productIdAttribute<\/code> to the HTML attribute name that stores the ID with each product HTML block on the page. The default value is <code>data-productid<\/code>, which means that the HTML structures that contain each product impression should have the attribute <code>data-productid=\"some_product_id\"<\/code> in one of the elements (preferably an element that wraps the entire impression).<\/p>\n<\/li>\n<\/ul>\n<p>Let me tear this code apart and show you what each individual part does.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) {\n  <span style=\"color:#00a\">while<\/span> (!targetElement.getAttribute(productIdAttribute) &amp;&amp; targetElement.tagName !== <span style=\"color:#a50\">'BODY'<\/span>) {\n    targetElement = targetElement.parentElement;\n  }\n}\n<\/code><\/pre>\n<\/div>\n<p>This is a simple iterator which climbs up the element tree from the clicked element until it finds the element with the aforementioned product ID attribute.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">if<\/span> (<span style=\"color:#00a\">typeof<\/span> <span style=\"color:#0aa\">window<\/span>[batchVariableName] === <span style=\"color:#a50\">'undefined'<\/span>) {\n  <span style=\"color:#0aa\">window<\/span>.addEventListener(<span style=\"color:#a50\">'beforeunload'<\/span>, <span style=\"color:#00a\">function<\/span>() {\n    <span style=\"color:#0aa\">window<\/span>.dataLayer.push({\n      event: <span style=\"color:#a50\">'sendFinalBatch'<\/span>\n    });\n  });\n}\n<\/code><\/pre>\n<\/div>\n<p>When the <code>customTask<\/code> is fired for the first time on the page, a <code>beforeunload<\/code> listener is created. The idea is that when the user leaves the current page, the <code>beforeunload<\/code> event that is automatically dispatched triggers a <code>window.dataLayer.push()<\/code> call that we can then use to send the remaining items in the batch queue.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> shouldFire = <span style=\"color:#00a\">false<\/span>,\n    batch      = <span style=\"color:#0aa\">window<\/span>[batchVariableName] = <span style=\"color:#0aa\">window<\/span>[batchVariableName] || [],\n    impressionId, \n    ost;\n<\/code><\/pre>\n<\/div>\n<p>By default, the <code>customTask<\/code> blocks the Google Analytics request from firing (<code>shouldFire = false<\/code>). Also, here we create the batch queue if one doesn\u2019t already exist.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.elementVisibility'<\/span>) {\n  impressionId = targetElement.getAttribute(productIdAttribute);\n  batch.push(impressionId);\n  <span style=\"color:#00a\">if<\/span> (batch.length === maxBatch) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n}\n<\/code><\/pre>\n<\/div>\n<p>If the tag was fired due to a visibility event, the product ID that triggered the event will be pushed into the batch queue. If the batch queue thus reaches its maximum length, <code>customTask<\/code> will allow the hit to fire.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">if<\/span> ([<span style=\"color:#a50\">'sendFinalBatch'<\/span>, <span style=\"color:#a50\">'gtm.timer'<\/span>].indexOf(event) &gt; -<span style=\"color:#099\">1<\/span> &amp;&amp; batch.length &gt; <span style=\"color:#099\">0<\/span>) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n    \n<span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) { shouldFire = <span style=\"color:#00a\">true<\/span>; }\n<\/code><\/pre>\n<\/div>\n<p>If the trigger event was <code>sendFinalBatch<\/code> (i.e. the user is trying to leave the page) or <code>gtm.timer<\/code> (i.e. 60 seconds have passed since the previous timer event or page load) AND if the batch queue has items in it, the hit will be allowed to fire, thus clearing the batch queue and sending all the items within to GA.<\/p>\n<p>If the trigger event was a click, meaning the user clicked a product impression, the GA request will be allowed to complete as well.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">if<\/span> (shouldFire) {\n  ost = customModel.get(<span style=\"color:#a50\">'sendHitTask'<\/span>);\n  customModel.set(<span style=\"color:#a50\">'sendHitTask'<\/span>, <span style=\"color:#00a\">function<\/span>(sendModel) {\n    ost(sendModel);\n    <span style=\"color:#0aa\">window<\/span>[batchVariableName] = [];\n  });\n} <span style=\"color:#00a\">else<\/span> {\n  <span style=\"color:#0aa\">Object<\/span>.keys(customModel.data).forEach(<span style=\"color:#00a\">function<\/span>(key) {\n    customModel.data[key] = <span style=\"color:#00a\">null<\/span>;\n  });\n}\n<\/code><\/pre>\n<\/div>\n<p>If the GA hit is allowed to fire, the first part of the <code>if<\/code> clause will do just that. After the hit has been sent, the batch queue is cleared of all items.<\/p>\n<p>If the GA hit was blocked, then the <code>else<\/code> clause will clear the model object thus effectively preventing the Google Analytics hit from being dispatched.<\/p>\n<h3 id=\"js---get-true-view-object\">{{JS &#8211; Get True View object}}<\/h3>\n<p>This variable builds the Enhanced Ecommerce object when the tag fires. It\u2019s used to build both the impression <strong>view<\/strong> object and the impression <strong>click<\/strong> object.<\/p>\n<p>So, create a <strong>Custom JavaScript<\/strong> variable, and put the following code within:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#aaa;font-style:italic\">\/\/ Configure the following:\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> maxBatch           = <span style=\"color:#099\">10<\/span>,\n      batchVariableName  = <span style=\"color:#a50\">'_impressions_batch'<\/span>,\n      productIdAttribute = <span style=\"color:#a50\">'data-productid'<\/span>; \n  \n  <span style=\"color:#aaa;font-style:italic\">\/\/ Do not touch anything below this\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  <span style=\"color:#00a\">var<\/span> targetElement = {{Click Element}},\n      event         = {{Event}},\n      batch         = <span style=\"color:#0aa\">window<\/span>[batchVariableName],\n      impressions   = google_tag_manager[{{Container ID}}].dataLayer.get(<span style=\"color:#a50\">'ecommerce.impressions'<\/span>),\n      ecomObj       = {ecommerce: {}};\n\n  <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) {\n    <span style=\"color:#00a\">while<\/span> (!targetElement.getAttribute(productIdAttribute) &amp;&amp; targetElement.tagName !== <span style=\"color:#a50\">'BODY'<\/span>) {\n      targetElement = targetElement.parentElement;\n    }\n  }\n\n  <span style=\"color:#00a\">var<\/span> latestImpression = impressions.filter(<span style=\"color:#00a\">function<\/span>(impression) {\n    <span style=\"color:#00a\">return<\/span> impression.id === targetElement.getAttribute(productIdAttribute);\n  }).shift();\n\n  <span style=\"color:#00a\">var<\/span> impressionsArr = batch.map(<span style=\"color:#00a\">function<\/span>(id) {\n    <span style=\"color:#00a\">return<\/span> impressions.filter(<span style=\"color:#00a\">function<\/span>(impression) {\n      <span style=\"color:#00a\">return<\/span> impression.id === id;\n    }).shift();\n  });\n  \n  <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.elementVisibility'<\/span>){\n    impressionsArr[maxBatch - <span style=\"color:#099\">1<\/span>] = latestImpression;\n  }\n\n  ecomObj.impressions = impressionsArr; \n\n  <span style=\"color:#00a\">if<\/span> (event === <span style=\"color:#a50\">'gtm.click'<\/span>) {\n    ecomObj.click = {\n      actionField: {\n        list: latestImpression.list\n      },\n      products: [latestImpression]\n    };\n  }\n  <span style=\"color:#00a\">return<\/span> {\n    ecommerce: ecomObj\n  };\n}\n<\/code><\/pre>\n<\/div>\n<p>As you can see, you\u2019ll need to configure the <strong>exact<\/strong> same settings (<code>maxBatch<\/code>, <code>batchVariableName<\/code>, <code>productIdAttribute<\/code>) in the beginning of this script as you had to in the <a href=\"https:\/\/www.simoahava.com\/analytics\/true-view-impressions-google-tag-manager\/#js-function-true-view-impression-handler\">previous Custom JavaScript variable<\/a>. It\u2019s important that these match <strong>exactly<\/strong> to the settings you configured earlier, so double-check to make sure they are the same.<\/p>\n<p>Other than that, the purpose of the JavaScript is to compile the impression product IDs in the batch queue to the corresponding Enhanced Ecommerce objects. If the event was a click, then the impression that was clicked will be sent as the Product Click target.<\/p>\n<h2 id=\"create-the-triggers\">Create the triggers<\/h2>\n<p>We\u2019ll need a whopping <strong>four<\/strong> triggers all attached to the tag.<\/p>\n<p>An <strong>Element Visibility<\/strong> trigger will handle building the batch queue from product impression views.<\/p>\n<p>A <strong>Custom Event<\/strong> trigger will fire the tag when the user is trying to leave the page.<\/p>\n<p>A <strong>Timer<\/strong> trigger will send the items in the batch queue periodically.<\/p>\n<p>A <strong>Click<\/strong> trigger will fire the tag when the user clicks a product impression.<\/p>\n<h3 id=\"the-element-visibility-trigger\">The Element Visibility trigger<\/h3>\n<p>The Element Visibility trigger will fire whenever a <strong>new<\/strong> product impression becomes visible. It will only fire once per element, which ensures that those elements for which an impression hit has already been sent won\u2019t get another impression sent while the user is on the page.<\/p>\n<p>The Element Visibility trigger will be set to fire when any element with the give <strong>product ID attribute<\/strong> becomes visible. It\u2019s important that you use the <strong>same attribute name<\/strong> you used in the two Custom JavaScript variables created above. If the attribute name was, for example, <code>data-productid<\/code>, the CSS selector you\u2019d need to configure in the Element Visibility trigger should be <code>[data-productid]<\/code>. Check <a href=\"https:\/\/www.simoahava.com\/gtm-tips\/10-useful-css-selectors\/\">this<\/a> if you need a refresher on CSS selectors.<\/p>\n<p>Anyway, make sure the trigger looks like something like this (with the change in the CSS selector if needed):<\/p>\n<div style=\"aspect-ratio: 1842 \/ 1194;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/visibility-trigger.jpg\" title=\"Visibility trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1194\" width=\"1842\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/visibility-trigger.jpg#ZgotmplZ\" alt=\"Visibility trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>You can change the percentage of the element that needs to be visible if you wish.<\/p>\n<h3 id=\"the-custom-event-trigger\">The Custom Event trigger<\/h3>\n<p>The Custom Event trigger is simple. It fires whenever the <code>beforeunload<\/code> listener (created in <a href=\"https:\/\/www.simoahava.com\/analytics\/true-view-impressions-google-tag-manager\/#js-function-true-view-impression-handler\">the <code>customTask<\/code> variable<\/a>) is triggered by the user trying to leave the page.<\/p>\n<div style=\"aspect-ratio: 1844 \/ 616;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/custom-event-trigger.jpg\" title=\"Custom Event trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"616\" width=\"1844\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/custom-event-trigger.jpg#ZgotmplZ\" alt=\"Custom Event trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"the-timer-trigger\">The Timer trigger<\/h3>\n<p>The Timer trigger will dispatch the items in the queue when it goes off. It\u2019s a good backup to have, because otherwise you run the risk of items being left in the queue indefinitely, only to be dispatched when the user triggers another visibility event some time in the future. This might lead to hermit sessions, where the only hits are these impression view hits. Not very useful.<\/p>\n<p>You can freely modify the settings of the trigger. Having it fire continuously isn\u2019t that big a deal. The Google Analytics tag will always fire, yes, but the <code>customTask<\/code> will make sure that no hit is actually built unless the batch queue actually has items in it.<\/p>\n<p>As you can see, I also make sure that the timer trigger only fires on valid pages by checking if a Data Layer variable for the key <code>ecommerce.impressions<\/code> is not <code>undefined<\/code>. This way the trigger will only activate on pages where there\u2019s the possibility of viewing impressions. You can change the condition to something else if it makes more sense.<\/p>\n<div style=\"aspect-ratio: 1840 \/ 932;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/timer-trigger.jpg\" title=\"Timer trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"932\" width=\"1840\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/timer-trigger.jpg#ZgotmplZ\" alt=\"Timer trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"the-click-trigger\">The Click trigger<\/h3>\n<p>The Click trigger has a simple purpose. It fires when a product impression is clicked, thus sending a Product Click payload to Google Analytics (along with any impressions that might have been in the batch queue).<\/p>\n<p>Remember to change the CSS selector to match the HTML attribute you use to encode the product ID for every product impression element on the page.<\/p>\n<p>If you\u2019re curious about the <code>[data-productid], [data-productid] *<\/code> syntax, take a look at <a href=\"https:\/\/www.simoahava.com\/analytics\/use-wildcard-css-selectors-with-all-elements-triggers\/\">this article<\/a>.<\/p>\n<div style=\"aspect-ratio: 1842 \/ 488;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/click-trigger.jpg\" title=\"Click trigger\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"488\" width=\"1842\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/click-trigger.jpg#ZgotmplZ\" alt=\"Click trigger\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h2 id=\"create-the-tag\">Create the tag<\/h2>\n<p>Finally, the tag itself. Now that you have all the necessary variables and triggers created, it\u2019s just a question of putting them all together in the tag.<\/p>\n<p>Feel free to modify what you send with <strong>Event Category<\/strong>, <strong>Event Action<\/strong>, and <strong>Event Label<\/strong>.<\/p>\n<p>Make sure you have the <code>transport<\/code> field set to <code>beacon<\/code>, since you\u2019ll want those <code>beforeunload<\/code> hits to be sent <a href=\"https:\/\/www.simoahava.com\/analytics\/fire-trigger-when-user-about-to-leave-page\/#set-the-transport-field-in-google-analytics-tags\">even if the page has already been unloaded<\/a>.<\/p>\n<ul>\n<li>\n<p><strong>Tag Type<\/strong>: Universal Analytics<\/p>\n<\/li>\n<li>\n<p><strong>Track Type<\/strong>: Event<\/p>\n<\/li>\n<li>\n<p><strong>Category<\/strong>: Ecommerce<\/p>\n<\/li>\n<li>\n<p><strong>Action<\/strong>: Impressions<\/p>\n<\/li>\n<li>\n<p><strong>Label<\/strong>: {{Lookup &#8211; Get Impression Label}}<\/p>\n<\/li>\n<li>\n<p><strong>Non-Interaction Hit<\/strong>: {{Lookup &#8211; Get Impression Interaction}}<\/p>\n<\/li>\n<li>\n<p><strong>Enable overriding settings in this tag<\/strong>: Checked<\/p>\n<\/li>\n<li>\n<p><strong>Tracking ID<\/strong>: UA-XXXXXX-Y<\/p>\n<\/li>\n<li>\n<p><strong>Fields to Set<\/strong>:<br \/>\u2013 <strong>Field Name<\/strong>: <code>customTask<\/code>, <strong>Value<\/strong>: {{JS &#8211; Function &#8211; True view impression handler}}<br \/>\u2013 <strong>Field Name<\/strong>: <code>transport<\/code>, <strong>Value<\/strong>: <code>beacon<\/code><\/p>\n<\/li>\n<li>\n<p><strong>Enable Enhanced Ecommerce Features<\/strong>: True<br \/>\u2013 <strong>Read Data from Variable<\/strong>: {{JS &#8211; Get True View object}}<\/p>\n<\/li>\n<\/ul>\n<div style=\"aspect-ratio: 1844 \/ 1856;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-event-tag-1.jpg\" title=\"Impression event tag\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1856\" width=\"1844\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-event-tag-1.jpg#ZgotmplZ\" alt=\"Impression event tag\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Finally, add all four triggers created in the previous chapter to this tag.<\/p>\n<div style=\"aspect-ratio: 1834 \/ 694;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-event-tag-2.jpg\" title=\"Impression event tag 2\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"694\" width=\"1834\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-event-tag-2.jpg#ZgotmplZ\" alt=\"Impression event tag 2\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>And you\u2019re all set! Then it\u2019s time to test things out.<\/p>\n<h2 id=\"how-to-test\">How to test<\/h2>\n<p>It\u2019s important <strong>not<\/strong> to rely on Google Tag Manager\u2019s debug mode to test this out. Why? Because even if it says that a Google Analytics tag has fired, it\u2019s <code>customTask<\/code> that governs whether the request was completed or not.<\/p>\n<p>So, I recommend you install David Vallejo\u2019s excellent <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/gtmga-debug\/ilnpmccnfdjdjjikgkefkcegefikecdc?hl=en\">GTM\/GA Debug<\/a> extension. It shows you what hits are actually sent to Google Analytics, and it has an excellent Enhanced Ecommerce tab for seeing exactly what impressions are dispatched.<\/p>\n<h3 id=\"test-the-batch-queue-first\">Test the batch queue first<\/h3>\n<p>When a page with impression loads, test how your batch queue works.<\/p>\n<p>You should see one <code>gtm.elementVisibility<\/code> event in the Debug mode panel for every product impression you see in the viewport of the page. These events should not dispatch the hit to GA <strong>until you reach the same number of visibility events as the maximum queue size<\/strong>.<\/p>\n<p>So if you\u2019ve configured the <code>maxBatch<\/code> in the Custom JavaScript variables to 10, then the first nine <code>gtm.elementVisibility<\/code> events should do nothing, but the tenth one should fire an Impressions hit with ten impressions within. And after that, every tenth visibility event should send another batch, etc.<\/p>\n<div style=\"aspect-ratio: 1862 \/ 1040;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-views-test.jpg\" title=\"Impression views test\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1040\" width=\"1862\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/impression-views-test.jpg#ZgotmplZ\" alt=\"Impression views test\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"test-with-a-timer\">Test with a timer<\/h3>\n<p>Next, make sure you have some Element Visibility triggers fired after the previous batch has been sent, but not enough to send another batch. In other words, you want the queue to contain some impressions, but not enough to trigger a batch dispatch.<\/p>\n<p>Then, wait for the Timer trigger to go off. It will fire as soon as the interval is reached. In this guide, I\u2019m using a 60 second interval, so within one minute of the page load the trigger should fire. When the trigger fires, it should send the items in the batch queue as an impression hit. The number of impressions should be less than what would be sent if the queue filled up.<\/p>\n<p>For example, here the batch queue limit has been reached twice, sending two sets of three impressions to Google Analytics. The third impression hit with just one impression is due to the timer trigger sending the remaining impression.<\/p>\n<div style=\"aspect-ratio: 1708 \/ 1040;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/timer-test.jpg\" title=\"Timer test\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1040\" width=\"1708\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/timer-test.jpg#ZgotmplZ\" alt=\"Timer test\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"test-a-product-click\">Test a product click<\/h3>\n<p>Again, scroll until the queue has items but not enough to fill the queue up to its maximum length. Then, click one product impression. What you should see is an Enhanced Ecommerce hit with the Product Click details of the impression that was clicked, <strong>and a list of impression views that were in the queue<\/strong>.<\/p>\n<div style=\"aspect-ratio: 2350 \/ 624;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/click-test.jpg\" title=\"Click trigger test\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"624\" width=\"2350\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/click-test.jpg#ZgotmplZ\" alt=\"Click trigger test\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"test-the-beforeunload-listener\">Test the <code>beforeunload<\/code> listener<\/h3>\n<p>Finally, scroll until the queue has items but not enough to fill the queue. Then, click a link away from the current page (not a product impression!). Using the GTM\/GA Debug extension, you should see the hits for the previous page including an impression view hit with some impressions (less than the maximum queue length):<\/p>\n<div style=\"aspect-ratio: 1966 \/ 516;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/01\/beforeunload-test.jpg\" title=\"Beforeunload test\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"516\" width=\"1966\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/01\/beforeunload-test.jpg#ZgotmplZ\" alt=\"Beforeunload test\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h2 id=\"final-words\">Final words<\/h2>\n<p>This is a fairly simple implementation. The \u201ccatch\u201d is that it doesn\u2019t use a Custom HTML tag. Everything is handled through a single Universal Analytics tag, utilizing the power of <code>customTask<\/code> to get the work done.<\/p>\n<p>It\u2019s not perfect. Without a Custom HTML tag, you\u2019ll need to use the default Timer trigger which leaves a lot to be desired. For example, optimally I\u2019d want to create a custom timer that would let me reset it whenever the batch queue is cleared and the first new item is added. That way the timer would not fire needlessly on the page. This isn\u2019t really doable in the <code>customTask<\/code> &#8211; you would need a Custom HTML tag to do it.<\/p>\n<p>And why not use a Custom HTML tag? For one, this is a fun exercise to do. The other reason is that GTM has a fairly robust thing going on with the Element Visibility trigger, and I want to make use of it without polluting the page with numerous Custom HTML tags; one for every product impression found by the Element Visibility trigger.<\/p>\n<p>Some might also consider the prerequisites unreasonable. Being forced to have an Enhanced Ecommerce <code>dataLayer<\/code> object AND the HTML elements decorated with custom data attributes might seem like too much work. It\u2019s a lot of work, but not <strong>too much<\/strong> work. Tracking impressions reliably by utilizing the Element Visibility trigger requires a strong link between the items on the page and those in the <code>dataLayer<\/code>. You could build your own custom system to support DOM scraping and custom <code>dataLayer<\/code> object compositions, but I\u2019ll leave that to your capable hands.<\/p>\n<p>Anyway, I hope you found this guide inspiring. Let me know in the comments what you think!<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>Last updated 9 October 2020: customTask updated to a more stable version. I\u2019m a big fan of Enhanced Ecommerce in Google Analytics. In fact, I think it\u2019s the only valid way to deploy Ecommerce tracking today, especially when using Google Tag Manager. The ability to use a Custom JavaScript variable and the possibility to tackle [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":101002,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[11161,1531,14982,14495,1791,5053,10183],"dealstore":[],"offerexpiration":[],"class_list":["post-101001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-ecommerce","tag-google","tag-impressions","tag-manager","tag-tag","tag-true","tag-view"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>True View Ecommerce Impressions With Google Tag Manager - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=101001\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"True View Ecommerce Impressions With Google Tag Manager - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"Last updated 9 October 2020: customTask updated to a more stable version. I\u2019m a big fan of Enhanced Ecommerce in Google Analytics. In fact, I think it\u2019s the only valid way to deploy Ecommerce tracking today, especially when using Google Tag Manager. The ability to use a Custom JavaScript variable and the possibility to tackle [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=101001\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-21T06:57:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2408\" \/>\n\t<meta property=\"og:image:height\" content=\"1078\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=101001#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"True View Ecommerce Impressions With Google Tag Manager\",\"datePublished\":\"2025-02-21T06:57:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001\"},\"wordCount\":3268,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg\",\"keywords\":[\"ECommerce\",\"Google\",\"impressions\",\"Manager\",\"TAG\",\"TRUE\",\"View\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=101001#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=101001\",\"url\":\"https:\/\/fivemor.com\/?p=101001\",\"name\":\"True View Ecommerce Impressions With Google Tag Manager - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg\",\"datePublished\":\"2025-02-21T06:57:11+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=101001#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=101001\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=101001#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg\",\"width\":2408,\"height\":1078},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=101001#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"True View Ecommerce Impressions With Google Tag Manager\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"True View Ecommerce Impressions With Google Tag Manager - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=101001","og_locale":"en_US","og_type":"article","og_title":"True View Ecommerce Impressions With Google Tag Manager - Som2ny Network","og_description":"Last updated 9 October 2020: customTask updated to a more stable version. I\u2019m a big fan of Enhanced Ecommerce in Google Analytics. In fact, I think it\u2019s the only valid way to deploy Ecommerce tracking today, especially when using Google Tag Manager. The ability to use a Custom JavaScript variable and the possibility to tackle [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=101001","og_site_name":"Som2ny Network","article_published_time":"2025-02-21T06:57:11+00:00","og_image":[{"width":2408,"height":1078,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=101001#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=101001"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"True View Ecommerce Impressions With Google Tag Manager","datePublished":"2025-02-21T06:57:11+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=101001"},"wordCount":3268,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=101001#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg","keywords":["ECommerce","Google","impressions","Manager","TAG","TRUE","View"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=101001#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=101001","url":"https:\/\/fivemor.com\/?p=101001","name":"True View Ecommerce Impressions With Google Tag Manager - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=101001#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=101001#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg","datePublished":"2025-02-21T06:57:11+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=101001#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=101001"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=101001#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/true-view-impressions-google-tag-manager.jpg","width":2408,"height":1078},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=101001#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"True View Ecommerce Impressions With Google Tag Manager"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/101001","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=101001"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/101001\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/101002"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=101001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=101001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=101001"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=101001"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=101001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}