In HTML Datalayer output snippet is at wrong location before body closing

Created on 25 October 2023, about 1 year ago

Problem/Motivation

The datalayer out is before closing</body>at wrong location. It should be just after <head/> in html.

  <script>window.dataLayer = window.dataLayer || []; window.dataLayer.push({"drupalLanguage":"en","drupalCountry":"US","siteName":"Umami Food Magazine","entityCreated":"1698170269","entityLangcode":"en","entityStatus":"1","entityUid":"4","entityUuid":"5fef7eca-f9c2-4214-9b98-7e060202b9a8","entityVid":"12","entityName":"Umami","entityType":"node","entityBundle":"recipe","entityId":"6","entityTitle":"Gluten free pizza","field_number_of_servings":{"value":"4","_attributes":[]},"field_preparation_time":{"value":"15","_attributes":{"content":"15"}},"field_tags":[],"entityTaxonomy":{"recipe_category":{"31":"Main courses"}},"userUid":0});</script>

  </body>

Steps to reproduce

tested on Drupal 10.1.5 and Datalayer 2.0.1

Proposed resolution

In html put the Datalayer script just after head

Remaining tasks

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Active

Version

2.0

Component

Code

Created by

🇺🇸United States adanbouzoua

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @adanbouzoua
  • Assigned to shiv_yadav
  • Issue was unassigned.
  • 🇺🇸United States adanbouzoua

    The version 2.0.0 has not bug related to snippet placement.
    The bug was introduced with the version 2.0.1

  • 🇺🇸United States eojthebrave Minneapolis, MN

    I bet this is what changed ... moving to using hook_page_bottom to attach the code. https://git.drupalcode.org/project/datalayer/-/commit/80a6a9e35968ca9760...

    If you change that to use hook_page_top instead of hook_page_bottom does it fix the problem?

  • 🇺🇸United States adanbouzoua

    Update
    The previous test was done with Google Tag Version: 8.x-1.6 and Datalayer 2.0.1
    Changing Google Tag Version: 8.x-1.6. >> Version: 2.0.2 fix the issue

    Conclusion: Datalayer 2.0.1 + Google Tag 2.0.2 has no issue. The module works with Google Tag version 2 but not with Google Tag version 8
    ---
    dataLayer.push allows the snippet elsewhere than inside .
    It seems that it has been implemented on Google Tag 2.0.2 but not 8.x-1.6

    Data Layer declaration vs dataLayer.push
    By adding a dataLayer snippet above the GTM container snippet. This step is called “Data Layer declaration”.
    Or by pushing data with dataLayer.push method.
    https://www.analyticsmania.com/post/what-is-data-layer-in-google-tag-man...

  • 🇺🇸United States mihaic

    I propose to update the module page documentation and also the project readme file to reflect what #6 is saying, here a patch, thanks

  • 🇺🇸United States eojthebrave Minneapolis, MN

    Good discovery. Thanks for digging into this more. I added a note to the project page about compatibility with Google Tag module versions.

    I wonder if there's a way to add something to the composer.json file, or the .info.yml file for the module that would also declare this requirement. So that for example Composer would let you know that you have incompatible modules? I think something like that, plus a note in the README, would make the most sense.

  • 🇺🇸United States neclimdul Houston, TX

    I think technically this being at the bottom works but being in the footer does make using the datalayer much more complicated. The values aren't available for early hooks meaning if you're trying to pass them to something like the page view event they aren't available.

    Additionally, since they only push the values on, not triggering any events, there isn't a way to trigger pushing any values into a tag.

    It seems like it would cause fewer problems for developers if it was in the header somewhere. even better if it could go _before_ tag manager.

  • Completely agree with @neclimdul . Previously I was able to send dataLayer properties along with the page_view event provided by the default Google Tag. At some point these properties became undefined, now I know why.

    My current solution is to set the Google Tag trigger to "DOM Ready" instead of the default "Initialization". This means the dataLayer is already populated before the Google Tag is triggered, however it can have a negative effect on metrics due to the delay between Initialization and DOM Ready. Further reading: Page view triggers

    Ideally the dataLayer snippet should be above the GTM snippet. That way the dataLayer is already populated and people can use the default "Initialization" trigger for their Google Tag. The default config should Just Work™ IMHO.

  • 🇺🇸United States neclimdul Houston, TX

    Yeah, digging into it, its a pretty hard problem and current Drupal asset and script attachment is working against this module at every step so I see how the module ended up where it is.

    As time allows I'm playing with some solutions. drupalSettings with attached javascript, attachinline.module, etc.

    Likely something with drupalSettings is the only solution to get something at the top and not cached because Drupal has special allowances to make the settings play well with cached. But it also turns out it is very difficult to target specific orders to place this before the tag manager script and after the settings script.

    📌 Replace custom weights with dependencies in library declarations; introduce "before" and "after" for conditional ordering Needs review aims to improve this but it isn't committed yet so it is probably a ways out from being adoptable as a real solultion for this module.

    I'm leaning toward a best effort with drupalSettings and a javascript behavior with documentation on how to read from drupalSettings in tag manager using variables as a fallback for sites that run into trouble. This also improves CSP stuff by getting rid of unsafe inline scripts so it should be a win/win if I can get it working.

  • 🇺🇸United States adanbouzoua

    A related issue in Google Tag
    Script placement differences between 1.x and 2.x
    https://www.drupal.org/project/google_tag/issues/3451427 💬 Script placement differences between 1.x and 2.x Active

  • 🇸🇪Sweden peter törnstrand

    This also improves CSP stuff by getting rid of unsafe inline scripts so it should be a win/win if I can get it working.

    Does this mean that I should not develop CSP nonce support for this module? I'm getting rid of insecure-inline on a project I'm working on and the only problem left is this module. I was just about to begin working on a patch when I read the above.

    I was going for the same solution as in Support Content Security Policy Needs review

Production build 0.71.5 2024