{"id":54741,"date":"2025-01-29T04:42:33","date_gmt":"2025-01-29T04:42:33","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/transformations-in-server-side-google-tag-manager\/"},"modified":"2025-01-29T04:42:33","modified_gmt":"2025-01-29T04:42:33","slug":"transformations-in-server-side-google-tag-manager","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=54741","title":{"rendered":"Transformations In Server-side Google Tag Manager"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>In January 2020, when <a href=\"https:\/\/developers.google.com\/tag-platform\/tag-manager\/server-side\">Google Tag Manager\u2019s server-side tagging<\/a> was first introduced to the general public at <a href=\"https:\/\/www.superweek.hu\">SuperWeek<\/a>, I wrote a <a href=\"https:\/\/twitter.com\/SimoAhava\/status\/1222459714614841346\">flurry of tweets<\/a>, sharing my vision of a server-side tagging future.<\/p>\n<p>In one of the tweets, I discussed how you could do these:<\/p>\n<ul>\n<li>Hit validation and fixing before the hit is sent to the endpoint<\/li>\n<li>PII and privacy controls for the requests before dispatch<\/li>\n<\/ul>\n<div style=\"aspect-ratio: 1084 \/ 538;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/04\/simo-twitter.jpg\" title=\"Tweet about server-side tagging\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"538\" width=\"1084\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/04\/simo-twitter.jpg#ZgotmplZ\" alt=\"Tweet about server-side tagging\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Fast forward to today, over three years later, and we are <em>finally<\/em> treated to a feature that grants us scalable controls to properly interrupt data flows within server-side GTM.<\/p>\n<p>I\u2019m talking about <strong>TRANSFORMATIONS<\/strong>.<\/p>\n<div style=\"aspect-ratio: 2356 \/ 724;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/04\/transformations.jpg\" title=\"Transformations\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"724\" width=\"2356\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/04\/transformations.jpg#ZgotmplZ\" alt=\"Transformations\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>It\u2019s a new feature and <strong>resource<\/strong> type in server-side tagging, which you can access through the new entry in the container resource navigator.<\/p>\n<p>Transformations sit firmly between the <strong>client<\/strong> and <strong>tags<\/strong>, allowing you to <strong>include<\/strong> and <strong>exclude<\/strong> parameters from the <a href=\"https:\/\/www.simoahava.com\/analytics\/server-side-tagging-google-tag-manager\/#event-model\">event data object<\/a> before tags can access it.<\/p>\n<p>You can also use it to <strong>augment<\/strong> existing parameters. This is useful if you want to enrich the event data object with an appropriately designed <a href=\"https:\/\/www.simoahava.com\/analytics\/enrich-server-side-data-with-cloud-firestore\/\">Firestore pipeline<\/a>, or something similar.<\/p>\n<p>Read on for more information about how transformations work and how to use them.<\/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=\"transformations-in-a-nutshell\">Transformations in a nutshell<\/h2>\n<p>To understand transformations, you first need to recall how <strong>clients<\/strong> and <strong>tags<\/strong> interact in a server-side tagging container.<\/p>\n<p>A <strong>client<\/strong> is a server-side tagging resource whose purpose is to digest an <strong>incoming HTTP request<\/strong> and ideally turn it into an <a href=\"https:\/\/www.simoahava.com\/analytics\/server-side-tagging-google-tag-manager\/#event-model\">event data object<\/a>.<\/p>\n<p>This event data object is then consumed by <strong>tags<\/strong> in order to perform their tasks, such as dispatching requests to third-party vendors. The event data object semantics are not standardized or enforced, but it is recommended that clients follow the <a href=\"https:\/\/developers.google.com\/tag-platform\/tag-manager\/server-side\/common-event-data\">schema outlined by Google<\/a>.<\/p>\n<p>For example, a client could take a URL parameter like <code>&amp;cid=12345.12345<\/code> and turn it into an event data object key named <code>client_id<\/code> with the value <code>12345.12345<\/code>. Tags could then be coded or configured to take this <code>client_id<\/code> key from the event data object and populate their own outgoing requests with the value.<\/p>\n<div style=\"aspect-ratio: 1920 \/ 1080;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/sgtm-client.jpg\" title=\"Server-side GTM client example\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1080\" width=\"1920\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/sgtm-client.jpg#ZgotmplZ\" alt=\"Server-side GTM client example\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The best way to check what type of event data objects are generated by clients is to use <a href=\"https:\/\/developers.google.com\/tag-platform\/tag-manager\/server-side\/debug\">Preview mode<\/a>. When you select an <em>event<\/em> in the left-hand navigation, the <strong>Event Data<\/strong> tab will show what the client produced.<\/p>\n<div style=\"aspect-ratio: 4142 \/ 1670;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/sgtm-preview.jpg\" title=\"SGTM preview mode\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1670\" width=\"4142\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/sgtm-preview.jpg#ZgotmplZ\" alt=\"SGTM preview mode\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<blockquote>\n<p>Why don\u2019t you see events under all the requests? That\u2019s because there either wasn\u2019t a client to <strong>claim<\/strong> the request in question, or the client didn\u2019t produce an event object using a <a href=\"https:\/\/developers.google.com\/tag-platform\/tag-manager\/server-side\/api#runcontainer\">specific template API<\/a>.<\/p>\n<\/blockquote>\n<p>The main problem with event data is that the client\u2019s operations are <strong>fixed<\/strong>. The event data object it produces is the same for <strong>all tags<\/strong> that are configured to make use of it. If you want a tag to ignore certain fields in the event data object, or if you want a set of tags to mutate some of the values into another format, the tag template itself needs to support this, <em>and not all tag templates do<\/em>.<\/p>\n<p>Furthermore, Google\u2019s own clients, which the majority of users will default to as the main controllers of the incoming data streams, are black boxes and there\u2019s not much you can do to control how they work.<\/p>\n<div style=\"aspect-ratio: 1786 \/ 698;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/04\/ga4-client.jpg\" title=\"GA4 Client\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"698\" width=\"1786\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/04\/ga4-client.jpg#ZgotmplZ\" alt=\"GA4 Client\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>For long, we\u2019ve been waiting for a feature that would allow us to edit the event data object itself before tags get to consume it.<\/p>\n<p>This is where <strong>transformations<\/strong> enter the stage.<\/p>\n<p>With <strong>transformations<\/strong>, you can now create a rule that removes or modifies the values in the event data object before tags can access it.<\/p>\n<p>Instead of having to make tag-specific exceptions, you can now <strong>modify the event data object itself<\/strong>. After doing so, any tag that is set to consume this transformation will be privy only to the modified event data object rather than the original one.<\/p>\n<div style=\"aspect-ratio: 1268 \/ 472;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/04\/transformation-type.jpg\" title=\"Transformationt ype\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"472\" width=\"1268\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/04\/transformation-type.jpg#ZgotmplZ\" alt=\"Transformationt ype\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<blockquote>\n<p>Importantly, transformations <strong>don\u2019t permanently edit<\/strong> the event data object. They create a transformed <em>clone<\/em> of the object to be digested by whatever tags and whatever conditions you specify in the transformation (more about these below). Tags that are not affected by a transformation will have access to the original, unmodified event data object.<\/p>\n<\/blockquote>\n<h2 id=\"create-a-new-transformation\">Create a new transformation<\/h2>\n<p>To create a new transformation, click the <strong>Transformations<\/strong> entry in the left-hand navigation of your server-side tagging container. You\u2019ll see a list of your existing transformations. If you click the button labeled <strong>NEW<\/strong>, you can create a new transformation.<\/p>\n<div style=\"aspect-ratio: 2074 \/ 536;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/new-transformation.jpg\" title=\"New transformation\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"536\" width=\"2074\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/new-transformation.jpg#ZgotmplZ\" alt=\"New transformation\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>When you create a transformation, you\u2019ll first need to choose its type.<\/p>\n<h2 id=\"transformation-types\">Transformation types<\/h2>\n<p>Transformations come in <strong>three types<\/strong>:<\/p>\n<ul>\n<li><strong>Allow parameters<\/strong>, which lets you <em>allowlist<\/em> the parameters that should end up in the event data object. This is very powerful, as parameters that are not allowed will be excluded from the event data.<\/li>\n<li><strong>Exclude parameters<\/strong>, which lets you <em>denylist<\/em> the parameters that should <strong>not<\/strong> end up in the event data object. Parameters that are not excluded will be included in the event data.<\/li>\n<li><strong>Augment event<\/strong>, which lets you <strong>add<\/strong> or <strong>modify<\/strong> event data parameters. This is where you would do <strong>data enrichment<\/strong>, <strong>sensitive data purges<\/strong>, and similar.<\/li>\n<\/ul>\n<div style=\"aspect-ratio: 832 \/ 488;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-type.jpg\" title=\"Transformation types\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"488\" width=\"832\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-type.jpg#ZgotmplZ\" alt=\"Transformation types\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h3 id=\"allow-parameters\">Allow parameters<\/h3>\n<p>When you choose <strong>Allow parameters<\/strong> as the transformation type, you\u2019ll need to populate a table of rows, with each row corresponding to a parameter name in the event data object.<\/p>\n<div style=\"aspect-ratio: 1776 \/ 884;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/allow-parameters.jpg\" title=\"Allow parameters\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"884\" width=\"1776\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/allow-parameters.jpg#ZgotmplZ\" alt=\"Allow parameters\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>When this transformation is evaluated, the keys in the event data object are compared against the parameters listed in this transformation. If there\u2019s a match, that key is kept in the event data object.<\/p>\n<p>If there\u2019s no match, then the key is dropped from the event data object for this transformation.<\/p>\n<div style=\"aspect-ratio: 1518 \/ 1362;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/allowed-parameters.jpg\" title=\"Allowed parameters\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1362\" width=\"1518\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/allowed-parameters.jpg#ZgotmplZ\" alt=\"Allowed parameters\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In the example above, the only allowed parameters are <code>client_id<\/code>, <code>event_name<\/code>, <code>ga_session_id<\/code>, and <code>custom_timestamp<\/code>. Other parameters are not included in this transformation.<\/p>\n<p>This is a very powerful transformation type, as it lets you proactively exclude all parameters that you are not aware of or that you haven\u2019t exclusively allowlisted for the tags that consume this transformation.<\/p>\n<blockquote>\n<p>It\u2019s also a risky transformation type because of this. Especially when working with third-party vendors, you might not know exactly which parameters the vendor needs due to poor documentation or lazy template design. The <strong>Allow parameters<\/strong> transformation is most potent when you\u2019re working with a service for which you know exactly which parameters are required and which are optional.<\/p>\n<\/blockquote>\n<h3 id=\"exclude-parameters\">Exclude parameters<\/h3>\n<p>Like <em>Allow parameters<\/em> above, parameter exclusion requires you to populate a table of rows, with each row corresponding to a parameter in the event data object.<\/p>\n<div style=\"aspect-ratio: 1772 \/ 702;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/exclude-parameters.jpg\" title=\"Exclude parameters\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"702\" width=\"1772\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/exclude-parameters.jpg#ZgotmplZ\" alt=\"Exclude parameters\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>However, this time when comparing keys in the event data object against this list, any key that matches between the two is <strong>dropped<\/strong> from the event data object. Keys that are <em>not<\/em> matched are kept.<\/p>\n<div style=\"aspect-ratio: 1820 \/ 1410;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/excluded-parameters.jpg\" title=\"Excluded parameters\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1410\" width=\"1820\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/excluded-parameters.jpg#ZgotmplZ\" alt=\"Excluded parameters\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In this case, <code>client_hints<\/code> and <code>ip_override<\/code> have been excluded from the final event data object in this transformation. That\u2019s why they have empty values above whereas all the other parameter values are preserved.<\/p>\n<p>While the allowlist is more <strong>proactive<\/strong> and pre-emptive as a measure, the <strong>Exclude parameters<\/strong> transformation lets you remove parameters that you <em>know<\/em> to be problematic.<\/p>\n<h3 id=\"augment-event\">Augment event<\/h3>\n<p>Event augmentation is what you\u2019d use for data enrichment and for cleaning up the contents of the event data object. Instead of removing or keeping parameters, the <strong>augment event<\/strong> transformation type lets you <strong>add<\/strong> new keys to the event data object <em>and\/or<\/em> <strong>modify<\/strong> existing values.<\/p>\n<div style=\"aspect-ratio: 1772 \/ 934;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-event.jpg\" title=\"Augment event with ecom data\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"934\" width=\"1772\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-event.jpg#ZgotmplZ\" alt=\"Augment event with ecom data\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>When you add parameter names and values into this transformation, any parameters that share the same name in the event data object get overwritten by the transformation\u2019s value for the given parameter. If there is no pre-existing parameter with that name, a new one is added to the event data object.<\/p>\n<div style=\"aspect-ratio: 1824 \/ 1252;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-from-firestore.jpg\" title=\"Parameters from Firestore\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1252\" width=\"1824\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-from-firestore.jpg#ZgotmplZ\" alt=\"Parameters from Firestore\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<blockquote>\n<p>In the example above, with the exception of <code>currency<\/code>, all the ecommerce parameters are <a href=\"https:\/\/www.simoahava.com\/analytics\/enrich-server-side-data-with-cloud-firestore\/#example-walkthrough\">retrieved from Firestore<\/a>.<\/p>\n<\/blockquote>\n<p>The cool thing is that the <strong>values<\/strong> you set support the full range of server-side Google Tag Manager\u2019s variable capabilities, including things like <strong>asynchronous API calls<\/strong> and <strong>Firestore lookups<\/strong>.<\/p>\n<p>While event augmentation is very useful for <strong>removing sensitive information<\/strong> from the <code>page_location<\/code> field, for example, its biggest potential lies in <strong>enriching<\/strong> the information in the event data object so that a multitude of tags can make use of the modification.<\/p>\n<h2 id=\"transformation-priority\">Transformation priority<\/h2>\n<p>It\u2019s possible for multiple transformations to apply to a given event data key. For example, you might have a transformation in place that <strong>augments<\/strong> an event data key and also another transformation in place that <strong>excludes<\/strong> this key under certain conditions.<\/p>\n<p>In this case it might be sensible to set the exclusion at a higher priority, so that the key isn\u2019t unnecessarily augmented in cases where it\u2019s already been excluded.<\/p>\n<div style=\"aspect-ratio: 1388 \/ 264;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-priority.jpg\" title=\"Transformation priority\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"264\" width=\"1388\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-priority.jpg#ZgotmplZ\" alt=\"Transformation priority\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>You can find the priority setting under the <strong>Advanced Settings<\/strong> of any transformation.<\/p>\n<p>If you don\u2019t specify a priority, then transformations are evaluated in this default priority order:<\/p>\n<p><strong>Allow parameters<\/strong> &gt; <strong>Augment event<\/strong> &gt; <strong>Exclude parameters<\/strong><\/p>\n<h2 id=\"matching-conditions\">Matching conditions<\/h2>\n<p><strong>Matching conditions<\/strong> allow you to enable the given transformation only when certain variable conditions are matched.<\/p>\n<p>For example, given the Ecommerce augmentation example from above, it makes sense to only enable this transformation when the <code>event_name<\/code> value is <code>purchase<\/code>, as that\u2019s the only event that would include the transaction ID required for fetching the data from Firestore (read more about this use case below).<\/p>\n<div style=\"aspect-ratio: 1856 \/ 1324;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/matching-conditions.jpg\" title=\"Matching conditions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1324\" width=\"1856\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/matching-conditions.jpg#ZgotmplZ\" alt=\"Matching conditions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>If GA4 is your main incoming data stream, you could even add a <strong>Client Name<\/strong> condition to the transformation to make sure that other types of incoming streams don\u2019t trigger the Firestore lookups.<\/p>\n<div style=\"aspect-ratio: 1378 \/ 460;\" class=\"figure \">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/matching-in-preview.jpg\" title=\"Matching conditions in preview mode\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"460\" width=\"1378\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/matching-in-preview.jpg#ZgotmplZ\" alt=\"Matching conditions in preview mode\"\/><\/p>\n<p>    <\/a><\/p>\n<p>    <span class=\"caption\">Matching conditions in preview mode<\/span><\/p>\n<\/div>\n<p>If any of these matching conditions does <em>not<\/em> match, then the transformation is not evaluated and event data is not modified.<\/p>\n<p>In addition to restricting transformations to work only under certain conditions, you can also apply them only to specific tags that you allowlist in the <strong>Affected tags<\/strong> settings.<\/p>\n<div style=\"aspect-ratio: 1858 \/ 1432;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/affected-tags.jpg\" title=\"Affected tags\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1432\" width=\"1858\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/affected-tags.jpg#ZgotmplZ\" alt=\"Affected tags\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In the example above, my <strong>Allow parameters<\/strong> transformation allowlists only a very restricted range of event data parameters for my custom analytics collector system.<\/p>\n<p>Other tags can make use of the entire event data object, but this particular Custom Analytics Collector tag is only privy to the limited set allowlisted in this transformation.<\/p>\n<h2 id=\"debug-transformations\">Debug transformations<\/h2>\n<p>In Preview mode, the main way to see transformations at work is to select an <strong>event<\/strong> in Preview mode, and then open a <strong>tag<\/strong> that should be affected by a transformation.<\/p>\n<div style=\"aspect-ratio: 1328 \/ 758;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/preview-mode.jpg\" title=\"Preview Mode\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"758\" width=\"1328\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/preview-mode.jpg#ZgotmplZ\" alt=\"Preview Mode\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here, under <strong>Modified event data<\/strong> you\u2019ll see what was available to the tag when it fired. If you check <strong>Show Original<\/strong>, you\u2019ll see a <em>diff<\/em> of what the original event data object looked like.<\/p>\n<div style=\"aspect-ratio: 1800 \/ 1666;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/show-original.jpg\" title=\"Show original\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1666\" width=\"1800\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/show-original.jpg#ZgotmplZ\" alt=\"Show original\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The transformations that affect this tag are also listed. By clicking them open, you can see what the transformation is supposed to do, and you can also see another diff of \u201cbefore\u201d and \u201cafter\u201d states of the event data object after the transformation does its job.<\/p>\n<p>If there are multiple transformations affecting the current tag, then the \u201cbefore\u201d state might be impacted by prior (higher priority) transformations modifying it.<\/p>\n<div style=\"aspect-ratio: 1774 \/ 1382;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-details.jpg\" title=\"Transformation details\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1382\" width=\"1774\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/transformation-details.jpg#ZgotmplZ\" alt=\"Transformation details\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In the image above, this transformation only shows a few keys in the event data object, because there was a higher priority <strong>Allow parameters<\/strong> transformation before this one, stripping out all the keys that were not explicitly allowlisted.<\/p>\n<h2 id=\"use-cases\">Use cases<\/h2>\n<p>Here are some use cases for transformations.<\/p>\n<p>#1 <a href=\"#use-case-1-flag-custom-events-as-conversions-for-ga4\">Flag custom events as conversions for GA4<\/a><br \/>#2 <a href=\"#use-case-2-enrich-ecommerce-data\">Enrich ecommerce data<\/a><br \/>#3 <a href=\"#use-case-3-hash-ssensitive-urls\">Hash sensitive URLs<\/a><br \/>#4 <a href=\"#use-case-4-populate-identifiers-from-firestore-storage\">Populate identifiers from Firestore storage<\/a><br \/>#5 <a href=\"#use-case-5-clear-unwanted-parameters-from-ga4s-event-data-object\">Clear unwanted parameters from GA4\u2019s event data object<\/a><br \/>#6 <a href=\"#use-case-6-force-ga4-hits-to-show-up-in-debugview\">Force GA4 hits to show up in DebugView<\/a><br \/>#7 <a href=\"#use-case-7-augment-event-with-first-party-user-data\">Augment event with first-party user data<\/a><\/p>\n<p>Naturally, all of these use cases have been doable before with server-side Google Tag Manager in one way or another. However, not all tags allow you to modify the information consumed from the event data object.<\/p>\n<p>Furthermore, the problem with modifying individual tags is that you might slip and miss a tag, which then becomes a liability in your tracking schema. By nipping the problem in the bud using a transformation, the event data object itself is modified making it impossible for a tag to access something that doesn\u2019t exist anymore.<\/p>\n<h3 id=\"use-case-1-flag-custom-events-as-conversions-for-ga4\">Use case #1: Flag custom events as conversions for GA4<\/h3>\n<p>One of the \u201cquirks\u201d of Google Analytics 4 is that it determines <strong>conversions<\/strong> in two places: in the <a href=\"https:\/\/support.google.com\/analytics\/answer\/12966437?sjid=7054793677152552224-EU\">Google Analytics 4 Admin interface<\/a> <em>and<\/em> in the client-side implementation, where conversion events are flagged with a specific URL parameter (<code>_c=1<\/code>) that tells GA4 the incoming event is, indeed, a conversion.<\/p>\n<p>This second context can result in a bit of a headache if you\u2019re using a server-side container to duplicate events across different Measurement IDs.<\/p>\n<p>For example, let\u2019s say you have a Google Analytics 4 event stream collecting to Measurement ID <code>G-1234567<\/code>. In this stream, the event <code>click_to_call<\/code> has <strong>not<\/strong> been flagged as a conversion, so the event requests do not have the <code>_c=1<\/code> parameter.<\/p>\n<p>However, in server-side GTM you forward this event to <code>G-2345678<\/code> where <code>click_to_call<\/code> <em>has<\/em> been flagged as a conversion. But because the original request didn\u2019t have the <code>_c=1<\/code> parameter, this conversion is not registered correctly.<\/p>\n<p><strong>Augment event<\/strong> transformation to the rescue!<\/p>\n<div style=\"aspect-ratio: 1856 \/ 1284;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-conversion.jpg\" title=\"Augment conversions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1284\" width=\"1856\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-conversion.jpg#ZgotmplZ\" alt=\"Augment conversions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Above, I\u2019m setting the parameter <code>x-ga-system_properties.c<\/code> to the value <code>1<\/code>. By comparing the Event Data object with the incoming request parameters, I know that this corresponds with the URL parameter <code>_c=1<\/code>.<\/p>\n<p>Additionally, I use a Lookup Table that returns <code>true<\/code> for all the events that should have this parameter added to them:<\/p>\n<div style=\"aspect-ratio: 1798 \/ 826;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/lookup-events.jpg\" title=\"Lookup table for conversion events\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"826\" width=\"1798\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/lookup-events.jpg#ZgotmplZ\" alt=\"Lookup table for conversion events\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Finally, I\u2019ve defined the transformation to only apply to the <code>G-2345678<\/code> GA4 tag in the Server container.<\/p>\n<p>Now the outgoing request to <code>G-2345678<\/code> for any event flagged as a conversion with the Lookup Table will always include the <code>_c=1<\/code> parameter.<\/p>\n<h3 id=\"use-case-2-enrich-ecommerce-data\">Use case #2: Enrich ecommerce data<\/h3>\n<p>One of my favorite data enrichment use cases is for <strong>ecommerce data<\/strong>.<\/p>\n<p>Just imagine a scenario where all you need to do client-side is collect a <code>purchase<\/code> event with a <code>transaction_id<\/code>. Then, in server-side GTM, you can use the <code>transaction_id<\/code> to pull in the rest of the ecommerce data from your sales engine (using HTTP API calls) or from Firestore, if it\u2019s something you\u2019ve already set up.<\/p>\n<p>You can now move this logic to an <strong>Augment event<\/strong> transformation so that all your conversion tags can make use of this enriched data automatically.<\/p>\n<div style=\"aspect-ratio: 1824 \/ 1252;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-from-firestore.jpg\" title=\"Parameters from Firestore\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1252\" width=\"1824\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-from-firestore.jpg#ZgotmplZ\" alt=\"Parameters from Firestore\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<blockquote>\n<p>You could even replace the <code>value<\/code> collected from the client-side hit with the actual <strong>profit<\/strong>, and send that to your vendors. You\u2019d never want to expose your profit margins in the client, but in a server-side environment it\u2019s very doable indeed.<\/p>\n<\/blockquote>\n<p>The benefit of using this <strong>Augment event<\/strong> transformation is that the augmentation applies to the <strong>event data object<\/strong>, which means that tags that make use of it (for example the GA4 tag) won\u2019t require any modifications in the tags themselves. They\u2019ll just see the transformed event data object and work with the augmented values out of the box.<\/p>\n<h3 id=\"use-case-3-hash-sensitive-urls\">Use case #3: Hash sensitive URLs<\/h3>\n<p>Sometimes the URL itself can contain information that you don\u2019t want to forward to a third-party vendor. However, the vendor might still need URL data for cohort building or something similar.<\/p>\n<p>With a properly setup <strong>Augment event<\/strong> transformation, you can now <strong>hash<\/strong> the <code>page_location<\/code> value whenever the URL has the potential of containing sensitive information.<\/p>\n<p>For example, in this case we want to use the <a href=\"https:\/\/tagmanager.google.com\/gallery\/#\/owners\/gtm-templates-simo-ahava\/templates\/sha256-hasher\">sha256 Hasher<\/a> variable template to hash the <code>page_location<\/code> value, but <em>only<\/em> when the <code>page_category<\/code> event data key has the value <code>logged-in<\/code> and <em>only<\/em> for Facebook tags.<\/p>\n<div style=\"aspect-ratio: 1862 \/ 1290;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-hash-for-facebook.jpg\" title=\"Augment hash for facebook\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1290\" width=\"1862\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-hash-for-facebook.jpg#ZgotmplZ\" alt=\"Augment hash for facebook\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>By doing this in a transformation, we can ensure that Facebook never gets the actual page URL for sensitive pages.<\/p>\n<h3 id=\"use-case-4-populate-identifiers-from-firestore-storage\">Use case #4: Populate identifiers from Firestore storage<\/h3>\n<p>If you have the legal basis to do so, one thing you might have been using server-side tagging for is to collect and collate a user\u2019s <strong>identity graph<\/strong>.<\/p>\n<p>This can be as simple as a table stored in Firestore, where all the identifiers associated with a user are stored in a neat document entry.<\/p>\n<div style=\"aspect-ratio: 1856 \/ 1118;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-cid-sid.jpg\" title=\"Augment identity from Firestore\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1118\" width=\"1856\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-cid-sid.jpg#ZgotmplZ\" alt=\"Augment identity from Firestore\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>For example, you could store the user\u2019s <strong>login ID<\/strong> as the primary key, and then under that you could add all their known client\/device identifiers, session IDs, and whatever other identifiers the different marketing platforms like to collect.<\/p>\n<p>With an <strong>Augment event<\/strong> transformation, you can see what parameters are included in the event data object and then populate the rest after performing the lookup in Firestore. You\u2019ll be able to \u201cfill in the gaps\u201d of your tracking schema by overwriting new or ephemeral identifiers with something more sticky.<\/p>\n<p>But \u2013 please. Make sure you have a legal basis for processing all that personal data first!<\/p>\n<h3 id=\"use-case-5-clear-unwanted-parameters-from-ga4s-event-data-object\">Use case #5: Clear unwanted parameters from GA4\u2019s event data object<\/h3>\n<p>The GA4 request seems to collect a <em>lot<\/em> of information that the GA4 client transpiles into the event data object. Not all of this information is documented!<\/p>\n<p>It might be useful to look at a handful of GA4 events in server-side tagging Preview Mode to see just what event data is generated. You can then create an <strong>Exclude parameters<\/strong> transformation to clear all the parameters that you\u2019re not comfortable with from the event data object.<\/p>\n<div style=\"aspect-ratio: 1772 \/ 702;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/exclude-parameters.jpg\" title=\"Exclude parameters\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"702\" width=\"1772\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/exclude-parameters.jpg#ZgotmplZ\" alt=\"Exclude parameters\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Similarly, you might want to remove Facebook-specific parameters from GA4 tags and vice versa, if you\u2019re using a GA4 client to produce an event data object for both GA4 and Facebook. And this applies to other marketing vendors to whom you are collecting data by piggybacking on the GA4 stream.<\/p>\n<div style=\"aspect-ratio: 1858 \/ 1266;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-excluded.jpg\" title=\"Exclude Facebook params\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1266\" width=\"1858\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/parameters-excluded.jpg#ZgotmplZ\" alt=\"Exclude Facebook params\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Use the \u201cSome tags\u201d setting here, as you can use it to specify the subset of tags that should consume any given transformation.<\/p>\n<h3 id=\"use-case-6-force-ga4-hits-to-show-up-in-debugview\">Use case #6: Force GA4 hits to show up in DebugView<\/h3>\n<p>Augmenting event data can help you debug your Google Analytics 4 hits, too.<\/p>\n<p>For an event to surface in GA4\u2019s <a href=\"https:\/\/support.google.com\/analytics\/answer\/7201382?hl=en\">DebugView<\/a>, it needs to be sent with the special URL parameter <code>_dbg=1<\/code> to GA4\u2019s collection servers.<\/p>\n<p>The GA4 Client parses this parameter into an event data key accessible through <code>x-ga-system_properties.dbg<\/code>. With an <strong>Augment Event<\/strong> transformation, it\u2019s now easy to add it to any events that you want to explore through DebugView.<\/p>\n<div style=\"aspect-ratio: 1856 \/ 1428;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-debug-mode.jpg\" title=\"Augment debug mode\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"1428\" width=\"1856\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/augment-debug-mode.jpg#ZgotmplZ\" alt=\"Augment debug mode\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In this transformation, I\u2019m setting <code>x-ga-system_properties.dbg<\/code> to <code>1<\/code> but only when the server-side tagging container is in Preview mode. I\u2019m also limiting this to GA4 tags, because no other tags need to make use of this GA-specific feature.<\/p>\n<h3 id=\"use-case-7-augment-event-with-first-party-user-data\">Use case #7: Augment event with first-party user data<\/h3>\n<p>While I think you should be <strong>very<\/strong> careful with using <a href=\"https:\/\/support.google.com\/google-ads\/answer\/9888656\">enhanced conversions<\/a>  due to obvious privacy issues with handing first-party data to Google on a silver platter, it doesn\u2019t stop me from exploring the technical fundamentals of how it works in server-side tagging.<\/p>\n<p>Instead of sourcing the first-party data client-side, you can <strong>augment it<\/strong> into your server-side hits by using a transformation that fetches it from a suitable data source.<\/p>\n<div style=\"aspect-ratio: 1768 \/ 746;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/user-data.jpg\" title=\"User data\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"746\" width=\"1768\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/user-data.jpg#ZgotmplZ\" alt=\"User data\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>To populate the first-party data variables, you need to use the prefix <code>user_data<\/code>. Under that, you can set:<\/p>\n<ul>\n<li><code>user_data.email<\/code>: the user\u2019s email address.<\/li>\n<li><code>user_data.phone_number<\/code>: the user\u2019s phone number.<\/li>\n<li><code>user_data.address.0.first_name<\/code>: the user\u2019s first name.<\/li>\n<\/ul>\n<p>And you can keep adding to the <code>address<\/code> object in addition to the first name with stuff like <code>city<\/code>, <code>country<\/code>, <code>last_name<\/code>, <code>region<\/code>, and <code>postal_code<\/code>.<\/p>\n<p>You don\u2019t have to hash them yourself, as they will be hashed by the Google tags before the outgoing request is compiled.<\/p>\n<p>With a transformation like this, it\u2019s <strong>absolutely vital<\/strong> you only enable it for vendors that you trust using the <strong>Affected tags<\/strong> setting. Otherwise you might be looking at a severe data breach possibility.<\/p>\n<h2 id=\"summary\">Summary<\/h2>\n<p>I\u2019m very happy with this feature release. I think server-side Google Tag Manager is close to having a very satisfactory feature set to cater to an unbelievable number of marketing use cases.<\/p>\n<p>The benefit of <strong>transformations<\/strong> for data governance should be obvious:<\/p>\n<ol>\n<li>Google strongly recommends and incentivizes vendors to utilize the <strong>event data object<\/strong> when sourcing values for their tag templates.<\/li>\n<li>With transformations, you have <strong>full control<\/strong> over what the event data object ends up looking like, regardless of what the client originally produces.<\/li>\n<li>This control can be used for <strong>adding<\/strong>, <strong>removing<\/strong>, and <strong>updating<\/strong> values in the event data object.<\/li>\n<\/ol>\n<p>Naturally, tags don\u2019t <em>have<\/em> to use the event data object. As transformations obviously pose a risk to malicious tags that want to collect as much as they can without users having a proper say, these tags could now proceed to scrape the information from the request URL itself or from cookies or other HTTP headers.<\/p>\n<p>Hopefully there will be additional UI signals in server-side Google Tag Manager that help us clearly see what data each tag template is using.<\/p>\n<p>One of the problems with transformations is that you need to know both what the event data object can look like at different times <em>and<\/em> which parameters each tag makes use of.<\/p>\n<p>A solid way of figuring out what a tag template is actually trying to do is to observe its <a href=\"https:\/\/developers.google.com\/tag-platform\/tag-manager\/server-side\/permissions\">permissions<\/a>. Good template design involves adding as few permissions as possible, so if a template clearly lists which event data keys it wants to access, you can build your transformations more efficiently.<\/p>\n<div style=\"aspect-ratio: 1528 \/ 410;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2023\/05\/tag-permission.jpg\" title=\"tag permissions\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"410\" width=\"1528\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2023\/05\/tag-permission.jpg#ZgotmplZ\" alt=\"tag permissions\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Obviously templates can also be built with wildcard permissions access, in which case this sleuth work won\u2019t be as effective. I hope that Google figures out a way to incentivize limited permission sets over broader wildcard selections.<\/p>\n<p>A few features that I\u2019d still like to see in transformations include:<\/p>\n<ul>\n<li>Ability to select a tag <em>type<\/em> over individual tags when choosing <strong>Affected tags<\/strong>.<\/li>\n<li>Ability to populate the table of parameters with a single <em>variable<\/em>, so that you could iterate over all the keys in the event data object, for example, and return an array (for Allow \/ Exclude) or object (for Augment) of parameter names (and values) to which you want the transformation to apply.<\/li>\n<\/ul>\n<p>What do you think about transformations? Do you have additional use cases in mind for them?<\/p>\n<\/p><\/div>\n<p><script async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><br \/>\n<br \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In January 2020, when Google Tag Manager\u2019s server-side tagging was first introduced to the general public at SuperWeek, I wrote a flurry of tweets, sharing my vision of a server-side tagging future. In one of the tweets, I discussed how you could do these: Hit validation and fixing before the hit is sent to the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":54742,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[1531,14495,18475,1791,31521],"dealstore":[],"offerexpiration":[],"class_list":["post-54741","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-google","tag-manager","tag-serverside","tag-tag","tag-transformations"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Transformations In Server-side 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=54741\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Transformations In Server-side Google Tag Manager - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"In January 2020, when Google Tag Manager\u2019s server-side tagging was first introduced to the general public at SuperWeek, I wrote a flurry of tweets, sharing my vision of a server-side tagging future. In one of the tweets, I discussed how you could do these: Hit validation and fixing before the hit is sent to the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=54741\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-29T04:42:33+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=54741#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Transformations In Server-side Google Tag Manager\",\"datePublished\":\"2025-01-29T04:42:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741\"},\"wordCount\":3590,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg\",\"keywords\":[\"Google\",\"Manager\",\"Serverside\",\"TAG\",\"Transformations\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=54741#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=54741\",\"url\":\"https:\/\/fivemor.com\/?p=54741\",\"name\":\"Transformations In Server-side Google Tag Manager - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg\",\"datePublished\":\"2025-01-29T04:42:33+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=54741#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=54741\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=54741#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=54741#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Transformations In Server-side 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":"Transformations In Server-side 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=54741","og_locale":"en_US","og_type":"article","og_title":"Transformations In Server-side Google Tag Manager - Som2ny Network","og_description":"In January 2020, when Google Tag Manager\u2019s server-side tagging was first introduced to the general public at SuperWeek, I wrote a flurry of tweets, sharing my vision of a server-side tagging future. In one of the tweets, I discussed how you could do these: Hit validation and fixing before the hit is sent to the [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=54741","og_site_name":"Som2ny Network","article_published_time":"2025-01-29T04:42:33+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=54741#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=54741"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Transformations In Server-side Google Tag Manager","datePublished":"2025-01-29T04:42:33+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=54741"},"wordCount":3590,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=54741#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg","keywords":["Google","Manager","Serverside","TAG","Transformations"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=54741#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=54741","url":"https:\/\/fivemor.com\/?p=54741","name":"Transformations In Server-side Google Tag Manager - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=54741#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=54741#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg","datePublished":"2025-01-29T04:42:33+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=54741#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=54741"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=54741#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/01\/transformations-in-server-side-google-tag-manager.jpg","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=54741#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Transformations In Server-side 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\/54741","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=54741"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/54741\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/54742"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=54741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=54741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=54741"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=54741"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=54741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}