Best practice for adding GTM tracking snippet to Sage 9 theme

Hello,

I’m looking to setup GTM on a few sites I have running Sage 9.

When you setup GTM, they advise to add x2 JS tracking snippets, one as high up in your as possible, and the other just after the opening tag.

My initial thought is, just add the tags directly to the partials/head.blade.php and layout/app.blade.php files and be done with it. Is this a sound approach?

Since these scripts don’t have dependencies, I don’t see what advantage I’m getting by using wp_enqueue_script, unless its more performant that the scripts be enqueued because they can be cached more optimally?

Using a plugin to do this seems like overkill, I’m aware of the plugins (but they seem to add a lot of additional cruft):

On a side note, I’m also curious if the approach would still hold for Sage 10 themes if I look to upgrade in the future.

Hi dear, it’s a please for me in first time answering something here, while being also the first to answer your question.

I think the solution I’ll propose here is better than what you have mentioned, but I don’t know if this is really the best one. I’ll share it and let’s see what the community experts say.

In the theme/functions.php file, find the line where it loads/register the “setup” and “filters” php files, add a new one, let’s call it “analytics”, so that block of code will look like this:

collect(['setup', 'filters', 'analytics'])
    ->each(function ($file) {
        [...]

Then, I created an environment variable called “GTM_ID” on my .env file:

#GOOGLE TAG MANAGER (GTM) ID
GTM_ID=GTM-XXXXXX

And finally, our analytics.php file, that includes the scripts required, on wp_head and wp_body_open using add_action, loading the GTM_ID from the .env file:

<?php

/**
 * Analytics helpers.
 */

add_action(
  'wp_head',
  function (): void {
    if(getenv('GTM_ID')){
      ?>
      <!-- Google Tag Manager -->
      <script>(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','<?= env('GTM_ID')?>');</script>
      <!-- End Google Tag Manager -->
      <?php
    }
  },
  1,
  0
);

add_action(
  'wp_body_open',
  function (): void {
    if(getenv('GTM_ID')){
    ?>
      <!-- Google Tag Manager (noscript) -->
      <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=<?= env('GTM_ID')?>"
      height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
      <!-- End Google Tag Manager (noscript) -->
      <?php
    }
  },
  1,
  0
);

Hope this get you to a good point! :slight_smile:

Thanks,
Matt.

5 Likes

Hi Matt,

Thanks for responding. Curious to know why you think this solution is better?

is it better because its more flexible if you want to add more layouts? or is it more performant? genuinely curious what is the difference between using the add_action vs. just creating x2 Blade partials (head-gtm.blade.php and body-gtm.blade.php) an adding to my layouts accordinly.

Thanks for the solutions!
It’s important, that your app.blade.php contains this peace of code after the <body> open:

  @php wp_body_open() @endphp

And your head.blade.php this peace of code:

  @php wp_head() @endphp