How can I set up GTM with TurboLinks?
The problem:
GTM and the SEO team asks me to add this to my Head:
<% if user_signed_in? %>
dataLayer = [{'userID': '<%= current_user.id %>'},{'userCategory': 'User'}];
<% end %>
</script>
<!-- Paste this code as high in the <head> of the page as possible: -->
<!-- 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','GTM-N7MDCP');</script>
<!-- End Google Tag Manager -->
This will be cached by TurboLinks. I could try to wrap this in page:change, but that won’t update the values for user_signed_in etc.
Can I safely move this into the body, where TurboLinks will refresh it? If not, how else can i get GTM to work with a dynmic datalayer and GTM?
2
Answers
With a slight modification, yes.
Initialize the (empty) dataLayer variable above the GTM code.
Any change in the dataLayer can be then added via the
push
-method (which is not the standard javascript array push, Google has overwritten that for the dataLayer with their own implementation). If you add a new value without a native event (load, DOM ready, window loaded) you need also to add a custom GTM event (event
is a sort of reserved word in GTM; if you add an object with the key “GTM” to the dataLayer array GTM updates its internal data model with the new variables and you can use the event to fire tags).So your implementation might look something like this (this goes in the body. Also while I know GTM I do not actually know Turbolinks, but you get the idea):
Now you can create a trigger within GTM of the type “custom event” with the event name of “loginStateChanged”, and all tags that are fired with/after that trigger will have access to the userID and userCategory variables.
According to the Turbolinks docs, you have to add
document.addEventListener("turbolinks:load", function() {
to the beginning of a script that you don’t want to be cached (Turbolinks documentation reference).
See here for a full example.
Do the same for the dataLayer push script and include a console.log() in both scripts to make sure they’re firing when they’re supposed to and only when they’re supposed to.