yireo / Yireo_GoogleTagManager2

Open Software License 3.0
146 stars 74 forks source link

Related or upsell products on product page contain itemdata as well #211

Closed mountainit-general closed 8 months ago

mountainit-general commented 9 months ago

We discovered that in a standard implementation of related products on the product page the item data script is added to all related products as well. The problem is that the code is being loaded not only for the main product but also for related products on the product catalog view page, which is causing unwanted behavior. This causes GTM to randomly see a different item as being added to cart, which in turn makes that events are not connected very well from page view to add to cart to an order.

It seems that details.phtml is loaded for related products as well (if you show the product details there). The issue is caused because the block yireo_googletagmanager2.product-details is added to the layout in both the main product section and the related products section of the page. We tested this with all third party extensions disabled - and it is a luma based theme. It does not seem to happen in Hyva shops.

For now we make sure the code is runned only once by overriding the details.phtml in our theme since the main product details are always the first on the page, but I am not sure that is the most universal and best solution.

<?php declare(strict_types=1);

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\View\Element\Template;
use Yireo\GoogleTagManager2\DataLayer\Tag\Product\CurrentProduct;
use Yireo\GoogleTagManager2\ViewModel\DataLayer;

/** @var Template $block */
/** @var CurrentProduct $productDetails */
/** @var DataLayer $dataLayer */

// Check if this is the first occurrence of the block
if (!$block->getData('gtm_code_executed')) {

    // Set a flag to mark that the code has been executed
    $block->setData('gtm_code_executed', true);

    $dataLayer = $block->getDataLayer();
    $productDetails = $block->getProductDetails();
    $product = $block->getProduct();

    if ($product instanceof ProductInterface) {
        $productDetails->setProduct($product);
    }

    $product = $productDetails->getProduct();
    $productData = $dataLayer->toJson($productDetails->merge());
    ?>
    <script>
        window['YIREO_GOOGLETAGMANAGER2_PRODUCT_DATA_ID_<?= $product->getId() ?>'] = <?= $productData ?>;
    </script>
<?php } ?>
jissereitsma commented 9 months ago

Thanks for posting. I have a hard time following along with the actual problem, perhaps due to differences in vocabulary. For instance, you say "This causes GTM to randomly see a different item as being added to cart". But to put this into the right words: GTM does not "see" anything except for events. In this Yireo extension, we therefore talk about events. Hence, your report suggests that clicking upon product A actually triggers the add_to_cart events with details of product B?

You say the "item data script is added to all related products", but I'm not sure which script you refer to and what it means that it is being "added". How it actually works in this extension: There is only a single PHTML template relevant on the product detail page which is the product/details.phtml template (and this is mentioned by you) which is added via the XML layout only in one single container product.info.form.content which should only occur once on every product detail page. In my demo environment, on a product page with related products, I'm only seeing this template occur once (for instance a JS constant like YIREO_GOOGLETAGMANAGER2_PRODUCT_DATA_ID_42 is only set once). I checked the source code of the Luma theme and it shows this container is only created once, and definitely not for related products.

Furthermore, the term "item data script" could also be applied to a JavaScript file being loaded on the product page. The only script that is loaded that has impact on add-to-cart actions (thus the GTM add_to_cart event) is the script catalog-add-to-cart-mixins.js. It changes the behaviour of the regular submitForm() function of the regular add-to-cart action and then uses the JS constants YIREO_GOOGLETAGMANAGER2_PRODUCT_DATA_ID_42 (mentioned above) to add product details into the GTM event add_to_cart. Because there is only a single constant, it only is able to add a single product to that event, which is the main product of the product detail page.

Perhaps it is not the add-to-cart of the main product but an add-to-cart of the related products that you are using? By default, Luma uses a template product/list/items.phtml for this. With the right configuration, you can show add-to-cart buttons in those related products. However, none of that uses the product.info.form.content container, none of that uses the JS mixin mentioned above and there is no add_to_cart event being generated via the related products - simply because it is not a feature of this extension. So the bug you describe can't be related to this, right?

You mentioned page view, but I assume you are aware that that's a GA3 term that is no longer work in the current version of Google Tag Manager since July last year. So no harm done there. There is a view_item event. This shows - on the product detail page - the main product, but is not supported for related products.

As of yet, I'm unable to reproduce this - in a plain Magento 2 site with Luma installed and zero modifications. However you mention explicitly that the product/details.phtml template is added to your related products as well. Could you please analyse why this is, because the Magento core code and my extension code are not giving any hints here?

mountainit-general commented 8 months ago

Thanks for the elaborate answer and apologies for the difference in vocabulary, I am not a GTM expert and may have mixed up some terms.

Anyway, a colleague here looked at it more in depth now. It seems that something did not go quite right locally and indeed some custom plugin was still active when I was pretty sure I was testing it without any third party plugins and Luma. This used the product/details.phtml for the related products was well, which we now also confirmed does not happen in any other installs. So this totally was the cause of the extra events.

We managed to fix this in the custom plugin that was added to this client's shop.

Thanks for your time and explanation.

jissereitsma commented 8 months ago

Good to hear. Thanks.