Convert Universal Analytics ecommerce dataLayer to Google Analytics 4
I often hear clients ask, “Can I create a GA4 ecommerce object from the one I use for Universal Analytics (UA)?”
The answer is that you can! This article shows you how to do this easily.
Important note: Make sure to set up the GA4 dataLayer properly by July 2023.
Let me first show you a couple of pictures for reference.
This is the UA ecommerce object:

And this is the GA4 ecommerce object:

Apart from the additions of various other variables like item category types and list types, the names of the variables are also changed in GA4. Thus, it is not just a simple job of capturing the data as a dataLayer variable in Google Tag Manager (GTM) and passing it on with the GA4 purchase tag.
It is relatively simple to get “transaction_id” from the older “id” by creating a dataLayer variable called “dlv – transactionId” from the dataLayer using the string “ecommerce.purchase.actionField.id”.

We can do similar dataLayer pickups for value, tax, currency, etc.
But what does one do to capture the items array from the products array? That is the part where people usually get stumped.
Let me show you.
Create a custom JavaScript variable for the items array and set it up this way:
function() {
var products = {{ga4-dlv-transactionProducts}};
return products.map(function(product) {
return {
"item_id": {{ga4-dlv-item_id}},
"item_name": {{ga4-dlv-item_name}},
"item_category": {{ga4-dlv-item_category}},
"quantity": {{ga4-dlv-quantity}},
"price": {{ga4-dlv-item-price}}
}
});
}
You can also see it in a picture here as I have set it up in GTM:

I have used the bare minimum of fields, but you can add to this array if the ecommerce products belong to multiple categories.
Let me also show you how to get the components that are being called from within this JavaScript function.
For “item_id”, the dataLayer variable “ga4-dlv-item_id” will be configured like this:
“ecommerce.purchase.products.0.id”.
For “item_name”, the dataLayer variable “ga4-dlv-item_name” will be configured like this:
“ecommerce.purchase.products.0.name”.
For “item_category”, the dataLayer variable “ga4-dlv-item_category” will be configured like this:
“ecommerce.purchase.products.0.category”.
For “quantity”, the dataLayer variable “ga4-dlv-quantity” will be configured like this:
“ecommerce.purchase.products.0.quantity”.
For “price”, the dataLayer variable “ga4-dlv-price” will be configured like this:
“ecommerce.purchase.products.0.price”.
For you to practice pulling data from the advanced ecommerce dataLayer, I have created a sample “thank you” page here. Please use this as much as you wish and desire.
Now, that the item array is all set, we can build the GA4 purchase tag, which can be done like this:

For more questions about this post, feel free to comment on this post or contact me directly.
I don’t think your javascript is correct you are mapping the same product from the datalayer over and over i.e ecommerce.purchase.products.0.id to item_id will always be the first product in the products ecommerce.purchase.products array .? it should be
function() {
var products = {{ga4-dlv-transactionProducts}};
return products.map(function(product) {
return {
“item_id”: product.id,
“item_name”: product.name,
“item_category”: product.category,
“quantity”: product.quantity,
“price”: product.price
}
});
}
Adrian – thanks for the fix above, which sorted the issue with the original code for me.