{"id":159783,"date":"2025-03-27T13:47:14","date_gmt":"2025-03-27T13:47:14","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/google-tag-managers-data-model\/"},"modified":"2025-03-27T13:47:14","modified_gmt":"2025-03-27T13:47:14","slug":"google-tag-managers-data-model","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=159783","title":{"rendered":"Google Tag Manager&#8217;s Data Model"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>It\u2019s time for <a href=\"http:\/\/www.measurecamp.org\/\">MeasureCamp<\/a> again! As <a href=\"https:\/\/www.simoahava.com\/analytics\/macro-magic-google-tag-manager\/\">before<\/a>, I want to write an accompanying post for my session, since there\u2019s always so much more to say than the time slot allows for. So, the topic of this article is the data model used by <a href=\"https:\/\/www.google.com\/tagmanager\">Google Tag Manager<\/a> to process digital data in your data layer.<\/p>\n<p>This post also picks up where I left in my previous foray into the <a href=\"https:\/\/www.simoahava.com\/analytics\/data-layer\/\">data layer<\/a>. However, where the first article aimed to be generic (since the data layer should be generic), this post will look at how GTM uses the information in the generic data layer, and how it processes this information to work with the proprietary features of the tool.<\/p>\n<div style=\"aspect-ratio: 724 \/ 479;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-model.jpg\" title=\"Data Model for Google Tag Manager\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"479\" width=\"724\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-model.jpg#ZgotmplZ\" alt=\"Data Model for Google Tag Manager\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The diagram above should elucidate my point (fear my PowerPoint-to-image skills).<\/p>\n<p>We have data passing through your backend systems to your website. Some of this data is used to build the website with its visuals and functionalities, and some of this data is stored in the data layer to be used by other tools and applications connected to the website.<\/p>\n<p>Google Tag Manager doesn\u2019t access the data layer\u2019s structure directly, since that would compromise the data layer\u2019s generic and tool-agnostic purpose. Rather, it pulls data from the data layer, stores it in its internal, abstract data model, and uses <em>that<\/em> to process the digital data.<\/p>\n<p>Since we live in a multi-vendor world, where web tools and applications are popping up like mushrooms after rain, it\u2019s important to respect the generic data layer. It\u2019s up to the sophistication of the tool itself to use this data, but it must be done in a non-invasive manner &#8211; using pull methods rather than push.<\/p>\n<table>\n<thead>\n<tr>\n<th><strong>dataLayer<\/strong><\/th>\n<th><strong>Data Model<\/strong><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Tool-agnostic<\/td>\n<td>Tool-specific<\/td>\n<\/tr>\n<tr>\n<td>Generic<\/td>\n<td>Unique<\/td>\n<\/tr>\n<tr>\n<td>Accessed directly<\/td>\n<td>Accessed via helper<\/td>\n<\/tr>\n<tr>\n<td>Structured<\/td>\n<td>Abstract<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>There\u2019s a difference between data layer and data model. To some it might seem very subtle, but in reality it\u2019s what ensures that the data layer remains a free-for-all, standardized container for data. The data model, on the other hand, is built according to each platform\u2019s own specifications, but the way it communicates with the data layer must be clean and perhaps even standardized, since only that way can we ensure that a single tool doesn\u2019t ruin the data layer for all.<\/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=\"setting-up-the-test\">Setting up the test<\/h2>\n<p>The most familiar way of accessing GTM\u2019s data model is through the Data Layer Variable Macro. When you call this macro type, the following happens:<\/p>\n<ul>\n<li>\n<p>The macro polls the data model through an interface method<\/p>\n<\/li>\n<li>\n<p>If a key with the given variable name is found, its value is returned<\/p>\n<\/li>\n<li>\n<p>If no key is found, <code>undefined<\/code> is returned instead<\/p>\n<\/li>\n<\/ul>\n<p>For the purposes of this article, I\u2019ll now create a tester, which shows you how the data model works. The tester is a Custom HTML Tag which fires upon a certain event (\u2018dlTest\u2019). When it fires, it prints the content of the Data Layer Variable Macro into the JavaScript console.<\/p>\n<div style=\"aspect-ratio: 798 \/ 444;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-layer-tester.jpg\" title=\"Data Layer Tester\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"444\" width=\"798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-layer-tester.jpg#ZgotmplZ\" alt=\"Data Layer Tester\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The macro itself is just a Data Layer Macro which refers to variable name <strong>testKey<\/strong>:<\/p>\n<div style=\"aspect-ratio: 395 \/ 568;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-layer-macro.jpg\" title=\"Data Layer Variable Macro\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"568\" width=\"395\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/data-layer-macro.jpg#ZgotmplZ\" alt=\"Data Layer Variable Macro\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>So now, whenever I want to see what the key <strong>testKey<\/strong> contains in the data model, I only have to type the following in the console:<\/p>\n<p><code>dataLayer.push({'event' : 'dlTest'});<\/code><\/p>\n<p>Next, I\u2019ll publish my container, and try this out. This is what the console looks like now if I run the event:<\/p>\n<div style=\"aspect-ratio: 316 \/ 118;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/test-macro.jpg\" title=\"Test Data Layer Macro\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"118\" width=\"316\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/test-macro.jpg#ZgotmplZ\" alt=\"Test Data Layer Macro\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The <code>undefined<\/code> is what the macro actually returns. <strong>false<\/strong> is returned because the event push triggered a tag.<\/p>\n<h2 id=\"add-and-modify-the-key\">Add and modify the key<\/h2>\n<p>Let\u2019s start simple. I\u2019ll add some values to the key, and see how the macro reacts:<\/p>\n<div style=\"aspect-ratio: 644 \/ 352;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/test-add-values.jpg\" title=\"Test Adding Values To Data Model\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"352\" width=\"644\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/test-add-values.jpg#ZgotmplZ\" alt=\"Test Adding Values To Data Model\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here are the pushes in order:<\/p>\n<ol>\n<li>\n<p><code>'string'<\/code> &#8211; <em>string<\/em><\/p>\n<\/li>\n<li>\n<p><code>1<\/code> &#8211; <em>number<\/em><\/p>\n<\/li>\n<li>\n<p><code>[1, 2, 3<\/code>] &#8211; <em>Array<\/em><\/p>\n<\/li>\n<li>\n<p><code>{'key' : 'value'}<\/code> &#8211; <em>object<\/em><\/p>\n<\/li>\n<li>\n<p><code>true<\/code> &#8211; <em>boolean<\/em><\/p>\n<\/li>\n<li>\n<p><code>function() { return undefined; }<\/code> &#8211; <em>function<\/em><\/p>\n<\/li>\n<\/ol>\n<p>As you can see, the interface <code>get()<\/code> function only returns the latest value. <code>dataLayer<\/code>, however, holds all the values:<\/p>\n<div style=\"aspect-ratio: 798 \/ 102;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/datalayer-after-push.jpg\" title=\"dataLayer after push\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"102\" width=\"798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/datalayer-after-push.jpg#ZgotmplZ\" alt=\"dataLayer after push\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here are the key takeaways:<\/p>\n<ul>\n<li>\n<p>The data model is not the same thing as data layer. All the values I pushed above can be found in the data layer, but only the most recent value is stored in the data model<\/p>\n<\/li>\n<li>\n<p>When pushing a value of different type, the previous value is completely overwritten in the data model<\/p>\n<\/li>\n<\/ul>\n<p>That\u2019s pretty simple, right? Well, let\u2019s try updating the value with another value of the <em>same type<\/em> next.<\/p>\n<div style=\"aspect-ratio: 578 \/ 450;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/push-same-value.jpg\" title=\"Push the same type\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"450\" width=\"578\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/push-same-value.jpg#ZgotmplZ\" alt=\"Push the same type\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here are the pushes in order:<\/p>\n<ol>\n<li>\n<p><code>'string'<\/code> + <code>'newString'<\/code> =&gt; <code>'newString'<\/code><\/p>\n<\/li>\n<li>\n<p><code>1<\/code> + <code>5<\/code> =&gt; <code>5<\/code><\/p>\n<\/li>\n<li>\n<p><code>[1, 2, 3]<\/code> + <code>[4, 5]<\/code> =&gt; <code>[4, 5, 3]<\/code> *<strong>HUH?<\/strong><\/p>\n<\/li>\n<li>\n<p><code>{'key' : 'value'}<\/code> + <code>{'newKey' : 'value'}<\/code> =&gt; <code>{'key' : 'value', 'newKey' : 'value'}<\/code> *<strong>WTF?<\/strong><\/p>\n<\/li>\n<\/ol>\n<p>The primitive values work as expected. Pushing another value of the same type just overwrites the previous value. However, the Array and the plain object behave very strangely.<\/p>\n<p>This is because when you\u2019re pushing an Array on top of an Array or a plain object on top of a plain object, the interface performs a <em>recursive merge<\/em>. That is, it checks whether the keys within the object or Array that are being pushed already exist. If they do, their values are updated, but all the other keys are left alone.<\/p>\n<p>It\u2019s easy to understand if you look at how the plain object behaves.<\/p>\n<p>First, you push an object with the key <strong>\u2018key\u2019<\/strong> with the value <strong>\u2018value\u2019<\/strong>. Next, you push an object with the key <strong>\u2018newKey\u2019<\/strong> with the value <strong>\u2018value\u2019<\/strong>. Now, <strong>\u2018key\u2019<\/strong> is not the same thing as <strong>\u2018newKey\u2019<\/strong>, so the plain object is <em>updated<\/em>, not replaced.<\/p>\n<p>But what about the Array? I\u2019m pushing <code>[4, 5]<\/code>, which have nothing in common with <code>[1, 2, 3]<\/code>. Shouldn\u2019t the end result be<\/p>\n<p><code>[4, 5]<\/code>, or<br \/>\n<code>[1, 2, 3, 4, 5]<\/code>, or even<br \/>\n<code>[[1, 2, 3], [4, 5]]<\/code>?<\/p>\n<p>Surely <code>[4, 5, 3]<\/code> is a bug?<\/p>\n<p>Nope, if you know your JavaScript. An Array is a type of an object. It, too, has keys with which you can access the values within. The keys start from 0 and go up until there are no more members in the Array. So, the first Array looks actually something like this:<\/p>\n<p><code>[1, 2, 3]<\/code><br \/>\nKey 0 : Value 1<br \/>\nKey 1 : Value 2<br \/>\nKey 2 : Value 3<\/p>\n<p>The second Array looks like this:<\/p>\n<p><code>[4, 5]<\/code><br \/>\nKey 0 : Value 4<br \/>\nKey 1 : Value 5<\/p>\n<p>Now, the recursive merge spots these shared keys (0 and 1), and updates their values accordingly. The third key (2) is not touched, since the Array that was pushed second had no value for it.<\/p>\n<p>We\u2019ll explore how to add data to existing Arrays soon enough.<\/p>\n<h2 id=\"removing-a-key-from-the-data-model\">Removing a key from the data model<\/h2>\n<p>If you have a single page app, and the data layer persist throughout the session, you might want to delete some variables from the data model every now and then. Just removing the key from <code>dataLayer<\/code> won\u2019t be enough:<\/p>\n<div style=\"aspect-ratio: 500 \/ 216;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/remove-key.jpg\" title=\"Delete Key from Data Layer\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"216\" width=\"500\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/remove-key.jpg#ZgotmplZ\" alt=\"Delete Key from Data Layer\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here\u2019s what happens:<\/p>\n<ol>\n<li>\n<p>I push \u2018simoahava\u2019 as the value of \u2018testKey\u2019, this is registered by the macro<\/p>\n<\/li>\n<li>\n<p>I delete this entire object from <code>dataLayer<\/code><\/p>\n<\/li>\n<li>\n<p>I verify this by looking at the contents of <code>dataLayer<\/code><\/p>\n<\/li>\n<li>\n<p>However, the data model still holds the latest value<\/p>\n<\/li>\n<\/ol>\n<p>This is actually an important feature of the data model. The data model treats <code>dataLayer<\/code> as a <em>queue<\/em> or a message bus, if you will. It operates on a first in, first out principle, meaning that as soon as something is pushed into <code>dataLayer<\/code>, it is processed and its values are stored into the data model.<\/p>\n<p>It wouldn\u2019t work if the data model should remove a key if it is dropped from <code>dataLayer<\/code>. You might have multiple pushes of the same key with different values (take \u2018event\u2019, for example). How would the data model know if you\u2019re just cleaning up objects from the global Array structure rather than asking for them to be removed from the data model?<\/p>\n<p>A remove method in the interface might be a good idea, but it\u2019s just as easy to take the generic approach and push <code>undefined<\/code> as the value of the key. This will store <code>undefined<\/code> into the data model as well, meaning it will be, for all intents and purposes, as if the key no longer exists.<\/p>\n<div style=\"aspect-ratio: 502 \/ 152;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/push-undefined.jpg\" title=\"Push undefined to remove key\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"152\" width=\"502\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/push-undefined.jpg#ZgotmplZ\" alt=\"Push undefined to remove key\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>That\u2019s how simple it is.<\/p>\n<h2 id=\"the-command-array\">The command array<\/h2>\n<p>This is where I left you hanging earlier. Say you want to update an Array by adding members to the end or into the middle. It\u2019s very difficult to do in a generic way, since you first need to retrieve the Array from the data model, add members to the end or to the middle, and then push it back. And all has to happen within the data layer, because you don\u2019t want all the other tools and platforms that use the data layer to be left outside.<\/p>\n<p>The way to do this is to use a special <em>command array<\/em>. It enables you to access methods of the value type you have stored in the data model.<\/p>\n<p>Here\u2019s how it works. I\u2019m going to update an Array <code>[1, 3]<\/code> first with two new members using <code>push()<\/code>, so that it becomes <code>[1, 3, 4, 5]<\/code>. Next I\u2019ll do a <code>splice()<\/code>, where I add the number 2 to its rightful place. Observe closely.<\/p>\n<div style=\"aspect-ratio: 527 \/ 201;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/command-array.jpg\" title=\"Command Array\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"201\" width=\"527\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/command-array.jpg#ZgotmplZ\" alt=\"Command Array\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As you can see, the command array has its special syntax. First of all, you need to push an Array into the data layer, <strong>not<\/strong> an object as you normally would.<\/p>\n<p>Next, the first member of the Array needs to be a string which holds the actual command. All the rest of the members in the command array are arguments to this command.<\/p>\n<p>Thus, <code>testKey.push(4,5)<\/code> becomes <code>['testKey.push', 4, 5]<\/code>, and <code>testKey.splice(1,0,2)<\/code> becomes <code>['testKey.splice', 1, 0, 2]<\/code>.<\/p>\n<p>This way you can do some cool things with the values stored in the data model without having to access them directly. Using the data layer ensures that other tools and applications can benefit from your modifications as well.<\/p>\n<h2 id=\"custom-methods\">Custom methods<\/h2>\n<p>The last thing I\u2019ll show you is how to perform some custom transformations on the values stored in the data model.<\/p>\n<p>Let\u2019s say I\u2019m storing a bunch of products and stores in the data layer. This data is provided by the backend system. As it turns out, one of the store names is misspelled, and this needs to be fixed in the data model. Performing a series of gets and sets would be cumbersome and very ineffective. Instead, I can just push a function which does this whole thing in a simple for-loop.<\/p>\n<div style=\"aspect-ratio: 472 \/ 611;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/09\/custom-method.jpg\" title=\"Push a custom method\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"611\" width=\"472\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/09\/custom-method.jpg#ZgotmplZ\" alt=\"Push a custom method\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>When you push a function into the data layer, <code>this<\/code> will be the interface of the data model on the page. It exposes two methods: <code>get(key)<\/code> and <code>set(key, value)<\/code>.<\/p>\n<p>First, I use <code>get()<\/code> to retrieve the value of <code>'testKey'<\/code>. Then, I do a for-loop which goes over each member in the <code>'testKey'<\/code> Array, looking for the typo. If a typo is found, then it\u2019s corrected there and then. Because I\u2019m dealing with objects, you don\u2019t have to push anything back into the data model, since you\u2019ve actually copied an object reference, not the object itself.<\/p>\n<p>Don\u2019t worry about that object mumbo-jumbo. The key here is that I performed a transformation on the data in the data model by using the data layer. This way other vendors and tools can benefit from the change as well. I could have just as well directly accessed the public method of the interface, but that would not be the generic way to do things.<\/p>\n<h2 id=\"summary\">Summary<\/h2>\n<p>This has been a complicated post, I know, but here are the things you should have learned.<\/p>\n<ul>\n<li>\n<p>The data layer on the page and the data model used by the tag manager are not the same thing<\/p>\n<\/li>\n<li>\n<p>The data layer is generic, tool-agnostic, and can be accessed by all applications that can tap into the global namespace<\/p>\n<\/li>\n<li>\n<p>The data model is internal to the tag manager, it\u2019s abstract (no Arrays here), and it has a public interface with just two methods<\/p>\n<\/li>\n<li>\n<p>Certain values (Arrays, plain objects) behave erratically when you try to update them with a regular push<\/p>\n<\/li>\n<li>\n<p>You should always do all additions, removals, and transformations by using the data layer, and not by accessing the interface of the data model directly<\/p>\n<\/li>\n<\/ul>\n<p>If you want to geek it up a little, take a look at the <a href=\"https:\/\/github.com\/google\/data-layer-helper\">Data Layer Helper<\/a> specification in GitHub, written by GTM\u2019s own Brian Kuhn. That\u2019s where most of the lessons here were picked up.<\/p>\n<p>It\u2019s so important to understand the subtleties of the data layer and the data model. The one is (or should be) tool-independent, the other is a proprietary feature of the tool. One can be standardized to serve multiple vendors and platforms, the other should cater to the idiosyncrasies of each tool separately.<\/p>\n<p><a href=\"http:\/\/www.slideshare.net\/mobile\/SimoAhava\/google-tag-manager-for-nerds\">My presentation \u201cGoogle Tag Manager For Nerds\u201d from MeasureCamp V<\/a><\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>It\u2019s time for MeasureCamp again! As before, I want to write an accompanying post for my session, since there\u2019s always so much more to say than the time slot allows for. So, the topic of this article is the data model used by Google Tag Manager to process digital data in your data layer. This [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":159784,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[11603,1531,11419,1168,1791],"dealstore":[],"offerexpiration":[],"class_list":["post-159783","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-data","tag-google","tag-managers","tag-model","tag-tag"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Google Tag Manager&#039;s Data Model - 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=159783\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Google Tag Manager&#039;s Data Model - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"It\u2019s time for MeasureCamp again! As before, I want to write an accompanying post for my session, since there\u2019s always so much more to say than the time slot allows for. So, the topic of this article is the data model used by Google Tag Manager to process digital data in your data layer. This [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=159783\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-27T13:47:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"724\" \/>\n\t<meta property=\"og:image:height\" content=\"479\" \/>\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=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=159783#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Google Tag Manager&#8217;s Data Model\",\"datePublished\":\"2025-03-27T13:47:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783\"},\"wordCount\":2057,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg\",\"keywords\":[\"Data\",\"Google\",\"Managers\",\"Model\",\"TAG\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=159783#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=159783\",\"url\":\"https:\/\/fivemor.com\/?p=159783\",\"name\":\"Google Tag Manager's Data Model - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg\",\"datePublished\":\"2025-03-27T13:47:14+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=159783#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=159783\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=159783#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg\",\"width\":724,\"height\":479},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=159783#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Google Tag Manager&#8217;s Data Model\"}]},{\"@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":"Google Tag Manager's Data Model - 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=159783","og_locale":"en_US","og_type":"article","og_title":"Google Tag Manager's Data Model - Som2ny Network","og_description":"It\u2019s time for MeasureCamp again! As before, I want to write an accompanying post for my session, since there\u2019s always so much more to say than the time slot allows for. So, the topic of this article is the data model used by Google Tag Manager to process digital data in your data layer. This [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=159783","og_site_name":"Som2ny Network","article_published_time":"2025-03-27T13:47:14+00:00","og_image":[{"width":724,"height":479,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=159783#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=159783"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Google Tag Manager&#8217;s Data Model","datePublished":"2025-03-27T13:47:14+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=159783"},"wordCount":2057,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=159783#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg","keywords":["Data","Google","Managers","Model","TAG"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=159783#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=159783","url":"https:\/\/fivemor.com\/?p=159783","name":"Google Tag Manager's Data Model - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=159783#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=159783#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg","datePublished":"2025-03-27T13:47:14+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=159783#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=159783"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=159783#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/data-model.jpg","width":724,"height":479},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=159783#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Google Tag Manager&#8217;s Data Model"}]},{"@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\/159783","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=159783"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/159783\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/159784"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=159783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=159783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=159783"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=159783"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=159783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}