{"id":161988,"date":"2025-03-28T15:49:12","date_gmt":"2025-03-28T15:49:12","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/persist-datalayer-in-google-tag-manager\/"},"modified":"2025-03-28T15:49:12","modified_gmt":"2025-03-28T15:49:12","slug":"persist-datalayer-in-google-tag-manager","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=161988","title":{"rendered":"Persist dataLayer In Google Tag Manager"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>(Update 19 November 2018: See <a href=\"https:\/\/www.simoahava.com\/analytics\/persist-datalayer-across-pages\/\">this article<\/a> for a more elegant solution.)<\/p>\n<p>If you know your <a href=\"https:\/\/www.simoahava.com\/analytics\/javascript-101-gtm-part-1\/\">JavaScript<\/a>, you know that all variables, functions, objects, resources, and data in the document get rewritten with every page load. In other words, every single page refresh builds the page from scratch, and the state of the document before the page refresh is left drifting in the ocean of oblivion.<\/p>\n<p><a href=\"https:\/\/www.google.com\/tagmanager\">Google Tag Manager<\/a>\u2019s dataLayer is also one such entity. It gets rewritten with every page load, so it\u2019s not possible to have a dataLayer variable <em>persist<\/em> from one page to the other without using cookies or, as I\u2019m going to show in this guide, the <a href=\"http:\/\/www.w3schools.com\/html\/html5_webstorage.asp\">HTML5 Web Storage API<\/a>. For web analytics, this is a bit of a shame. It forces us to think of things in the scope of a single page, when rarely anything worth mentioning has a lifespan that short.<\/p>\n<p>Before we begin, <a href=\"http:\/\/blog.intlock.com\/google-tag-manager-persistent-data-layer-per-session-and-per-visitor\/\">take a look<\/a> at what Shay Sharon expertly wrote two years ago about the persistent dataLayer. In his solution, cookies are used to carry the dataLayer across page refreshes. It\u2019s a good patch, and it performs the task admirably. However, the thing with cookies is that they can be deleted (and usually are). Also, the length of the cookie string is limited (though 4KB is still plenty), and there\u2019s always the fact that cookies are resolved with every single page load (since they are part of the document object).<\/p>\n<p>Data in browser storage, on the other hand, is actually pretty difficult to delete on a granular level, it has a huge quota, and it\u2019s only retrieved and stored on demand. Also, using <code>localStorage<\/code> (more about this soon), you have the data stored indefinitely, so <em>user-level<\/em> storage is very easy to implement.<\/p>\n<p>(<strong>UPDATE<\/strong>: Remember that browser local storage should be treated the same as cookies when observing the <a href=\"http:\/\/www.cookielaw.org\/\">cookie laws<\/a> of your country. Thanks to Martijn Visser for pointing this out (he\u2019s from the Netherlands, and they have pretty much the strictest interpretation of the cookie law in place.))<\/p>\n<div style=\"aspect-ratio: 1514 \/ 1122;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/08\/persist-datalayer.jpg\" title=\"Persistent dataLayer stores variables across page loads\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1122\" width=\"1514\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/08\/persist-datalayer.jpg#ZgotmplZ\" alt=\"Persistent dataLayer stores variables across page loads\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In this guide, I\u2019ll give you an API of sorts to save, load, replace, and delete items from the local storage. I use a 30 minute expiration for data in <code>localStorage<\/code> to mimic session-length storage.<\/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=\"introducing-localstorage\">Introducing localStorage<\/h2>\n<p><code>localStorage<\/code> stores data indefinitely in your browser\u2019s own storage compartment. It has a larger-than-needed size limit (around 5MB), and data is handled more securely than with cookies. Cookies, you see, are written on the document every time you load a page, and this introduces potential security risks.<\/p>\n<p>Items in <code>localStorage<\/code>, on the other hand, are retrieved only when called. This way all the data you store will be picked up on demand, and all you need to do is make sure your script handles the data correctly (which is what I\u2019ll do for you in this guide).<\/p>\n<p>In <code>localStorage<\/code>, data is written as key-value pairs, but unlike with dataLayer, both the key and the value need to be of String type. This means that in order to save stuff from dataLayer, which can hold any types of values, to <code>localStorage<\/code>, some object serialization and type conversion needs to take place (Object =&gt; String). Similarly, the reverse needs to take place when loading data from <code>localStorage<\/code> and pushing it to dataLayer.<\/p>\n<h2 id=\"the-persistent-datalayer-api\">The Persistent dataLayer API<\/h2>\n<p>Without further ado, allow me to introduce the Persistent dataLayer API. Copy the following code into a Custom HTML Tag, and read on.<\/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-html\" data-lang=\"html\">script&gt;\n  (<span style=\"color:#00a\">function<\/span>() {\n    <span style=\"color:#aaa;font-style:italic\">\/\/ Declare some utility variables\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">var<\/span> retrievedDL = <span style=\"color:#a50\">''<\/span>,\n        getDL = {},\n        saveDL = {},\n        persistEvent = <span style=\"color:#099\">\/^persist(Save|Replace)\/<\/span>,\n        timeNow = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>().getTime(),\n        timeStorage = <span style=\"color:#a50\">''<\/span>,\n        persistTime = <span style=\"color:#099\">1000<\/span>*<span style=\"color:#099\">60<\/span>*<span style=\"color:#099\">30<\/span>; <span style=\"color:#aaa;font-style:italic\">\/\/ Expiration in milliseconds; set to null to never expire\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    \n    <span style=\"color:#aaa;font-style:italic\">\/\/ Only works if browser supports Storage API\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">if<\/span>(<span style=\"color:#00a\">typeof<\/span>(Storage)!==<span style=\"color:#a50\">'undefined'<\/span>) {\n        \n      retrievedDL = localStorage.getItem(<span style=\"color:#a50\">'persistDL'<\/span>);\n      timeStorage = localStorage.getItem(<span style=\"color:#a50\">'persistTime'<\/span>);\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ Append current dL with objects from storage\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> loadDL = <span style=\"color:#00a\">function<\/span>() {\n        <span style=\"color:#00a\">if<\/span>(retrievedDL) {\n          dataLayer.push(JSON.parse(retrievedDL));\n          <span style=\"color:#aaa;font-style:italic\">\/\/ dataLayer.push({'event': 'DLLoaded'});\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>        }\n      }\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ Save specified object in storage\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> storeDL = <span style=\"color:#00a\">function<\/span>() {\n        <span style=\"color:#00a\">for<\/span> (<span style=\"color:#00a\">var<\/span> i = <span style=\"color:#099\">0<\/span>; i if (persistEvent.test(dataLayer[i].event)) {\n            saveDL = dataLayer[i];\n            <span style=\"color:#00a\">delete<\/span> saveDL.event;\n            getDL = JSON.parse(retrievedDL) || {};\n            <span style=\"color:#00a\">for<\/span> (<span style=\"color:#00a\">var<\/span> key <span style=\"color:#00a\">in<\/span> saveDL) {\n              <span style=\"color:#00a\">if<\/span> (saveDL.hasOwnProperty(key)) {\n                getDL[key] = saveDL[key];\n              }\n            }\n            localStorage.setItem(<span style=\"color:#a50\">'persistDL'<\/span>, JSON.stringify(getDL));\n          }\n        }\n      }\n      <span style=\"color:#00a\">var<\/span> deleteDL = <span style=\"color:#00a\">function<\/span>() {\n        localStorage.removeItem(<span style=\"color:#a50\">'persistDL'<\/span>);\n      }\n      <span style=\"color:#00a\">switch<\/span> ({{event}}) {\n        <span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'gtm.js'<\/span>:\n          <span style=\"color:#00a\">if<\/span> (retrievedDL &amp;&amp; timeStorage) {\n            <span style=\"color:#00a\">if<\/span> (persistTime &amp;&amp; timeNow &gt; <span style=\"color:#0aa\">Number<\/span>(timeStorage) + persistTime) {\n              deleteDL();\n            } <span style=\"color:#00a\">else<\/span> {\n              loadDL();\n            }\n          }\n          <span style=\"color:#00a\">break<\/span>;\n        <span style=\"color:#aaa;font-style:italic\">\/\/ Delete dataLayer variables\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>        <span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'persistDelete'<\/span>:\n          deleteDL();\n          <span style=\"color:#00a\">break<\/span>;\n        <span style=\"color:#aaa;font-style:italic\">\/\/ Replace dataLayer variables\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>        <span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'persistReplace'<\/span>:\n          retrievedDL = <span style=\"color:#00a\">null<\/span>;\n        <span style=\"color:#aaa;font-style:italic\">\/\/ Save dataLayer variables\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>        <span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'persistSave'<\/span>:\n          storeDL();\n          <span style=\"color:#00a\">break<\/span>;\n      }\n      \n      localStorage.setItem(<span style=\"color:#a50\">'persistTime'<\/span>, JSON.stringify(timeNow));\n    }\n  })();\n<span style=\"color:#1e90ff;font-weight:bold\">script<\/span>&gt;<\/code><\/pre>\n<\/div>\n<p>The tag will need the following firing rule:<\/p>\n<p><strong>{{event}} matches RegEx ^(gtm.js|persist(Save|Replace|Delete))<\/strong><\/p>\n<p>Here\u2019s a rundown of how the API works, before I go into the technical stuff:<\/p>\n<ol>\n<li>\n<p><strong>With every page load<\/strong>, dataLayer variables stored in <code>localStorage<\/code> are retrieved and pushed into dataLayer.<\/p>\n<\/li>\n<li>\n<p><strong>When pushing an object with \u2018event\u2019: \u2018persistSave\u2019<\/strong>, all variables in the same push (e.g. \u2018pageCount\u2019 and \u2018author\u2019 in <code>dataLayer.push({'event': 'persistSave', 'pageCount': '5', 'author': 'Simo-Ahava'});<\/code>) are saved to <code>localStorage<\/code>. If a variable with the same name already exists in <code>localStorage<\/code>, it is updated with the new value.<\/p>\n<\/li>\n<li>\n<p><strong>When pushing an object with \u2018event\u2019: \u2018persistDelete\u2019<\/strong>, all dataLayer variables in <code>localStorage<\/code> are deleted.<\/p>\n<\/li>\n<li>\n<p><strong>When pushing an object with \u2018event\u2019: \u2018persistReplace\u2019<\/strong>, all existing dataLayer variables in <code>localstorage<\/code> are deleted, and all variables in the <code>dataLayer.push()<\/code> are saved.<\/p>\n<\/li>\n<\/ol>\n<p>So remember the following commands:<\/p>\n<p><code>dataLayer.push({'var1': 'value1', 'var2': 'value2', **'event': 'persistSave'**});<\/code> stores \u2018var1\u2019 and \u2018var2\u2019 (with values) to <code>localStorage<\/code>.<\/p>\n<p><code>dataLayer.push({'var1': 'value1', 'var2': 'value2', **'event': 'persistDelete'**});<\/code> deletes all saved dataLayer variables in <code>localStorage<\/code>; doesn\u2019t store anything.<\/p>\n<p><code>dataLayer.push({'var1': 'value1', 'var2': 'value2', **'event': 'persistReplace'**});<\/code> deletes all saved dataLayer variables in <code>localStorage<\/code>; stores \u2018var1\u2019 and \u2018var2\u2019 (with values) to localStorage.<\/p>\n<p>A few additional details:<\/p>\n<ul>\n<li>\n<p>With every page load, variables are loaded from <code>localStorage<\/code> and pushed to dataLayer. Even though the tag itself fires on <strong>{{event}} equals gtm.js<\/strong>, there\u2019s a slight delay when processing data through the Storage API. This means that usually the variables appear in dataLayer after <strong>gtm.dom<\/strong> but before <strong>gtm.load<\/strong>.<\/p>\n<\/li>\n<li>\n<p>Every interaction with <code>localStorage<\/code>, resets the 30 minute expiration timer. If a page load occurs so that the last interaction was over 30 minutes ago, all saved dataLayer variables in <code>localStorage<\/code> are deleted.<\/p>\n<\/li>\n<li>\n<p>Before saving the data, dataLayer variables are serialized into a String. When loading from <code>localStorage<\/code>, they are parsed from JSON back to their original types. Thus Arrays, objects, and primitive values are restored to their original types before pushed back into dataLayer.<\/p>\n<\/li>\n<\/ul>\n<h2 id=\"technical-stuff\">Technical stuff<\/h2>\n<p>Let\u2019s go over the code (almost) line-by-line.<\/p>\n<p>The function is wrapped in an IIFE (immediately invoked function expression). This is because I want to avoid using the global scope when utilizing so many different variables. Scoping the variables to this function ensures that I don\u2019t mess with global variables of some other library, for example.<\/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> retrievedDL = <span style=\"color:#a50\">''<\/span>,\ngetDL = {},\nsaveDL = {},\npersistEvent = <span style=\"color:#099\">\/^persist(Save|Replace)\/<\/span>,\ntimeNow = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">Date<\/span>().getTime(),\ntimeStorage = <span style=\"color:#a50\">''<\/span>,\npersistTime = <span style=\"color:#099\">1000<\/span>*<span style=\"color:#099\">60<\/span>*<span style=\"color:#099\">30<\/span>; <span style=\"color:#aaa;font-style:italic\">\/\/ Expiration in milliseconds; set to null to never expire\n<\/span><\/code><\/pre>\n<\/div>\n<p>Here I introduce a bunch of utility variables. If you want to have the storage persist for ever and ever, set <code>persistTime = null;<\/code>.<\/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>(Storage)!==<span style=\"color:#a50\">'undefined'<\/span>) {\n  retrievedDL = localStorage.getItem(<span style=\"color:#a50\">'persistDL'<\/span>);\n  timeStorage = localStorage.getItem(<span style=\"color:#a50\">'persistTime'<\/span>);\n  ...\n}\n<\/code><\/pre>\n<\/div>\n<p>Only run the API if the browser supports HTML5 Web Storage. It\u2019s basically only a problem with IE versions older than 8. I saw no reason to provide an alternative for them, since if you\u2019re still using IE7 or older, you deserve a horrible browsing experience.<\/p>\n<p>Check Shay Sharon\u2019s excellent post I linked to in the beginning for a cookie-solution to the persistent dataLayer. That should work with your crappy, out-of-date browser.<\/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> loadDL = <span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">if<\/span>(retrievedDL) {\n    dataLayer.push(JSON.parse(retrievedDL));\n    <span style=\"color:#aaa;font-style:italic\">\/\/ dataLayer.push({'event': 'DLLoaded'});\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>  }\n}\n...\n<span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'gtm.js'<\/span>:\n  <span style=\"color:#00a\">if<\/span>(retrievedDL &amp;&amp; timeStorage) {\n    <span style=\"color:#00a\">if<\/span>(persistTime &amp;&amp; timeNow &gt; <span style=\"color:#0aa\">Number<\/span>(timeStorage)+persistTime) {\n      deleteDL();\n    } <span style=\"color:#00a\">else<\/span> {\n      loadDL();\n    }\n  }\n  <span style=\"color:#00a\">break<\/span>;\n<\/code><\/pre>\n<\/div>\n<p>With every page load, parse the dataLayer variables in <code>localStorage<\/code> back to their original types, and push them into dataLayer as a single object. If you want to set a trigger event to fire your tags after the variables have been loaded from <code>localStorage<\/code>, uncomment the line with \u2018event\u2019: \u2018DLLoaded\u2019. This way you can have your dependent tags fire on <strong>{{event}} equals DLLoaded<\/strong> to ensure that they have access to the stored variables.<\/p>\n<p>Also, if the variables in storage expire (default is 30 minutes since last interaction), no data is loaded and the variables are deleted from <code>localStorage<\/code>. If you\u2019ve set <code>persistTime = null;<\/code>, then there\u2019s no expiration for the data in storage, and the variables are stored until they are manually deleted.<\/p>\n<p>When a <code>dataLayer.push();<\/code> is made so that the object that is pushed contains the property \u2018event\u2019: \u2018persistSave\u2019, the function <code>storeDL()<\/code> is run.<\/p>\n<p>First, the function removes the \u2018event\u2019 property from the object that was pushed into dataLayer. This is done because you don\u2019t want to store the trigger event itself in <code>localStorage<\/code>. (Another possibility is to just skip the \u2018event\u2019 property when storing properties into <code>localStorage<\/code>.)<\/p>\n<p>Next, each property in this dataLayer object is pushed into the object that was found in <code>localStorage<\/code>. Thus, all variables that were already stored are updated with new values, and new variables are appended.<\/p>\n<p>Finally, the object, now serialized into a string of keys and values, is stored in <code>localStorage<\/code>, waiting to be loaded with a new page refresh.<\/p>\n<p>If the \u2018event\u2019 was \u2018persistReplace\u2019, then this the <code>storeDL()<\/code> is run as well, but all dataLayer variables in storage are replaced with the new variables.<\/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> deleteDL = <span style=\"color:#00a\">function<\/span>() {\n  localStorage.removeItem(<span style=\"color:#a50\">'persistDL'<\/span>);\n}\n...\n<span style=\"color:#00a\">case<\/span> <span style=\"color:#a50\">'persistDelete'<\/span>:\n  deleteDL();\n  <span style=\"color:#00a\">break<\/span>;\n<\/code><\/pre>\n<\/div>\n<p>If the trigger event was \u2018persistDelete\u2019, all dataLayer variables in <code>localStorage<\/code> are deleted.<\/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\">localStorage.setItem(<span style=\"color:#a50\">'persistTime'<\/span>, JSON.stringify(timeNow));\n<\/code><\/pre>\n<\/div>\n<p>Finally, every time the script is run, the current time is saved as a timestamp in <code>localStorage<\/code>.<\/p>\n<h2 id=\"conclusions\">Conclusions<\/h2>\n<p>I\u2019ve noticed that many people have been aching for a persistent dataLayer. I\u2019m pretty sure this post will become obsolete as soon as the GTM team choose to deploy such a feature into the product itself, but until then, this should serve you well.<\/p>\n<p>And if nothing else, at least you got to learn about yet another really cool JavaScript API!<\/p>\n<p>Do you have suggestions for the API? Or maybe you have a sweet use case for persistent variables that you might want to share with others?<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>(Update 19 November 2018: See this article for a more elegant solution.) If you know your JavaScript, you know that all variables, functions, objects, resources, and data in the document get rewritten with every page load. In other words, every single page refresh builds the page from scratch, and the state of the document before [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":161989,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[38540,1531,14495,21084,1791],"dealstore":[],"offerexpiration":[],"class_list":["post-161988","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-datalayer","tag-google","tag-manager","tag-persist","tag-tag"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Persist dataLayer In 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=161988\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Persist dataLayer In Google Tag Manager - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"(Update 19 November 2018: See this article for a more elegant solution.) If you know your JavaScript, you know that all variables, functions, objects, resources, and data in the document get rewritten with every page load. In other words, every single page refresh builds the page from scratch, and the state of the document before [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=161988\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-03-28T15:49:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1\" \/>\n\t<meta property=\"og:image:height\" content=\"1\" \/>\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=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=161988#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Persist dataLayer In Google Tag Manager\",\"datePublished\":\"2025-03-28T15:49:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988\"},\"wordCount\":1420,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg\",\"keywords\":[\"dataLayer\",\"Google\",\"Manager\",\"persist\",\"TAG\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=161988#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=161988\",\"url\":\"https:\/\/fivemor.com\/?p=161988\",\"name\":\"Persist dataLayer In Google Tag Manager - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg\",\"datePublished\":\"2025-03-28T15:49:12+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=161988#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=161988\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=161988#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=161988#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Persist dataLayer In 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":"Persist dataLayer In 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=161988","og_locale":"en_US","og_type":"article","og_title":"Persist dataLayer In Google Tag Manager - Som2ny Network","og_description":"(Update 19 November 2018: See this article for a more elegant solution.) If you know your JavaScript, you know that all variables, functions, objects, resources, and data in the document get rewritten with every page load. In other words, every single page refresh builds the page from scratch, and the state of the document before [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=161988","og_site_name":"Som2ny Network","article_published_time":"2025-03-28T15:49:12+00:00","og_image":[{"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg","width":1,"height":1,"type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=161988#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=161988"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Persist dataLayer In Google Tag Manager","datePublished":"2025-03-28T15:49:12+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=161988"},"wordCount":1420,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=161988#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg","keywords":["dataLayer","Google","Manager","persist","TAG"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=161988#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=161988","url":"https:\/\/fivemor.com\/?p=161988","name":"Persist dataLayer In Google Tag Manager - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=161988#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=161988#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg","datePublished":"2025-03-28T15:49:12+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=161988#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=161988"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=161988#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/03\/persist-datalayer.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=161988#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Persist dataLayer In 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\/161988","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=161988"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/161988\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/161989"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=161988"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=161988"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=161988"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=161988"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=161988"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}