Blog

  • Technical overview of new APP+WEB Properties

    Some days ago, Google announced a new upcoming property type for Google Analytics, they called them “APP + WEB”. And yes, the name says it all, finally we’re going to be able to measure our apps and websites at the same time. This has been for years one of the biggest handicaps of Google Analytics, and not only that, when Firebase came into the scene, we had ended having two platforms to measure apps, double the SDK’s and despite having all this tools we were not able to measure users accross platforms properly.

    But Google finally took the right step and they’re going to merge everything within the same platform, and also they are moving away from a “session” based tracking model to a events” based tracking model. Yes, you’ve heard it right, sessions as we do know them now will be gone ( don’t worry we’ll have sessions anyway, continue reading ..)

    This post won’t be covering the basic details about this new properties details, how the reports work since that’s all is covered by other authors in the blogs: New App + Web Properties in Google Analytics by Krista Seiden or A new way to unify app and website measurement in Google Analytics on Google Blog , or a google all-in introduction by Simo Ahava HERE .

    The star feature of the new properties is that they offer a way to unify our measurement strategy across different devices in one single place. Yay! ,
    On this post we’ll be learning how the new properties work, from a technical/implementation point of view and which are the most important changes compared to the current Google Analytics tracking.

    The main change on the tracking side and that from now on ALL is an “event” . The new platform is based on GA4F ( Google Analytics for Firebase ) , so we need to define everything ourselves.

    We need to start sending events and then based on these we’ll build the reports. In any case Google is including a default web tracking model within the APP+WEB properties which will allow us to have the most web relevant events in place and will be also offering some in-built parameters reporting ( same way we previously had dimensions and metrics based on events, returning visitors, etc ).

    Events

    event: {
            param1,
            param2,
            param3,
            paramN,
            user_parameters: {
             	         userParam1,
                             userParam2,
                             userParamN
            }
     }

    In the Schema above we can see the kind of data we can send along with an event to a APP+WEB property. Note that there’s a reserver parameter key called “user_parameters” that will hold and object with a list of the parameters related to the user. ( By the way we’ll need to define these in the UI first ).
    As you may noticied, there’s no longer any custom dimensions or metrics, so there are not cdX or cdN keys on our hits. Now we have Event Parameters and User Parameters instead.

    Measurement Protocol v2

    Along with the new APP+WEB properties, Google released a new protocol ( it’s more a v1 protocol version improvement rather than a new version ).

    If you usually work on debugging Google Analytics implementations you’ll be recognize most of th e parameters that you’ll see in the hits

    As an example, check the image below for how a simple page_view event hit looks like. I’m pretty sure you’ll feel familiar with most of keys.

    New Parameters List

    I tried to document the most import new keys that are part of the new Measurement Protocol. Here is a list of them:

    enEvent Name
    _fvFirst Visit
    _ssSession Start
    sidSession ID
    segSession Engaged
    sctSession Count
    _pCache Buster?
    _etEvent Time ( time since start for this event )
    ep.[a-z]Event Paramter ( String )
    epn.[a-z] Event Parameter ( Number )
    up.[a-z] User Parameter ( String )
    upn.[a-z] User Parameter ( Number )

    DISCLAIMER: APP+WEB is currently in beta and it’s likely adding new parameters in the upcoming months to cover all the current Google Analytics functionality / data points.

    Transport details

    Actually in Universal Analytics, the hits may use 3 different transport types:

    new Image() ( used for GET hits )
    XMLHttpRequest ( used for POST hits )
    sendBeacon ( Optional transport )

    It looks like the new library just uses sendBeacon for sending the hits, which looks like a good choice looking to the current functionality adoption by browsers:

    We also can find a new endpoint: Now the hits will be send to the following URL ( note the “g” )

    https://www.google-analytics.com/g/collect

    So, you said that we’ll have to look at the Request Payload in order to get the current hits data, is this correct?

    Not at all, what we said is that now hits are sent using the POST method (sendBeacon uses POST method to work). But still we can POST data to an URL that have a querystring.


    This means that on the new measure protocol the data is sent to the endpoint using and hybrid approach, a mix of a QueryString and Request Payload are used for sending the data. Some data is sent in the Query String and some details “may” be sent in the Request Payload ( POST Data ). In overall common hit details like the clientId, the language, the screen resolution ( all this data will be shared by all the events ) will be sent using the Query String, and the events details will be send in the Request Payload. Anyway we’ll see that this won’t be this way in all cases, since there will be differences on how the hit payload it send depending if the hit has one event, or more than just one.

    Continue reading to learn how to identify the different hit formats you’ll find.

    Multi Event Hits

    In the newly released protocol, we can send multiple events within one single hit request ( beware this is not the same as the previous “batches” in Universal Analytics ).

    This is a nice feature because it will help us reducing the number of requests that our site will be loading.

    But, wait a second…

    In the previous table you showed there was only one slot key for the event name, how is it supposed to work if we can send more than 1 event?.

    We already learnt that the new protocol uses a mix of QueryString and Request Payload in order to send the data to the endpoint. And we also briefly mentioned that depending on the number of events travelling within the hit the behaviour could be differents.

    Let’s take a deeper look to how it works:

    So, events details may go into the Query String or within the Post Data, depending on the events count in the hit. This helps on reducing the number of request send to Google Analytics servers and also helps reducing the payload size, since the details shared by the events are only send once. Double Win!.

    Events Queing

    This is not directly related to the measurement protocol itself, but it’s one of the first things that I saw when I started playing around with APP+WEB and it made me think I was doing something wrong.

    You may have noticed that when you push an event using the official GTAG API the data its not flowing to the endpoint as soon as you push it, There’s a small delay between the time you push the event and the hit shows up in the network tab. DON’T WORRY, this is normal, the new GTAG library, queues the events and dispatch them altogether each 5 seconds ( +/- ), remember that the new protocol allowed to send multiple events on each hit?, this take advantage of that feature.

    Debugging

    With all the previous details, you should be able to understand and read most of the details from the hit requests, but you can make your life easier using some extension that will parse the requests details properly and show you the details in a more friendly way.

    If you want you can take a look to my GTM/GA Debug Extension which actually support GA4F ( Google Analytics for Firebase ) hits.

    Cookies and Sessions

    The APP+WEB properties use not 1 but 2 cookies in order to perform the tracking on a website. The first one is an old friend of all us:

    “_ga” cookie, nothing changed on it, it will be taking care of holding the current user ClientID.

    “_ga_XXXXXX” cookies We’ll be find a new cookie for each of the Measurement ID’s we’re using on our site. Meaning that if we have a dual or triple tracking setup we’ll have the same amount of cookies, since they keep they own namespace and cookie.

    Let’s review all the technical details about this new cookie

    Cookie Name

    _ga_MEASUREMENT_ID

    Cookie Domain and Path

    The cookie is set to the nearest root domain name and it uses ‘/’ path by default

    Cookie Duration

    2 years

    Cookie USe and Format

    Do you remember back in Urchin or legacy analytics (ga.js) days when the session data was calculated via user cookies?, Then we switched to Universal Analytics and everything was being calculated server-side on Google side.

    Now with the new APP+WEB properties we’re back to the roots ( almost ) since it uses a similar approach as the first Gooogle Analytics versions ( remember the UTMA and UTMB cookies? ), but with one small difference, the visits attribution will be still calculated on Google side ( no UTMZ cookie ). So that’s the main use for this cookie, keeping track of total sessions and current session state.

    Check the following image for a full cookie definition ( I have not found the use of the last cookie value yet )

    WEB MODEL

    Google is offering a pre-built reports and events model for websites tracking. So we don’t need to start from scratch. Therefore we’ll be able to send page_views, and APP+WEB will take care of collections some extra data for these events without us needing to define any extra parameters ( like the page_titles, sources, mediums, browser details, geographical details ,etc )

    If you take a look to any APP+WEB Property you’ll notice that you have at least 4 different events, despite you may be only sending a “page_view” event:

    I’m sure that you may be thinking, What kind of magic is this?, I didn’t setup any ‘user_engagement‘ , ‘session_start‘ or “first_visit” events on my setup, just the “page_view” one.

    The same way that APP+WEB has some in-built parameters for the “page_view” events like the source, medium, title, browser, etc . Google will use generate some auto-events based on some parameters from the hits.

    user_engagementFrom hits including the key “seg” in the payload.
    session_startFrom hits including the key “_ss” in the payload.
    first_visitFrom hits including the key “_fv” in the payload.

    HEY WAIT! Remember that almost everyone around is mentioning that sessions won’t be longer available on GA, that’s not a 100% true statement, it’s true that we’re moving to an event-tracked model instead of a sessions-based mode, but that doesn’t necesarilly mean that we won’t have sessions count at all. Now we’ll have some events to calculate our old sessions metrics along with some other ones. Based on the the current auto-events on App+Web, we’ll have:

    user_engagementCan be used to calculate the bounce rate
    session_startCan be used to calculate the total sessions
    first_visitCan be used to calculate new VS returning visitors

    Enhanced Measurement

    The “page_view” is the core event for web tracking, this didn’t change on this new version, but APP+WEB offers something called “Enhanced Measurement” which will help us setting some tracking in our sites without even needing to do anything else but turning on a checkbox.

    • Youtube Video Tracking
    • Outbound clicks ( Click Listeners )
    • File Downloads ( Click Listeners )
    • Scroll Tracking ( 90% event )
    • Pageviews ( on page load or history changes )
    • Site Search Events
  • Google Tag Manager Custom Template – BrainSINS

    Today’s custom template ifs for: BrainSINS , a personalization platform based in Spain.

    Just import the template into your container and set the Token that you’ll find in your user corner.

    Downloadhttps://github.com/thyngster/gtmtemplates/tree/master/BrainSINS

  • Detecting if Google Analytics is being blocked using a Google Tag Manager Custom Template Tag

    Today I’m releasing a small Custom Template for Google Tag Manager that will take care of notifying the dataLayer about if Google Analytics is currently being blocked by the browser.

    Some days ago, I published the following tweet, to get some user’s feedback on Twitter. The approach not really bad, but having to deal with code is not the best solution for most people.

    I decided today to build a quick Custom Template to take care of checking if Google Analytics is being blocked. We’ll simply using the sendPixel library from Custom Templates. If you didn’t know if sendPixel library allows you to fire an onSuccess or onFailure callback functions.

    Then based on these callbacks the template will be push the data accordinlty to the dataLayer. And from there you may do whatever your want, like notifying an external application with an event, or showing the user any alerts ( this was just a dummy idea, please don’t annoy the users on this ).

    sendPixel(url, onSuccess, onFailure)

    The Custom Template has some configurations available to fine-tune que current behaviour of the tracking.

    • You can decide if sending an event if GA is being blocked or if GA is NOT being blocked
    • You can individualy define the event names for each of the previous pushes
    • You can set how often you want to the template to check if GA is being blocked. On each pageview, once per session ( 30 min ) or a personalized time period.

    If you’re insterested on trying it, you can DOWNLOAD it from my github repo:
    https://github.com/thyngster/gtmtemplates/tree/master/Google%20Analytics%20Block%20Checker

  • Release: Yandex Metrica Debug Extension

    About one month ago I started to work on a Google Tag Manager Custom Template for Yandex Metrica, I must say it was my first contact with it apart from installing the default snippet some years ago on this same blog.

    In order to ease my testings for the template I ended building a Browser Extension which I’m releasing today for Chrome, Firefox and Opera.

    I tried to cover all the differents hits that Yandex may send, but of course I may be missing some of them ( more likely to be on the beta JS library ). The extension currently support the following hit types:

    • Hit (Fields Reported: URL, Title, Referrer, full payload details)
    • reachGoal (Fields Reported: Goal ID, Currency, Value, , full payload details)
    • setUserID (Fields Reported: UserID, full payload details )
    • params (Fields Reported: Key,Value Up to 5 levels , full payload details )
    • userParams (Fields Reported: Key,Values Object , full payload details )
    • notBounce(Fields Reported: none , full payload details )
    • webvisor (Fields Reported: All Post Payload for webvisor is reported in a beautified way, full payload details )
    • ecommerceDetail (Fields Reported: Product Details , full payload details )
    • ecommerceAdd (Fields Reported: Product Details , full payload details )
    • ecommerceRemove (Fields Reported: Product Details , full payload details )
    • ecommercePurchase (Fields Reported: Purchase Details+ Product Details, full payload details )

    It may happen that the extension is not able to detect the hit data type, and it will be shown as undetected row:

    Don’t worry about this kind of rows in the reports they will be gone gradually as long I continue learning about Yandex Metrica Protocol and API.

    I’d define the current extension status somewhere between Alpha and Beta. So have in mind that you may find bugs while using it in your sites. Please don’t hesitate to contact me so that way I can improve the extension functionality. 🙂

    CHROME WEB STORE ( INSTALL LINK ) : https://chrome.google.com/webstore/detail/yandex-metrica-debugger/ehppjfimmbekmmponndiiiofmmdmgjlp

  • Google Tag Manager Custom Template – Algolia Search Insights

    Algolia is a company that offers a Search_as_a_service tools. They offer a Real Time services, which can be improved by sending events about users interactions over the products your site like add to carts, adds to wishlists, clicks after search, filters use, or conversion.

    For this task they offer a the Search Insights JS library.

    This library currently allows to track 3 main types of events:
    Clicks (clickedObjectIDsAfterSearch , clickedObjectIDs, clickedFilters)
    Conversions (convertedObjectIDsAfterSearch, convertedObjectIDs, convertedFilters)
    Views (viewedFilters, viewedObjectIDs)

    From now on you can setup your Algolia’s Search Insights, via Google Tag manager using a Custom Template.

    At this first Release the following functionality is implemented on the Custom Templates

    Methods/Events

    • viewedFilters
    • viewedObjectIDs
    • clickedObjectIDsAfterSearch
    • clickedObjectIDs
    • clickedFilters
    • convertedObjectIDsAfterSearch
    • convertedObjectIDs
    • convertedFilters

    Events Variables

    • userToken
    • index
    • eventName
    • objectIDs
    • filters
    • queryID
    • positions

    Advanced Settings

    • Manage if the current user has Opted Out
    • Override the default cookie duration (default value 6 months)
    • Region value setting from the Init Tag
    • User Token persistance. You can define the User Token within the Init tag and it will be persisted to the subsecuent events sent to Algolia Search Insights

    Where do I get the Custom Template

    Download: https://github.com/thyngster/gtmtemplates/tree/master/Algolia%20Search%20Insights

  • Google Tag Manager Custom Template – Barilliance

    Barilliance, is a eCommerce personalization tools for eCommerce including cart abandonment/retargeting emails and personalized product recommendations.

    The tag setup is pretty easy, just add your account id into the unique available place in the tag configuration 🙂

    Where do I find my Account Domain ID

    Where can I download the custom template

    Download: https://github.com/thyngster/gtmtemplates/tree/master/Barilliance

  • Google Tag Manager Custom Template – Sleeknote

    The following custom template for Google Tag Manager, will help adding Sleeknote to your sites.

    Sleeknote is a customer engagement tool, mostly focused on Ecommerce Websites.

    The setup is pretty simple, just add your account ID within the Account ID textbox in the tag.

    Where do I find my Account ID

    Where can I download the template

    Download: https://github.com/thyngster/gtmtemplates/tree/master/Sleeknote

  • Google Tag Manager Custom Template – Yandex Metrica

    It’s been a while since my last post ( Shame on me!) , but the new Custom Templates feature has been a great addition to Google Tag Manager the last week.

    If you don’t know what the Custom Templates are, please do yourself a favor and read Simo Ahava’s great guide on them.

    I’ve been playing the last days with this new feature, trying to build a more complex template, so I decided to try to implement a full Yandex Metrica Custom Template for Google Tag Manager.

    What’s supported:

    Method ( track types )

    • Init
    • Outbound links ( Fields: URL )
    • File Downloads ( Fields: URL , Referrer )
    • Reach Goals ( Fields: Target, Order Price, Currency )
    • Hit ( Fields: URL, Referrer, Title )
    • User Id ( Fields: User Id )
    • Session Pameters ( Fields : Parameters Map )
    • User Parameters ( Fields : Parameters Map )
    • Not Bounces

    Tracking features supported on the tracker:

    • Enabling/Disabling default Data Sending ( default pageview, useful for SPA Sites )
    • Enabling Hash Tracking
    • Disabling sending pages to Yandex Index
    • Loading the Script library from the alternative CDN
    • Enabling/Disabling Accurate Track Bounce tracking
    • Enabling/Disabling Click Maps tracking
    • Enabling/Disabling Track Links ( including extensions personalization)
    • Enabling/Disabling Webvisor
    • Enabling Disabling the Debugging Cookie
    • Ecommerce Tracking ( data layer variable name can be personalized )

    I’ve included some advanced features ( I’m new to Yandex Metrica, so I had no time to properly test them yet )

    • Debug Mode can be enabled from Init Tag without the need of setting up a QueryString parameter

    Upcoming features

    • Callbacks support
    • Code improvements/comments

    You can get the template from the following URL: https://github.com/thyngster/gtmtemplates/tree/master/Yandex%20Metrica

    ChangeLog 14 June 2019

    • Fixed Ecommerce Setup . It was not being initilized.
    • Minor UI Reorganization
    • Added Session Parameters Tracking
    • Added User Parameters Tracking
    • Added userID Tracking
    • Added not-Bounce Tracking
    • Fixed Debug being reset on after init methods

    Screenshots

    Waiting for your feedback and request 🙂

  • Release: Google Tag Manager Debugging Extension

    Today is a big day!, I finally managed to put some of my internal debugging snippets within a single Chrome Extension and I’ve just released it on the Chrome Webstore so everyone can try and use it.

    To install it you will need to visit the extension page on the Google Chrome Webstore, you can there just clicking on the screenshot below:

    NOTE: The first time you open the extension panel. It may be show an empty report, just click F5 to start seeing data. This will be fixed on next release.

    The extension focuses on debugging Google Tag Manager implementations ( most information reported is related to dataLayer information ), and it does also offer some information about Google Analytics hits being sent from the current loaded page ( ok folks:  only Universal Analytics is supported, if you’re using the legacy GA library (ga.js) please give your implementation/client a bit of love and upgrade to Universal Analytics ).

    The current extension release provides the following information:

    • dataLayer pushes list ( including some profiling details, like the time passed between pushes )
    • Current push details and current dataLayer model status for each dataLayer push
    • Google Analytics hits sent by the current page.

    Along with the pieces on info abouve the following features are available:

    • All dataLayer pushes are shown in a prettified way, so they are more readable and easy to use.
    • You can individually copy to the clipboard any push details in a formatted way ( useful for when making documentation for clients )
    • Hits payload are shown in a prettied and formatted way, making the debugging even  easier.
    • You can filter the hits by the UA property ( great for when you’ve some big implementations sending hits to different properties )
    • You can filter the hits by the type ( event, timing, pageview, etc )
    • You can see the details about how each GA hit was sent, using GET, POST, or if it was sent using image or beacon transports
    • You can easily view the current hit payload size and if it contains any Enhanced Ecommerce Data

    The current GTM Debug Extension is somewhere between Alpha and Beta stages, so don’t be so hard with it. I’m already aware of it having some weird behaviour over some websites and it would be really helpful if you could take 5 minutes to report these bugs to me. I’ve opened a Google Group in order to be able to get feedback and bugs reports.  You can find it on the following link: https://groups.google.com/forum/#!forum/gtm-debugger-extension

    If you are working on a client website and want to expose the website, you can reach me through twitter or use this website’s contact form :).

    Looking forward for your comments in order to improve the extension! 🙂

    Install Extensionhttps://chrome.google.com/webstore/detail/gtm-debug/ilnpmccnfdjdjjikgkefkcegefikecdc

    Extension Screenshots

  • Proper method/tips for setting up Facebook Pixels with no errors

    I’m finding a lot of people lately complaining about their Facebook Pixels throwing an infamous “duplicate pixel” error:

    fbevents.js:9 Facebook Pixel Error: Duplicate Pixel ID: XXXXXXXXXXXXXXXXX

    This  error is thrown because we’re trying to initialize a pixel ID twice and therefore FB complains about it. And nope you are not alone 🙂

    For example you may have a FB pixels that fires on the page load like this:

    fbq('track', "PageView");

    And then you may have another Add To Cart event like this:

    fbq('track', 'AddToCart'
       , { 
        brand: 'Apple',
        sku: 'MN4L2LL',
        content_ids: 'JET BLACK',
        content_name: 'Iphone 7 Plus',
        content_type: 'product',
        value: '1130.33',
        currency: 'EUR'
    });
    fbq('init', 'MY_FB_PIXEL_ID');
    fbq('track', 'AddToCart'
       , { 
        brand: 'Apple',
        sku: 'MN4L2LL',
        content_ids: 'JET BLACK',
        content_name: 'Iphone 7 Plus',
        content_type: 'product',
        value: '1130.33',
        currency: 'EUR'
    });
    
    

    The code above will show that ugly error into your browser console, despite you didn’t do anything really bad at all. ( I don’t really get why the FBEvents.js doesn’t just silently ignore the init if the pixel Id is already initialized :X )

    This said, let’s explain how Facebook Pixel works:

    As you can see each ‘init‘ method call, puts that pixel id into an internal array. And then each track call will loop through that array firing a hit for each already “initialized pixel id” on it.

    Yep, this means that after a pixel has been initialized any call to the “track” or “trackCustom” method will forcedly be sent for all current initialized pixels !! Meaning that you won’t be able to control which pixels should be sending the current action. I can’t really understand why each pixel doesn’t own their own namespace to have a better control.

    Now let’s see which would be the best way to setup our Facebook Pixels using Google Tag Manager.

    1. One that that is going to take care of initializing all our Facebook Pixels.

    2. On each different action we want to track on FB (eg: “Add To Cart”, “ViewContent”). We’ll be adding just the method call, since the main library an object are already in place! 

    Techie Fix Alternative

    Another way of fixing this error is checking if the current pixel we’re using is already initialized before calling the “init” method. As usual some coding may help us, we can check it using the following JS snippet:

    if (window.fbq.__fbeventsModules.fbevents().getState().pixels.map(function(pixel) {
            return pixel.id;
        }).indexOf('MY_FB_PIXEL_ID') == -1) { // PIXEL NOT INITIALIZED. DO YOUR STUFF }