Magento2: Blocking Google Analytics prevents Checkout

Created on 24 Nov 2017  路  34Comments  路  Source: magento/magento2


Preconditions


  1. Magento 2.2.1
  2. PHP 7.0.25-1~dotdeb+8.1
  3. mysql Ver 15.1 Distrib 10.0.32-MariaDB
  4. uBlock Origin 1.14.18 on client

Steps to reproduce

  1. Enable Google Analytics in Stores > Settings > Configuration > Sales >Google API
  2. Install uBlock Origin on client, or block Google Analytics in any other AdBlocker
  3. Go to Checkout

Expected result

  1. Checkout is working

Actual result

  1. Checkout is loading infinitely

The rest of the site works fine. Apparantly the checkout just cannot handle any errors and will stop functioning immediately.

GET http://example.com/pub/static/frontend/Magento/luma/en_US/Magento_GoogleAnalytics/js/google-analytics.js net::ERR_BLOCKED_BY_CLIENT
Clear Description Confirmed Format is valid Ready for Work Reproduced on 2.2.x Reproduced on 2.3.x good first issue

Most helpful comment

We should be able to control if we want to be tracked or not. If the final user want to have an ad blocker he's free.
Actually a third party as the google analytics shouldn't broke the core functionality.
It's a major issue because we can't control (and we never should) if our customers has an AdBlocker or not..

All 34 comments

@dwirt, thank you for your report.
We've created internal ticket(s) MAGETWO-84475 to track progress on the issue.

This seems to be related to magento/magento2#13061 and #12828 . The pr doesn't appear to fix this issue though.

Even if you replace the x-magento-init block in Magento_GoogleAnalytic\view\frontend\templates\ga.phtml with...

<script type="text/javascript">
require(["Magento_GoogleAnalytics/js/google-analytics"], function (analytics){
        analytics({
            "isCookieRestrictionModeEnabled": <?= (int)$block->isCookieRestrictionModeEnabled() ?>,
            "currentWebsite": <?= (int)$block->getCurrentWebsiteId() ?>,
            "cookieName": "<?= /* @escapeNotVerified */ \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>",
            "ordersTrackingData": <?= /* @escapeNotVerified */ json_encode($block->getOrdersTrackingData()) ?>,
            "pageTrackingData": <?= /* @escapeNotVerified */ json_encode($block->getPageTrackingData($accountId)) ?>
        });},
        function(err) {
            console.warn(err);
        }
    );
</script>

...which shouldn't be able to kill any javascript flow, checkout-loader is still not cleared and the checkout doesn't work.

Error thrown is:

GET ####/en_GB/Magento_GoogleAnalytics/js/google-analytics.js net::ERR_BLOCKED_BY_CLIENT require.js:1895 

Caught error (printed as a warning is:

(index):261 Error: Script error for: Magento_GoogleAnalytics/js/google-analytics
http://requirejs.org/docs/errors.html#scripterror
    at makeError (require.js:166)
    at HTMLScriptElement.onScriptError (require.js:1681)

I'm not sure I understand requirejs enough to work out whats going wrong. I assume the error thrown by require.js:1895 which is not caught (?) is the culprit but I can't see how.

Just commenting out the script fixes the cart, so it doesn't _have_ to load to work.

I am not suggesting this should be the actual solution, but here is a work around, since I don't understand where the blocking comes from (although @andrewhowdencom seems to have an idea).

<!-- BEGIN GOOGLE ANALYTICS CODE -->
<script type="text/javascript">
        require(["jquery"], function ($){
            $.get("<?php echo $block->getViewFileUrl('Magento_GoogleAnalytics/js/google-analytics.js'); ?>",
            function( script, textStatus ) {
                require(["Magento_GoogleAnalytics/js/google-analytics"], function (analytics){
                        analytics({
                            "isCookieRestrictionModeEnabled": <?= (int)$block->isCookieRestrictionModeEnabled() ?>,
                            "currentWebsite": <?= (int)$block->getCurrentWebsiteId() ?>,
                            "cookieName": "<?= /* @escapeNotVerified */ \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>",
                            "ordersTrackingData": <?= /* @escapeNotVerified */ json_encode($block->getOrdersTrackingData()) ?>,
                            "pageTrackingData": <?= /* @escapeNotVerified */ json_encode($block->getPageTrackingData($accountId)) ?>
                        });
                    });
            }
            ,'text');
        });
</script>
<!-- END GOOGLE ANALYTICS CODE -->

It just tries to load the .js file using jquery _first_, only if this is successful does it allow require to have a run at it. If the jquery request fails there appears to be no adverse effects. If require fails there are, so don't let it even try until we know it works.

For anyone having the same Issue:

Check your Ad-Blocker settings ;-)

We should be able to control if we want to be tracked or not. If the final user want to have an ad blocker he's free.
Actually a third party as the google analytics shouldn't broke the core functionality.
It's a major issue because we can't control (and we never should) if our customers has an AdBlocker or not..

This certainly is an issue. I can confirm it for the 2.2.3 version.

Additional information and use cases: https://github.com/magento/magento2/issues/11208

Another solution is to just set the require.onError handler.

require.onError = function(e) {
  console.error("RequireJS Error", e);
}

You just need to create a template and add it before everything in the after.body.start block.

<referenceBlock name="after.body.start">
  <block name="requirejs-errors" class="Magento\Framework\View\Element\Template" template="Magento_Theme::html/requirejs-errors.phtml" before="-"/>
</referenceBlock>

The added benefit of this solution is that it'll catch any uncaught error during the requireJS process.

Does it prevent the infinite load gif (wheel of death)?

@thomas-blackbird Ya, it fixed it for me at least. That load gif stays there because there was an error in the JS code, and where there isn't an error handler setup, requirejs just poops.

I am also facing the same issue, and I don't have Google Analytics enabled on my website.

did anyone find any permanent solution?

I think adding the requireJS onError handler is a permanent solution.

@ragboyjr I've tried your approach as well as this https://github.com/magento/magento2/pull/13061/files but the loading wheel is still there. Surprisingly though, the problem does not exist when js bundling is enabled. Hope that helps someone.

@fluential interesting, it definitely fixed the JS issues for me. The code in the PR is a specific error handler for those require is entries, adding a global handler like i did seems to catch a bit more. But the more error handling the better honestly.

Adding the error handler to require did not work for me, but turning on js Bundling solved the issue for me. Credit to @fluential

@spectravp problem is, you don't always want bundling enabled. And it should not matter if it's enabled or disabled.

I'll try to find out what the cause is and how to fix the loader thing.

Alright, so the issue is that the loader is only removed as soon as all RequireJS dependencies are loaded. It uses mage/requirejs/resolver.js for this. I tried (together with @schmengler) to remove the dependency (i.e. with removing it from the registry and with requirejs.undef()), but without any result. I think the best solution would be to actually improve the resolver, so you can add "optional" requirements, so that if it fails, it will just skip that one from the resolver. That wouldn't actually resolve the issue with the Google Analytics file, but since this is done by the customer himself, it might be acceptable.

Also, the issue seems not to be there when JavaScript bundling is enabled, so if you do that on production, the issue will not be there.

For now, I think the best solution would be the solution mentioned by @lingwooc here.

Dropping require entirely from the dependenc resolution chain would avoid
this issue, as well as fix various others. This was the behaviour prior to
2.2(?)

See https://github.com/magento/magento2/issues/13267

On Sun., 22 Apr. 2018, 1:28 am Arjen Miedema, notifications@github.com
wrote:

Alright, so the issue is that the loader is only removed as soon as all
RequireJS dependencies are loaded.

>

Andrew Howden

Careful, well crafted web development.

W: https://andrewhowden.com/

PGP: https://pgp.andrewhowden.com (79BAC08A6ED1FF1EABE350A7587D3B3A961D2D2D)

It seems like @sidolov changed this a year ago from JavaScript to a RequireJS block. Moving it back to plain JavaScript could work, but I have the feeling that this is changed for a reason. Maybe @sidolov can give more information regarding this.

@ArjenMiedema I'm agree with you

I think the best solution would be to actually improve the resolver, so you can add "optional" requirements, so that if it fails, it will just skip that one from the resolver.

:+1:
I had the same conclusion as you: see referenced issue: #13346

@lingwooc Could you provide a little more detail on the fix? What file(s) did you modify?

Magento_GoogleAnalytics/templates/ga.phtml
https://gist.github.com/lingwooc/c6f09e3d0b37e67aafde73c578673bf6

You can fix it in a theme then remove it when magento finally decide they care/become competent. I guess it's OK, it's only sales this stops. No rush. You guys relax.

Christ, just noticed they've marked this to be fixed by the community!

@lingwooc we worked on it during Imagine and I'll probably follow up on this later. My idea would be that I'd just roll back to the "old school" implementation without requireJS for now, since there's no easy way to fix this without doing the call to the JS file twice. The nice way would be to make this "optional" in requireJS, but that's not available at this moment.

Hi!

Can you try if this helps? https://github.com/magento/magento2/pull/14874

@vovayatsyuk checked it with this issue and even though the error remains in the console, the loader is removed. Placing an order on my local machine also worked, so it seems like this is the fix for this issue that I was looking for. Thanks!

Looks like issue was fixed in scope of https://github.com/magento/magento2/pull/14874
I'm closing issue as not relevant

For enterprise maintainers using Magento_GoogleTagManager, #14874 does not fix the problem.

I applied the latest version of resolver.js and this does fix the problem as the whole isPending logic was revised by Magento core team.

On magento enterprise 2.2.6 and still get this issue - will this be resolved soon?

Can confirm what @asim-vax said. It does not fix the issue for Magento EE 2.2.6.

I tried on both vanilla versions and it does not work for the EE.

I can also confirm that the issue is still on 2.2.6 EE

Please put a fix for magento 2.2.3 here. It's very annoying that you always put a fix for the latest version of magento. People cannot upgrade their whole webshop for each bug or problem they encounter. You must have a better service for all your versions.

Was this page helpful?
0 / 5 - 0 ratings