Skip to content

Analytics

This is a guide on how our Google Tag Manager setup works, our conventions, data layer, and how the client-side and server-side tracking works.

This is by no means a comprehensive guide on how to use Google Tag Manager, but rather a guide on how we use it in our platform.

Abbreviations

  • GTM: Google Tag Manager Client Container
  • SGTM: Google Tag Manager Server Container
  • SST: Server-Side Tagging
  • CST: Client-Side Tagging
  • GA4: Google Analytics
  • GAds: Google Ads
  • CAPI: Conversion API
  • DLV: DataLayer Variable
  • CJS: Custom JavaScript

GTM

How it works

  • All GA4 events are sent to SGTM.
  • There's currently a custom HTML tag for clickcease that sends events directly to ClickCease (this tag is subject to change).
  • Algolia events are sent directly to Algolia (this should preferably be implemented on SGTM).

Naming Conventions

  • Tags: [Platform][optional: .priority] [optional: Event | Tag | Consent] - [Description][optional: -- Variant]
    • Algolia Event - Click Filters
    • GAds.98 Tag - Google Tag
    • GTM.98 Consent - Default -- CA
  • Triggers: [Source][optional: .target] - [Description][optional: -- Variant]
    • Click.button - addToCart -- Reactivation
    • Event - CTAClick
    • Calculated.cookie - GAds Consent Denied
  • Variables: [Type] - [Description][optional: -- Variant][ = (value)|value type|source]
    • DLV - Amount/Value = ecommerce.value
    • CJS - Is video on page

Datalayer

We use datalayer to pass information to GTM. There are currently two ways to make the information available:

  1. Setting the information to the datalayer without any given event - Messages
  2. Pushing an event to the datalayer with the information - Events

DataLayer event names are in snake_case. Properties are currently in two states, either snake_case or titleCase. We should aim to have all properties in snake_case.

Code

Messages

Messages are used to set information to the datalayer without any given event. The most common use case is to set user information on every page load.

Messages are usually set using the following snippet:

php
\Spatie\GoogleTagManager\GoogleTagManager::set('user', [
    // User information
]);

Events

Events are used to push information to the datalayer when something happens. Examples are "Add To Cart", "Purchase", or "Learning Path Selected".

Events are usually set using the \App\Modules\Analytics\Services\GtmDataReporter service:

php
app()->make(\App\Modules\Analytics\Services\GtmDataReporter::class)->addToCart(\App\Modules\Analytics\Models\CartItem::fromPrice($price));

Note: Make sure to read the inline documentation in the service.

We use GA4 Recommended Events and Parameters to set information from BE to GTM.

See the following classes and enums to have a better understanding:

  • \App\Modules\Analytics\Services\GtmDataReporter
  • \App\Modules\Analytics\Ga4\Contracts\Ga4Event
  • \App\Modules\Analytics\GtmEvent

Gtm Middleware

We're using a custom middleware, which intercepts both before and after the request.

See \App\Modules\Analytics\Http\Middleware\GtmMiddleware for more information. The implementation is inspired by \Spatie\GoogleTagManager\GoogleTagManagerMiddleware.

The middleware is responsible for the following:

  1. Setting all non-internal values from analytics store to the datalayer
  2. Fetching all values from session and setting them to GTM
  3. Storing all remaining values after the request is completed to the session to make it available for the next request

Difference between set and push

There are two ways to set information to the datalayer using the spatie/googletagmanager package:

  • GoogleTagManager::set: This methods makes the information available to the GTM container before any events are pushed. Only use this event to set information that is required by all events, like user information.
  • GoogleTagManager::push: This method makes the information available to the GTM container when the event/message is pushed. Use this method to set information that is only required by a specific event, like the product information when a product is added to the cart.

SGTM

How it works

All requests to our SGTM are claimed using a GA4 client.

SGTM also serves our gtm.js file, meaning that we have 1st party cookies on our domain.

There are different variables, responsible for determining the event name mapping as well as trigger conditions for different GA4 events to be sent to Meta, LinkedIn, and GAds. This is done using lookup tables and is the simplest way to prevent duplication. These variables should be treated as SSoT (Single Source of Truth) for conversion events sent to different platforms.

Naming Conventions

The current naming convention doesn't follow a strict rule, but names are chosen in a way that makes them easy to understand.

Variables

The biggest chunk of the magic in SGTM happens in variables. We mainly use lookup tables to determine if a tag should be fired or not or to transform data received, like event names.

Make sure you read the notes on each variable on GTM and keep it up-to-date.

We set a consent cookie on the client-side, which is then read by GTM. This cookie is used to populate many Calculated variables in GTM.

The given consent for SST is sent by GA4 tag to SGTM, which is then used in transformers to determine if user information should be removed or not.

Testing

Manual Testing

To manually test GTM and SGTM, you need to have 1st party cookies. To make this work, we use ngrok to serve our local environment on a custom subdomain of the production domain.

Read more about it on our ngrok guide.

  1. Connect to ngrok
  2. Put SGTM in preview mode
  3. Put GTM in preview mode (make sure the order is correct)
  4. Start debugging https://ngrok.interaction-design.org

Video Documentation

▶️ Analytics Module Overview With Mehrdad (Part 1)
Recorded on July 31, 2024 · 30 minutes

▶️ Analytics Module Overview With Mehrdad (Part 2)
Recorded on July 31, 2024 · 38 minutes

External Resources

Other Topics - Probably deprecated

Frequently Asked Questions