This is a bit anticlimactic of a post, for my triumphant return after a long while of not blogging, but this question keeps coming up so I figured I’d document it publicly so I can reference it when needed. I find many of my posts that are for my own benefit, to use as a reference, tend to be the most viewed posts, so here’s Jenn’s notes to herself about converting Doubleclick tags to gtag:
Quick Reference
If you’re generally familiar with gtag and the old Doubleclick/Floodlight/Search Ads 360 tags, and just want a quick reminder of the order of things, here is the format of the send_to variable, inspired by Google’s documentation:
‘send_to’ : ‘DC-[floodlightConfigID (src)]/[activityGroupTagString (type)]/[activityTagString (cat)]+[countingMethod-either conversion or purchase]
That’s src, type, and cat pulled from these spots:
If that doesn’t make a lot of sense to you, you need more examples, or you just want to understand it better, read on.
Walkthrough
Doubleclick’s standard tag used to look something like this (sometimes using an img instead of an iframe, but the same general idea either way):
<!--
Start of Floodlight Tag: Please do not remove
Activity name of this tag: Jenn-Kunz-Example-Tag
URL of the webpage where the tag is expected to be placed: https://www.digitaldatatactics.com/
This tag must be placed between the <body> and </body> tags, as close as possible to the opening tag.
Creation Date: 08/18/2021
-->
<script type="text/javascript">
var axel = Math.random() + "";
var a = axel * 10000000000000;
document.write('<iframe src="https://12345678.fls.doubleclick.net/activityi;src=12345678;type=myagency;cat=jkunz_001;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=;npa=;gdpr=${GDPR};gdpr_consent=${GDPR_CONSENT_755};ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
</script>
<noscript>
<iframe src="https://12345678.fls.doubleclick.net/activityi;src=12345678;type=myagency;cat=jkunz_001;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=;npa=;gdpr=${GDPR};gdpr_consent=${GDPR_CONSENT_755};ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
</noscript>
<!-- End of Floodlight Tag: Please do not remove -->
Some agencies/deployments still use this format. You may get a request from an agency or marketer to deploy a tag documented this way. But if you already use gtag on your site, or you just want to modernize and take advantage of gtag, you can convert these old iframe tags into gtag by just mapping a few values.
Before you get started, you need to note a few things from your original tag:
Keep track of these, we’ll use them in a moment. (If you also have custom dimensions or revenue and such, hang on, we’ll get to those in a bit.)
Step 1. Global Site Tag code
First, make sure you have gtag code on your site. No matter how many tags use it, you only need to reference it once.
Note, I’m only walking through the code; if you’re in Launch, using a tool like Acronym’s Google Site Tag extension (which is great, in my opinion), hopefully this post combined with their documentation will be enough to get you what you need to know.
<!--
Start of global snippet: Please do not remove
Place this snippet between the <head> and </head> tags on every page of your site.
-->
<!-- Global site tag (gtag.js) - Google Marketing Platform -->
<script async src="https://www.googletagmanager.com/gtag/js?id=DC-12345678"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'DC-12345678');
</script>
<!-- End of global snippet: Please do not remove -->
The part that matters, that establishes which gtag accounts you want to set up, is in the config:
This is where you’d put #1- Your Account ID. Add a “DC-” to the front of it (DC for Doubleclick, as opposed to AW for AdWords…), and you have your config ID.
Step 2. Send an event
With that, you have the gtag library on your page, and you’ve configured it. But this merely “primes” your tracking…. it sets it up, but does not actually send the information you want. For that, you need to convert your original iframey tag into a gtag event. A traditional gtag event looks like this:
<!--
Event snippet for Jenn-Kunz-Example-Tag-Home-Page on https://www.digitaldatatactics.com: Please do not remove.
Place this snippet on pages with events that you’re tracking.
Creation date: 08/19/2021
-->
<script>
gtag('event', 'conversion', {
'allow_custom_scripts': true,
'send_to': 'DC-12345678/myagency/jkunz_001+standard'
});
</script>
<noscript>
<img src=""https://ad.doubleclick.net/ddm/activity/src=12345678;type=myagency;cat=jkunz_001;dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;tfua=;npa=;gdpr=${GDPR};gdpr_consent=${GDPR_CONSENT_755};ord=1?"" width=""1"" height=""1"" alt=""""/>
</noscript>
<!-- End of event snippet: Please do not remove -->
But the part we need (and the only part that actually sends info to google) is just this:
gtag('event', 'conversion', {
'allow_custom_scripts': true,
'send_to': 'DC-12345678/myagency/jkunz_001+standard'
});
Here is where we do our mapping. As stated above, the format for the “send_to” variable is:
'send_to' : 'DC-[#1 floodlightConfigID (src)]/[#2 activityGroupTagString (type)]/[#3 activityTagString (cat)]+[countingMethod]
So this in your original iFrame/pixel Doubleclick tag:
Becomes this for gtag:
There are two other things to pay attention to in that gtag event, and they don’t map directly to something in your original tag:
(Note, the “allow_custom_scripts” will always be true, so you don’t need to worry about it.)
The event type (“conversion”) and the counting method (“+standard”) will reflect whether or not your tag is for a purchase or not. For the Counting Method, Google says:
Standard counts every conversion by every user. This is the counting method for action activities generated in Search Ads 360.
Transactions counts the number of transactions that take place, and the cost of each transaction. For example, if a user visits your website and buys five books for a total of €100, one conversion is recorded with that monetary value. This is the counting method for transaction activities generated in Search Ads 360.
Unique counts the first conversion for each unique user during each 24-hour day, from midnight to midnight, Eastern Time (US).
In other words, most cases will be “conversion”/”+standard”, unless you’re tracking a purchase, in which case it will be “purchase”/”+transaction”. If your original tag has cost and qty in it, then it’s a purchase, otherwise, it’s likely just a conversion and you can use “+standard” as your counting method. On a rare occasion, you may be asked to use “+unique” so the conversion only counts once per day. I hear there may be other counting methods, but I don’t have examples of them.
If your tag is a conversion and you’re not sending custom variables, then the allow_custom_scripts and the send_to is all you need- you’re done! If it is a transaction and/or you have custom variables, read on.
Transactions
If your original iframey tag is intended for a purchase confirmation page, it probably includes a “qty”, “cost” and “ord”, with the intent for you to dynamically fill these in based on the user’s transaction:
If so, then your gtag will need a few more things, like value and transaction_id (and make sure your event type is “purchase” instead of “conversion”) :
gtag('event', 'purchase', {
'allow_custom_scripts': true,
'value': '[Revenue]',
'transaction_id': '[Order ID]',
'send_to': 'DC-12345678/myagency/jkunz_001a+transactions',
});
The mapping for these is probably fairly obvious. What was “cost” goes into “value”; what was “ord” goes into “transaction_id”:
Quantity seems to have fallen by the wayside; the old iframey tags asked for it but I’ve never seen it in a gtag purchase tag.
Maybe it could go without saying, but to be clear, the expectation is that you’d dynamically fill in those values in square brackets. So if you’re in Launch, it might look like this:
gtag('event', 'purchase', {
'allow_custom_scripts': true,
'value': _satellite.getVar('purchase: total'),
'transaction_id': _satellite.getVar('purchase: confirmation number'),
'send_to': 'DC-12345678/myagency/jkunz_001a+transactions',
});
Custom Variables
Doubleclick tags might contain parameters that are the letter u followed by a number and the name of what they want you to send there:
gtag('event', 'purchase', {
'allow_custom_scripts': true,
'value': '[Revenue]',
'transaction_id': '[OrderID]',
'u1': '[Flight Number]',
'u2': '[Departure Airport]',
'u3': '[Departure Date]',
'send_to': 'DC-12345678/sales/jkunz_001a+transactions',
});
Again, the expectation is that you would replace anything in square brackets with dynamic values that reflect the user’s experience. I often leave the description they provided in comments, just for reference and to make sure I’m putting stuff in the right places.
gtag('event', 'purchase', {
'allow_custom_scripts': true,
'value': _satellite.getVar('purchase: total'),
'transaction_id': _satellite.getVar('purchase: confirmation number'),
'u1': _satellite.getVar('flight number'), //'[Flight Number]'
'u2': _satellite.getVar('departure code'), //'[Departure Airport]'
'u3': _satellite.getVar('flight date'), //'[Departure Date]'
'send_to': 'DC-12345678/myagency/jkunz_001a+transactions',
});
What about the serialization and other gunk?
You may be wondering about some of the other bits of code in the original iframey tag:
NoScript
A quick word about the noscript tags:
These are a remnant of an older internet, where mobile devices didn’t run JavaScript, and tag management systems didn’t exist. It says “if the user doesn’t run JavaScript, then run this HTML instead”, usually followed by a hard-coded pixel.
Frankly, it’s comical that anyone includes these anywhere anymore:
- These days, the only devices not running JavaScript are bots. Unless you WANT inflated numbers (maybe some agencies/vendors do), you don’t want bot traffic.
- Sometimes vendors/agencies will ask for dynamic values within the noscript tag:
Which is just silly- without JavaScript, the only way to dynamically set those values would be to have them set serverside. Which I’ve never seen anyone do. - Finally… if you’re deploying it through a Tag Management System, and the user isn’t running JavaScript, the TMS won’t run at all, meaning the rule won’t fire, meaning the noscript tag will never get a chance to be written.
In short, delete noscript tags and their contents. Some agencies may not know these not-exactly-rocket-science nuances of the internet, and may whine at you about not including the noscript tag because they have a very specific checklist to follow. Include it if you must to appease the whiners, but… know that if it’s within a TMS, the contents of that noscript tag will never see the light of day.
How to send to multiple accounts
This isn’t tied directly to converting from old tags, but for reference…. if you want to send a gtag event to multiple accounts, instead of duplicating the tag, you can add a config in your global code:
<script async src="https://www.googletagmanager.com/gtag/js?id=DC-12345678"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'DC-12345678');
gtag('config', 'DC-87654321');
</script>
Then in your event code, turn the “send_to” into an array:
gtag('event', 'purchase', {
'allow_custom_scripts': true,
'value': '[Revenue]',
'transaction_id': '[Order ID]',
'send_to': [
'DC-12345678/myagency/jkunz_001a+transactions',
'DC-87654321/agencyB/book_01a+transactions'
]
});
You may ask “If I only need to have the gtag library script once, and I have multiple gtags, what do I do about this id on the global script src?”
Conclusion
It’s not exactly cutting-edge content, nor relaxing bedside reading, but I hope this comes in handy for those for those struggling to find answers in existing documentation. Cheers!
Disclaimer: I’m not a Doubleclick expert, but I have deployed many many Doubleclick tags- I daresay hundreds of them. If any of the above isn’t “gospel truth”, it’s “truth that worked for me”, but I’d love to hear if any of my reasoning/theories are incorrect or incomplete.