{"id":172706,"date":"2025-04-06T01:05:00","date_gmt":"2025-04-06T01:05:00","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/google-tag-manager-the-history-listener\/"},"modified":"2025-04-06T01:05:00","modified_gmt":"2025-04-06T01:05:00","slug":"google-tag-manager-the-history-listener","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=172706","title":{"rendered":"Google Tag Manager: The History Listener"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>There\u2019s a new listener in town! It\u2019s a few days now since the <a href=\"https:\/\/www.google.com\/tagmanager\">Google Tag Manager<\/a> team unleashed the <strong>History Listener<\/strong>, and the time has come for me to tell you what this baby can do.<\/p>\n<p>The History Listener is designed to be used on websites where content is loaded dynamically. Typically, these websites make heavy use of <a href=\"https:\/\/www.w3schools.com\/xml\/ajax_intro.asp\">AJAX<\/a> (<strong>A<\/strong>synchronous <strong>J<\/strong>avaScript <strong>a<\/strong>nd <strong>X<\/strong>ML), which is designed for loading content in the background and serving it dynamically without having to reload the page.<\/p>\n<div style=\"aspect-ratio: 998 \/ 626;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/ajax-example.jpg\" title=\"AJAX basics\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"626\" width=\"998\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/ajax-example.jpg#ZgotmplZ\" alt=\"AJAX basics\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Because I don\u2019t want to go too deep into how a dynamic website works, this tutorial should be pretty simple. The key is to understand what events trigger the History Listener, and how you can track your page views in a website without static URLs bound to static content.<\/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=\"background\">Background<\/h2>\n<p>A site which loads content dynamically is usually incompatible with certain default browser events. For example, if you have a site which dynamically loads its content without any change in the URL of the page (nothing happens in the address bar), what do you think happens when a visitor navigates away from your site and then clicks the browser <strong>Back<\/strong> button? I can give you a hint, they won\u2019t see whatever dynamic state the page was in just before they left.<\/p>\n<p>This is, of course, a <a href=\"http:\/\/searchengineland.com\/bing-offers-recommendations-for-seo-friendly-ajax-suggests-html5-pushstate-152946\">problem for search engines<\/a> as well, since they want to index pages with unique URL addresses, which each return a static, unique piece of content. This is why <strong>URL fragments<\/strong> (AKA anchors AKA hashes) were introduced to solve the problems with browser history. If you loaded content clicking an \u201cAbout Us\u201d link, your URL would have looked like <code>https:\/\/www.simoahava.com\/main#aboutus<\/code>.<\/p>\n<p>This fixed the problem with browser history, since now you could detect changes in the URL fragment and serve appropriate content again, even if the user used the Back button. However, this wasn\u2019t good enough for search engines or for Google Analytics, which have a hard time dealing with URL fragments.<\/p>\n<p>Enter the <strong>hashbang<\/strong> (coolest name to be ever given to anything anywhere). The hashbang is a hash followed by an exclamation mark: <strong>#!<\/strong>. It\u2019s an old invention, having existed in UNIX systems to facilitate script loading. Google adopted it as a schema to signify an AJAX site with crawlable content. When search crawlers came across the hashbang sequence, they translated it to a proper URL query parameter (<strong><em>escaped_fragment=_the-original-fragment<\/em><\/strong>). A query parameter meant that the page could be crawled and indexed for search engine users to find.<\/p>\n<p>However, the hashbang isn\u2019t the easiest solution to implement, it looks <a href=\"http:\/\/www.slideshare.net\/RobOusbey\/new-technologies-11724391\/22\">absolutely horrible<\/a>, and <a href=\"http:\/\/danwebb.net\/2011\/5\/28\/it-is-about-the-hashbangs\">it\u2019s just not how you should treat your URLs<\/a>.<\/p>\n<p>The final chapter of the story, and the most relevant one for the History Listener, is brought about by the HTML5 standard. HTML5 introduced the <strong><a href=\"http:\/\/diveintohtml5.info\/history.html\">window.history<\/a><\/strong> API, which can be used to manually manipulate browser history when loading content dynamically. You can now manually push a state into the browser history, and when someone navigates with the browser\u2019s Back button to your page, you can look for stored states and load them in order, just like the default behavior of a static website.<\/p>\n<p>The History Listener listens for changes in browser history. If it detects such a change event, it will tell you what happened, whether there\u2019s a state object stored in history, and if there was a URL fragment change involved. You can use this information to send virtual page views, prevent certain tags from firing again, serve dynamic tags, and basically anything that you\u2019d normally do when a page is loaded.<\/p>\n<h2 id=\"set-up-the-history-listener\">Set up the History Listener<\/h2>\n<p>You set up the History Listener like you would <a href=\"https:\/\/www.simoahava.com\/analytics\/auto-event-tracking-google-tag-manager\/\">any other listener<\/a>.<\/p>\n<ol>\n<li>\n<p>Create a new tag<\/p>\n<\/li>\n<li>\n<p>Name it wisely<\/p>\n<\/li>\n<li>\n<p>Set Tag Type to <strong>Event Listener &gt; History Listener<\/strong><\/p>\n<\/li>\n<li>\n<p>Set firing rule to All pages (<strong>{{url}} matches regex .<\/strong>*)<\/p>\n<\/li>\n<\/ol>\n<div style=\"aspect-ratio: 885 \/ 289;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/history-listener.jpg\" title=\"The History Listener\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"289\" width=\"885\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/history-listener.jpg#ZgotmplZ\" alt=\"The History Listener\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>And that\u2019s it. This will set your listener up on all pages to wait for the triggers that activate it.<\/p>\n<p>You\u2019ll also notice that a bunch of new auto-event variables have been provided. You can use these to access properties of the history event change after the History Listener has fired. Read more about these in my <a href=\"https:\/\/www.simoahava.com\/analytics\/macro-guide-google-tag-manager\/\">Macro Guide<\/a>.<\/p>\n<h2 id=\"the-triggers\">The triggers<\/h2>\n<p>The History Listener will activate every time one of the following occurs:<\/p>\n<ul>\n<li>\n<p>Call to the <strong>window.history.pushState() method<\/strong><\/p>\n<\/li>\n<li>\n<p>Call to the <strong>window.history.replaceState() method<\/strong><\/p>\n<\/li>\n<li>\n<p>A <strong>popstate<\/strong> event is detected<\/p>\n<\/li>\n<li>\n<p>The URL fragment (hash) changes<\/p>\n<\/li>\n<\/ul>\n<p><strong>window.history.pushState()<\/strong> is used to add a state into the browser history stack. <strong>pushState()<\/strong> takes three arguments: a state object, a title, and a URL.<\/p>\n<p>The state object is where you store details about the content, which you can use later to serve the same content to the returning visitor. The title is just a way to name the history entry, though it can be used with <strong>popstate<\/strong> to set the page title. The URL is what will appear in the address bar of your browser after the <strong>pushState()<\/strong> csll is completed. This is especially useful, because your site visitors can share this \u201cvirtual\u201d URL, which can be then used to serve the correct content to visitors arriving via this link.<\/p>\n<p><strong>window.history.replaceState()<\/strong> is pretty much the same as pushState(), except that it replaces the current history state with the new state.<\/p>\n<p><strong>popstate<\/strong> is what occurs every time the active history entry changes. For example, the browser\u2019s Back and Forward buttons trigger <strong>popstate<\/strong>. If the history entry which is activated upon <strong>popstate<\/strong> was created by <strong>pushState()<\/strong> or <strong>replaceState()<\/strong>, the <strong>popstate<\/strong> event will have the stored state object as a property. You can use this object to serve the same content to people navigating through browser history to your AJAX site.<\/p>\n<p><strong>Note!<\/strong> There are some differences as to how and when browsers send the <strong>popstate<\/strong>. Chrome and Safari, for example, fire a <strong>popstate<\/strong> with every page load (since that\u2019s when the active history entry changes), but Firefox doesn\u2019t. Firefox requires a history entry that was created by a <strong>pushState()<\/strong> or <strong>replaceState()<\/strong> call.<\/p>\n<p><strong>URL fragment changes<\/strong> are remnants of the hashbang era, but fragments are still widely used on websites. For example, if you have internal anchor links, you\u2019ll trigger a fragment change event every time the visitor jumps to an anchor on your page. In AJAX sites, you can listen for fragment change events, and use these to send a page view or fire a tag of your choosing.<\/p>\n<h2 id=\"event-equals-gtmhistorychange\">{{event}} equals gtm.historyChange<\/h2>\n<p>When the History Listener is running, and any of the events described in the previous chapter occur, a <em>gtm.historyChange<\/em> is pushed into the data layer. Most of the properties in this event can be accessed by the auto-event macros, but it\u2019s good to know what the data layer entry looks like.<\/p>\n<p>Here\u2019s what your dataLayer object looks like after a pushState() event. Here, the state object I push is very simple. It contains just a single key-value pair, <strong>page: \u201cAbout Us\u201d<\/strong>.<\/p>\n<div style=\"aspect-ratio: 288 \/ 157;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/pushstate.jpg\" title=\"Data Layer after pushState()\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"157\" width=\"288\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/pushstate.jpg#ZgotmplZ\" alt=\"Data Layer after pushState()\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here\u2019s what you dataLayer looks like after a replaceState() event. The parameters are the same as in pushState(). Note that I fired replaceState() just after pushState(), so you\u2019ll see the previous state object stored in the <strong>gtm.oldHistoryState<\/strong> property!<\/p>\n<div style=\"aspect-ratio: 306 \/ 179;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/replacestate.jpg\" title=\"Data Layer after replaceState()\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"179\" width=\"306\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/replacestate.jpg#ZgotmplZ\" alt=\"Data Layer after replaceState()\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Now, if I navigate away from the page and return with the browser Back button, a <strong>popstate<\/strong> event occurs with my state object neatly stored within:<\/p>\n<div style=\"aspect-ratio: 276 \/ 180;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/popstate.jpg\" title=\"Data Layer after popstate\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"180\" width=\"276\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/popstate.jpg#ZgotmplZ\" alt=\"Data Layer after popstate\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As you can see, the old state and the new state are the same, because I navigated away from the Contact page and arrived on the same page after clicking Back in my browser. When popstate occurs, I can look into the history state object and send the correct page view for the dynamic content. In this case, I can see that the visitor returned to the Contact page.<\/p>\n<p>Finally, here\u2019s me navigating from one URL fragment to another:<\/p>\n<div style=\"aspect-ratio: 278 \/ 123;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/fragmentchange.jpg\" title=\"Data Layer after fragment change\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"123\" width=\"278\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/fragmentchange.jpg#ZgotmplZ\" alt=\"Data Layer after fragment change\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>As you can see, I first went to the bottom of the page via URL fragment <strong>#bottom<\/strong>. This triggers a <strong>popstate<\/strong> event, with <strong>#bottom<\/strong> as gtm.newUrlFragment. After that, I clicked \u201cBack to top\u201d, which transported me to URL <strong>#backtotop<\/strong>, and this is reflected in the screenshot above.<\/p>\n<h2 id=\"example-of-use\">Example of use<\/h2>\n<p>I\u2019ll show a quick example, expanding the idea of navigating to the \u201cContact\u201d page, where the page details are stored in a state object, created using <strong>pushState()<\/strong>.<\/p>\n<p>The premise is that when your visitor clicks a link to the \u201cContact\u201d page, the contents are loaded dynamically. To account for history changes, the <strong>pushState()<\/strong> method is called with something 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\">var<\/span> page = {page:<span style=\"color:#a50\">\"Contact\"<\/span>};\nhistory.pushState(page,<span style=\"color:#a50\">'Contact'<\/span>,<span style=\"color:#a50\">'contact.html'<\/span>);\n<\/code><\/pre>\n<\/div>\n<p>This pushes a new entry into your browser history stack, with a single property within the state object. This property is the one we\u2019ll want to access in a <strong>popstate<\/strong> instance, i.e. when someone returns to the contact page via a history event (browser Back, for example).<\/p>\n<div style=\"aspect-ratio: 651 \/ 526;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/history-change-source.jpg\" title=\"History Change Source macro\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"526\" width=\"651\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/history-change-source.jpg#ZgotmplZ\" alt=\"History Change Source macro\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<ul>\n<li>Create a new Data Layer Variable macro to get the <strong>page<\/strong> property of the new history state:<\/li>\n<\/ul>\n<div style=\"aspect-ratio: 644 \/ 522;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/page-property.jpg\" title=\"New macro for Page property\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"522\" width=\"644\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/page-property.jpg#ZgotmplZ\" alt=\"New macro for Page property\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<ul>\n<li>Create a new rule for your page view tag:<\/li>\n<\/ul>\n<div style=\"aspect-ratio: 449 \/ 293;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/rule-for-history-change.jpg\" title=\"Rule for the History Change\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"293\" width=\"449\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/rule-for-history-change.jpg#ZgotmplZ\" alt=\"Rule for the History Change\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>And that\u2019s it. You can attach this sequence to your page view tag, for example, ensuring that the page view is sent every time someone navigates back to your Contact content via browser history (see below for how to make sure the page view properties are in order).<\/p>\n<p>The firing rule is important. You\u2019re looking for a <strong>gtm.historyChange<\/strong> event. This is pushed into the data layer when the History Listener is triggered. After that, you\u2019ll want to make sure that the event was <strong>popstate<\/strong> (the macro in (2)), and that the <strong>page<\/strong> property of the new history state has value \u201cContact\u201d.<\/p>\n<p>Now when you send a page view, the URL will be correctly contact.html (since you provide that in the pushState() call). However, your document title might be off, unless you explicitly set it in your AJAX logic. A nice way to send the page title is to use the Document Path setting in your page view tag, and populate it with the value of a Lookup Table macro, which in turn evaluates the <strong>page<\/strong> property again. Allow me to demonstrate:<\/p>\n<div style=\"aspect-ratio: 479 \/ 391;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/page-view.jpg\" title=\"Page View tag with document title\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"391\" width=\"479\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/page-view.jpg#ZgotmplZ\" alt=\"Page View tag with document title\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>That\u2019s your page view tag. In the Document Title field, you\u2019re retrieving the value from a Lookup Table macro, which I\u2019ve named <strong>{{ AJAX &#8211; Page Title }}<\/strong>.<\/p>\n<div style=\"aspect-ratio: 643 \/ 518;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2014\/03\/lookup-table-ajax.jpg\" title=\"Lookup Table from AJAX Page Title\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"518\" width=\"643\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2014\/03\/lookup-table-ajax.jpg#ZgotmplZ\" alt=\"Lookup Table from AJAX Page Title\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>This sets the page title depending on the <strong>page<\/strong> property, pushed into the data layer when the history listener is fired. You could set a default value to the Lookup Table macro, but on the other hand, if it doesn\u2019t return a value, the tag will just send whatever is found in the <strong>document.title<\/strong> property.<\/p>\n<h2 id=\"conclusions\">Conclusions<\/h2>\n<p>Phew! This turned into a monster of a tutorial. But that\u2019s to be expected. Working with AJAX and dynamic content is not easy, as there are so many things to factor in. Not only are there usability and browser compatibility issues involved, you\u2019ll also need to take <a href=\"http:\/\/moz.com\/blog\/create-crawlable-link-friendly-ajax-websites-using-pushstate\">search engines into account<\/a>, and you\u2019ll need to understand how history events work.<\/p>\n<p>As always, I highly recommend that you brush up on your JavaScript before you start working with the History Listener. There\u2019s no damage to be done, but you don\u2019t want to screw your tracking by not understanding how state objects work, for example. Also, it\u2019s very likely that you\u2019ll have to return to your AJAX setup to make sure that pushState() calls and replaceState() calls provide all the necessary data for you to use.<\/p>\n<p>Using the History Listener on a dynamic site is so much better than resorting to Link Click Listeners. More often than not, you\u2019ll come across <a href=\"https:\/\/www.simoahava.com\/analytics\/dont-gtm-listeners-work\/\">event propagation problems<\/a> with your listeners, since most of AJAX navigation is designed to prevent the default behavior of links. With the History Listener, you\u2019re only listening for browser history events, so on-page conflicts won\u2019t affect the listener\u2019s basic functionality.<\/p>\n<p>You\u2019ll need to be careful and precise with your rules. Make use of all the properties of the gtm.historyChange event, because you\u2019ll want to do different things upon <strong>pushState()<\/strong> and <strong>popstate<\/strong>, for example.<\/p>\n<p>And if you have any questions, drop me a mail or leave a comment below!<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>There\u2019s a new listener in town! It\u2019s a few days now since the Google Tag Manager team unleashed the History Listener, and the time has come for me to tell you what this baby can do. The History Listener is designed to be used on websites where content is loaded dynamically. Typically, these websites make [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":172707,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[1531,3734,32681,14495,1791],"dealstore":[],"offerexpiration":[],"class_list":["post-172706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-google","tag-history","tag-listener","tag-manager","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: The History Listener - 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=172706\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Google Tag Manager: The History Listener - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"There\u2019s a new listener in town! It\u2019s a few days now since the Google Tag Manager team unleashed the History Listener, and the time has come for me to tell you what this baby can do. The History Listener is designed to be used on websites where content is loaded dynamically. Typically, these websites make [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=172706\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-06T01:05:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"998\" \/>\n\t<meta property=\"og:image:height\" content=\"626\" \/>\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=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=172706#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Google Tag Manager: The History Listener\",\"datePublished\":\"2025-04-06T01:05:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706\"},\"wordCount\":2062,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg\",\"keywords\":[\"Google\",\"history\",\"Listener\",\"Manager\",\"TAG\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=172706#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=172706\",\"url\":\"https:\/\/fivemor.com\/?p=172706\",\"name\":\"Google Tag Manager: The History Listener - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg\",\"datePublished\":\"2025-04-06T01:05:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=172706#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=172706\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=172706#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg\",\"width\":998,\"height\":626},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=172706#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Google Tag Manager: The History Listener\"}]},{\"@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: The History Listener - 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=172706","og_locale":"en_US","og_type":"article","og_title":"Google Tag Manager: The History Listener - Som2ny Network","og_description":"There\u2019s a new listener in town! It\u2019s a few days now since the Google Tag Manager team unleashed the History Listener, and the time has come for me to tell you what this baby can do. The History Listener is designed to be used on websites where content is loaded dynamically. Typically, these websites make [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=172706","og_site_name":"Som2ny Network","article_published_time":"2025-04-06T01:05:00+00:00","og_image":[{"width":998,"height":626,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=172706#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=172706"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Google Tag Manager: The History Listener","datePublished":"2025-04-06T01:05:00+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=172706"},"wordCount":2062,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=172706#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg","keywords":["Google","history","Listener","Manager","TAG"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=172706#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=172706","url":"https:\/\/fivemor.com\/?p=172706","name":"Google Tag Manager: The History Listener - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=172706#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=172706#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg","datePublished":"2025-04-06T01:05:00+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=172706#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=172706"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=172706#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/04\/ajax-example.jpg","width":998,"height":626},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=172706#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Google Tag Manager: The History Listener"}]},{"@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\/172706","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=172706"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/172706\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/172707"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=172706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=172706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=172706"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=172706"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=172706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}