Unable to get dataLayer.push to function following installation of GTM script

I am looking to incorporate Enhanced Ecommerce using Google Tag Manager and I need to send additional data for the Universal Analytics tag.

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

However, I'm facing an issue where dataLayer.push only works if it is placed right before the GTM script.

For example, this setup 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 place dataLayer.push after the GTM script, it doesn't work - no data is sent and no errors are reported.

This configuration is not effective:

<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>

    <!-- some 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>

Answer №1

If you don't follow best practices, be prepared for potential issues down the road.

  • Always opt for .push over initialization: Starting with array initialization (dataLayer = []) can cause problems if the dataLayer already exists. This initialization will overwrite everything, including the customized .push method used by GTM to receive pushed events. Although it may work now because GTM is called after initialization, this practice is risky. One day, moving GTM above the initialization or adding similar initializations after GTM could result in a breakdown.

Your code should look like this:

window.dataLayer = window.dataLayer || [];  
dataLayer.push({...});
  • Don't forget to include the event property: The event property is crucial for GTM triggers and determining when data is available. While you can have consecutive .push calls where the first has an event and the second doesn't, relying on this behavior is not recommended.

For example:

dataLayer.push({
  'event': 'ecommerce', // naming is your choice, but must match your GTM triggers 
  'ecommerce': {
  ...

In your case specifically, without the event key, things work only because GTM loads after the push. If the push call moves before GTM, missing the event property means GTM won’t know when the data is ready. To avoid this issue:

  • Include the event key always
  • Create triggers that align with the event

Here are some resources for further reading on these topics:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The order in which JavaScript files are loaded is critical, especially when dealing with external

After experiencing issues with my script not working because it was loaded before jQuery by the client (a necessity), I am seeking a solution. My challenge lies in ensuring that my code waits for jQuery to load before execution, especially when dealing wi ...

Get Python CSV file with Callback feature

When trying to download a CSV file from Morningstar by clicking on a button link, the presence of a callback in the URL seems to be hindering the download process. Even when pasting the URL (http://financials.morningstar.com/finan/ajax/exportKR2CSV.html?&a ...

Error: Trying to retrieve the 'substr' property from an undefined value

Apologies for any confusion, I have a lengthy script that is causing an issue when live. The error message in Chrome's Console reads: Uncaught TypeError: Cannot read property 'substr' of undefined This snippet of code seems to be where t ...

Using JavaScript to dynamically invoke a function and pass parameters dynamically

Exploring a dynamic method call with parameters in JavaScript. let obj = { method: 'foo1', params: ['one', 'two'] } foo1(p1, p2) { // do something } To execute it => [obj.method](obj.params) Is there a way to dyn ...

What is the best way to stop a web page from automatically scrolling to the top of the browser?

I am experiencing an issue on my webpage where, after scrolling down and selecting an item to view, pressing the browser back button causes the page to scroll back to the top instead of the previous location. The webpage is using JavaScript to render a l ...

Having trouble populating a datalist with options sourced from a MySQL table, as the options do not consistently show up (Node.js)

My goal is to dynamically populate a datalist with option elements by querying a MySQL server using node. The requirement is that if the inputted text by the user matches any part of a university name in the database, that university should be displayed as ...

Tips for resolving the issue of 'no serverless pages built' during deployment of a Next.js application on Vercel

Recently, I've been encountering the same two errors while trying to deploy my NextJs app: // and will just error later on Error: No serverless pages were built. You can learn more about this error here I'm stuck and unsure of how to resolve bo ...

Exploring the realm of Jquery and the world of JavaScript namespaces

As I attempt to organize my js/jquery code with namespaces, I've encountered an issue. Previously, I used to write all my JS code in each html/php file, but now I want to consolidate it into a single js file with namespaces. In my html file, I have ...

Utilize an asynchronous method to upload files to Google Cloud Storage in a loop

I am new to using Javascript and have been working on a loop to upload images to Google Cloud Storage. While the image uploads correctly with this code, I'm facing an issue where the path (URL) is not being saved in the database AFTER the upload. I a ...

Updating the div#content dynamically with Jquery without the need to refresh the page

After spending countless hours on this forum, I have yet to find a solution that perfectly fits my needs, so I will pose my question. Here is the gist of what I am attempting to accomplish: When the page loads, the default page fades in and displays. Wh ...

Setting the result of d3.csv into a globally accessible variable

Is there a way to store the data fetched from a csv file using d3.csv() in a global variable for future use? I'm facing an issue where the global variable dataset is showing as undefined even after assigning it inside the d3.csv() function. var datas ...

There was an issue encountered while trying to install Electron using the command 'npm install electron'

While attempting to install electron using npm install electron, I encountered the following error: 908 error code 1 909 error path C:\Users\name\Documents\name\Code\code\node_modules\gl 910 error command failed ... ...

Ways to establish whether the element $(this) is present in an array during a click event

I am currently working on populating 4 arrays with a set of id values. Each array will eventually be assigned text values for an h1 and a p element, but for now I am focusing on setting up an alert when one of the images in the array named graphicDesign is ...

Directive ng-click not executing as expected

Currently, I am developing an Angular application that involves a controller named visualization and a directive named force-layout. Within the HTML template of the directive, I have implemented three buttons with corresponding functions attached to them. ...

Failure to trigger AJAX error function when database match is not located

UPDATED: Having some issues with my code entry box when a match is not found in the database. Below are the results for both a good and bad match. Check out my code snippet: function checkDiscountCode() { var discount; if ($('#dbReturnString') ...

I am looking to modify the visibility of certain select options contingent upon the value within another input field by utilizing ngIf in AngularJS

I am currently utilizing Angularjs 1.x to develop a form with two select fields. Depending on the option selected in the first select, I aim to dynamically show or hide certain options in the second select field. Below is the code snippet for the form: &l ...

Detecting a mobile device when using NextJS can be accomplished by using user

With so many topics and questions on Stack Overflow, I am struggling to find the most efficient solution for detecting mobile devices. I have two components - one designed solely for desktops and another for mobile devices. {isMobile? (<SecondComponen ...

TinyMCE - Utilizing selection.setContent along with getContent for the Warp Button

I am looking to implement a button that will wrap content with all tags. Snippet of Code: editor.addButton('MobileToggleArea', { text: '<M>', icon: false, onclick: function (){ editor.selection. ...

Utilize AJAX, jQuery, and Symfony2 to showcase array information in a visually appealing table format

I have a requirement to showcase data utilizing ajax and jQuery in a table on my twig file. The ajax call is made with a post request to the controller, where the controller attempts to input several rows from a csv file into the database. However, there ...

Modifying a variable in $rootScope data will also update other instances of $rootScope data

Since I need to use the data in multiple controllers, I have stored it in $rootScope.currentCache. When the page loads, the data typically looks like this: { System: "Foo Bar", StartDateTime: "2014-11-27T12:35:00" } (please disregard any formatti ...