compsoul.dev Posted September 20, 2024 Share Posted September 20, 2024 Hi everyone, I’m trying to add data layers for GTM using JavaScript, without mixing the JS layer with the HTML layer, which is why I’ve taken this approach. However, it seems like not every layer can be added this way. My ideal solution would be to create a separate .tpl file for each event, where I could fetch the data via AJAX after the event is triggered and send it to Google. However, I implemented a less labor-intensive approach, and I’m facing a problem with the final event: the "purchase" event. I'm not sure how to fetch that data purely from the JS layer. Does anyone have any ideas on how to solve this? I know I could add the necessary code in the .tpl file, but that’s my last resort and not the most desirable solution. Here are the solutions I’ve used for other events: (function() { prestashop.on("updateCart", function (event) { const cartProducts = event.resp.cart.products, addedProductId = Number(event.resp.id_product), addedProductAttributeId = Number(event.resp.id_product_attribute), addedQuantity = event.resp.quantity, reason = event.reason.linkAction; const addedProduct = cartProducts.find(function(product) { return Number(product.id_product) === addedProductId && Number(product.id_product_attribute) === addedProductAttributeId; }); if (addedProduct && reason == "add-to-cart") { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'add_to_cart', 'ecommerce': { 'items': [{ 'item_name': addedProduct.name, 'item_id': addedProduct.id_product, 'item_variant': addedProduct.id_product_attribute, 'price': addedProduct.price_amount, 'quantity': addedQuantity, }] } }); console.log('Dane produktu zostały dodane do Data Layer:', window.dataLayer); } }); })(); (function() { document.body.addEventListener('click', function(event) { if (event.target.href && prestashop.urls && prestashop.urls.pages && prestashop.urls.pages.order && event.target.href === prestashop.urls.pages.order) { if (prestashop.cart && prestashop.cart.products) { const cartProducts = prestashop.cart.products; const totalValue = prestashop.cart.totals.total.amount; const currency = prestashop.currency.iso_code; const coupon = prestashop.cart.vouchers.length > 0 ? prestashop.cart.vouchers[0].name : ''; window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'begin_checkout', 'ecommerce': { 'currency': currency, 'value': totalValue, 'coupon': coupon, 'items': cartProducts.map(function(product) { return { 'item_name': product.name, 'item_id': product.id, 'coupon': coupon, 'discount': product.reduction || 0, 'item_brand': product.manufacturer_name, 'item_category': product.category, 'item_variant': product.id_product_attribute, 'price': product.price_amount, 'quantity': product.cart_quantity }; }) } }); console.log('Zdarzenie begin_checkout zostało wypchnięte do Data Layer', window.dataLayer); } } }); })(); (function() { prestashop.on("updateCart", function (event) { const reason = event.reason.linkAction, resp = event.resp; if (reason == "delete-from-cart" && resp.success) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'remove_from_cart', 'ecommerce': { 'items': [{ 'item_id': resp.id_product, 'item_variant': resp.id_product_attribute, }] } }); } }); })(); (function() { if (prestashop.page && prestashop.page.page_name === 'cart') { if (prestashop && prestashop.cart && prestashop.cart.products && prestashop.currency) { const cartProducts = prestashop.cart.products, totalValue = prestashop.cart.totals.total.amount, currency = prestashop.currency.iso_code; window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'view_cart', 'ecommerce': { 'currency': currency, 'value': totalValue, 'items': cartProducts.map(function(product) { return { 'item_name': product.name, 'item_id': product.id, 'item_variant': product.id_product_attribute, 'price': product.price_amount, 'quantity': product.cart_quantity, 'item_url': product.url, 'item_brand': product.manufacturer_name, 'item_category': product.category }; }) } }); } } })(); (function() { const jsonScripts = document.querySelectorAll('script[type="application/ld+json"]'); jsonScripts.forEach(function(script) { try { const jsonData = JSON.parse(script.textContent); if (jsonData['@type'] === 'ItemList') { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'view_item_list', 'ecommerce': { 'items': jsonData.itemListElement.map(function(item) { return { 'item_name': item.name, 'item_url': item.url, 'position': item.position }; }) } }); console.log('Dane produktu zostały dodane do Data Layer:', window.dataLayer); } } catch (error) { console.error('Błąd parsowania JSON-LD:', error); } }); })(); (function() { const jsonScripts = document.querySelectorAll('script[type="application/ld+json"]'); jsonScripts.forEach(function(script) { try { const jsonData = JSON.parse(script.textContent); if (jsonData['@type'] === 'Product') { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ 'event': 'view_item', 'ecommerce': { 'items': [{ 'item_name': jsonData.name, 'item_id': jsonData.mpn || jsonData.sku, 'item_brand': jsonData.brand ? jsonData.brand.name : undefined, 'item_category': jsonData.category, 'price': jsonData.offers ? Number(jsonData.offers.price) : undefined, 'currency': jsonData.offers ? jsonData.offers.priceCurrency : undefined, 'item_url': jsonData.offers ? jsonData.offers.url : undefined, 'item_image': jsonData.offers && jsonData.offers.image ? jsonData.offers.image[0] : undefined }] } }); console.log('Dane produktu zostały dodane do Data Layer:', window.dataLayer); } } catch (error) { console.error('Błąd parsowania JSON-LD:', error); } }); })(); Thanks in advance for any suggestions! Link to comment Share on other sites More sharing options...
Butch0071 Posted January 21 Share Posted January 21 (edited) Hi, I do not have a quite solution - since I am using .tpl and fetched data from php to purchase event - however I have question regarding to 'add_to_cart" event. 'item_name': addedProduct.name, 'item_id': addedProduct.id_product, 'item_variant': addedProduct.id_product_attribute, 'price': addedProduct.price_amount, 'quantity': addedQuantity, I need to put in 'item_variant' a mpn value for current combination - but do not have an idea how to reach the value from js...Can not see the value in js product object. Any suggestions? Oh, I think that price passed to DL for GA should be just value without currency sign- so probably: addedProduct.price_wt Edited January 21 by Butch0071 (see edit history) Link to comment Share on other sites More sharing options...
compsoul.dev Posted January 21 Author Share Posted January 21 prestashop.on("updateCart", function (event) { console.log(event); }); Here you can access the products along with their variants. Link to comment Share on other sites More sharing options...
Butch0071 Posted January 21 Share Posted January 21 Thank you - yes indeed but there is no mpn value there. EAN, ISBN but no mpn. Link to comment Share on other sites More sharing options...
Butch0071 Posted January 21 Share Posted January 21 I found it weird that there is no MPN value in product variant information, there is ISBN and EAN - not sure but I quess it is a bug (or feature?). Can't think of reason why is that.. It turns out the shop is using MPN field for each combination of a product and I kindda need to access that value on 'updateCart' - seems that some workaround needs to be done Link to comment Share on other sites More sharing options...
compsoul.dev Posted January 21 Author Share Posted January 21 You can always add such a value to itemListElement in JS. You can also add an id and use the loop in “updateCart” to retrieve the field you are interested in. This will consume CPU. You also need to understand that developers can't fetch all the product fields, every time, it would load the query render a lot. Link to comment Share on other sites More sharing options...
Butch0071 Posted January 21 Share Posted January 21 All true, do you know maybe where to find class responsible for generating that 'event' data? I would try to add or replace one of fields with one I need... I understand that it is impossible to fetch all product fields but that would make much more sense to fetch all product fields that can be set on product edit page then rather some data that are stored in Prestashp data objects - and are rather useless for 99.9% of developers... Example from data in event, availability: "available" availability_date: null availability_message: "" available_later: "" available_now: "" ... upc: legend: I am pretty sure that someone missed that MPN field there -when ean, isbn, upc even are there... MPN field is only 40 chars stored in product_attribute table - so wouldn't make much difference, just one more field in same query. This ecotaxes fields or availability_message are probably much more CPU and query -time consuming I know someone will say "ecotax fields are must have in product data object" the other will say "availabilty_message field is super important" - it all depands on what you need at the moment but in my opinion it is rather clear that mpn field would be used a lot more often then 'availabilty_message' or 'upc' or 'ean' or 'isbn' fields even. Presta is great but have a lot of small annoying, ill-considered little things like that... Link to comment Share on other sites More sharing options...
Butch0071 Posted January 23 Share Posted January 23 Do you maybe know how that js object with those data is generated? Where to find mechanism to change data it is generating. I can't find it. In all classes I checked I see all product data - mpn too. My quess it can be a bug or misspell of variable or something like that.. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now