dataLayer.push not working after GTM script
Asked Answered
P

1

16

I want to implement the Enhanced Ecommerce with Google Tag Manager and I want to push some data for the tag Universal Analytics.

I have always created the dataLayer before the GTM script, but now I need to send more data with dataLayer.push

And it doesn't work, datalaLayer.push only works if it happens just before the GTM script starts.

Example. This works:

   <script>
    <head>
     dataLayer = [{   
                 
            'google_tag_params': {
               'ecomm_pagetype': 'category',
               'ecomm_category': '{{ $resource->seo->h1 }}',
             }
         }];
    
    dataLayer.push({
              'ecommerce': {
                'currencyCode': 'EUR',    
                'impressions': [
                     {
                        'id':       '12312',
                        'price':    24,
                        'category': 'wfwefwerwerwer',
                        'position': 2,
                        'name':     'wfwefwerwerwer',  
                        'brand':   'My Brand',
                        'list':    'Product List',
    
                    }
                ]
              }
            });
    
    (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXXXX');
    
    </script>
    </head>

But if I use dataLayer.push after the GTM script does not work, no data is sent and no errors are reported.

This isn't working for me:

<head>
    <script>
         dataLayer = [{   
                     
                'google_tag_params': {
                   'ecomm_pagetype': 'category',
                   'ecomm_category': '{{ $resource->seo->h1 }}',
                 }
             }];
        
        
        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','GTM-XXXXXX');

    </script>
</head>

<body>

    //something content html here

    <footer></footer>

    <script>
        dataLayer.push({
          'ecommerce': {
            'currencyCode': 'EUR',    
            'impressions': [
                 {
                    'id':       '12312',
                    'price':    24,
                    'category': 'wfwefwerwerwer',
                    'position': 2,
                    'name':     'wfwefwerwerwer',  
                    'brand':   'My Brand',
                    'list':    'Product List',

                }
            ]
          }
        });
    </script>
</body>
Penetrating answered 1/8, 2018 at 5:37 Comment(5)
What do you see in GTM debug mode, when you open this page? The push call seems to be fine, although its missing an event, which could be processed by GTM. You won't have this data during the Page View event, but you'll see an event you specify, and you can build triggers on it.Hygroscope
@kgrg, I think you should make this an answer. That the data is not available due to the missing event will make it look like this isn't working, so this seems the most likely culprit.Lowrance
BTW for newcomers to Analytics it's really badly explained in the documentation that window.dataLayer.push is actually PATCHED by GTM to run its own code. It isn't just a dumb array sitting on the page anymore. So that's how you're able to add to it later. Type window.dataLayer.push in the browser console and you'll see it's a custom function in gtm.jsHolierthanthou
Tip: Disable Caching in Chrome when frequently updating GTM tags to make sure you get the latest version technipages.com/google-chrome-how-to-completely-disable-cache - Sometimes you may have everything perfectly setup but your browser is just using an old versionHolierthanthou
You're missing the var part of declaring dataLayer. You can use var, or just add it to the window namespace window.dataLayerJackquelin
U
27

You're not following best practices, so you'll run into issues, sooner or later.

  • Always use .push instead of initialization: your first call is an array initialization (dataLayer = []). This means that if the dataLayer already exists, it will be completely overwritten, including the .push method which is customized by GTM in order to receive pushed events. Right now it's working fine because you're calling GTM after the initialization. But it's a bad habit to take. One day you will move GTM above that initialization or add similar initialization calls after GTM, and it will break.

Your calls should be:

window.dataLayer = window.dataLayer || [];  
dataLayer.push({...});
  • Always set the event property: the event property is what is used by GTM to define triggers and know when data becomes available. You can have 2 successive .push calls, the 1st with an event, and the 2nd without, and the data from the 1st will be available in the 2nd (as long as that push doesn't overwrite it), but once again that's bad habit and playing with fire.

For instance:

dataLayer.push({
  'event': 'ecommerce', // naming is up to you, should match your GTM triggers 
  'ecommerce': {
  ...

In your particular case, since the event key is missing, it works as long as GTM loads after the push, because the data is already there when GTM kicks in. When the push call is moved after GTM, because there is no event property, there is just no way for GTM to know when data becomes available. So you should:

  • Add the event key (always!)
  • Configure a trigger which matches the event

Here is some more reading on those topics:

Unlash answered 1/8, 2018 at 9:4 Comment(2)
My first call should be dataLayer = window.dataLayer || []; and dataLayer.push({...});, but, where place GTM script? before or after? ThanksPenetrating
GTM should load as soon as possible to minimize delay (browser needs to fetch GTM = 1 network round trip, then fetch other libraries = 2nd trip, then eventually fire the analytics events). So place GTM as early after <head> as you can. As for .push calls, it doesn't matter where you place them as long as you always use .push and initialize 1st time (window.dataLayer || []). If GTM is already in place, you will grab the dataLayer it created (window.dataLayer), if not you will create a dummy array (` || []`) which GTM will later convert to a proper dataLayer while preserving its data.Unlash

© 2022 - 2024 — McMap. All rights reserved.