Google Tag Manager Server-Side — How To Manage Custom Vendor Tags

Nicolas Hinternesch
Level Up Coding
Published in
8 min readSep 17, 2020

--

The analytics community agrees: The launch of Google Tag Manager Server-Side is a significant milestone for the industry. Not only does it underline the paradigm shift towards server-side technology for analytics, it also has the potential to completely overthrow how organizations approach data collection and building their data model.

This article is not an introduction to the concept of server-side tag management and its terminology. Simo Ahava and Julius Fedorovicius have brilliantly covered this in great detail. This tutorial builds on these rundowns by walking you through a bare-bones example of how to configure GTM server-side for custom vendors that are not part of the Googleverse.

Google Tag Manager Server-Side Header Image

As the product is currently still in its early stages, its functionality and the available documentation is heavily focused on the Google environment. The built-in clients, tags, and variables solely focus on the implementation of Google Analytics via the server side container. While this is very beneficial for setting up your GA measurements, the overarching goal of deploying server-side tag management should be for organizations to collectively manage multiple different tags on the server to significantly reduce client load.

Therefore, I will take you through an example workflow that illustrates how the different components of a GTM server-side setup work together, when the goal is to collect, prepare, and dispatch data for a custom vendor, such as Adobe Analytics, AT Internet, Snowplow, or Facebook.

Google Tag Manager Server-Side Workflow

How It Works

For this example, I want to manage a measurement request for AT Internet. A certain hit structure is required for the data to be processed correctly. It consists of a collection domain, a path, and multiple tracking parameters in a query string:

https://collectionDomain.com/hit.xiti?param1=value1&param2=value2...

Instead of sending this hit directly from the browser to the AT Internet servers, I want to use GTM server-side to collect the data, parse it into an event model, and use that event data to dispatch the measurement to AT Internet from the server.

1 - Sending the data to your GTM server-side container

The tracking data for most measurement tools is picked up via JavaScript in the client-browser and sent to a vendor collection server. While each vendor requires a specific raw hit structure here (such as Google’s Measurement Protocol), a well designed GTM server-side setup ideally lets you collect all the data needed for different vendor endpoints in one generic tracking request to your server container. This tracking request can be generated by any kind of JavaScript. For the hit below (generated by the AT Internet Smartttag library), note that the default collection domain needs to be replaced with the domain of your GTM container:

https://gtm-abcde12-a1aaa.uc.r.appspot.com/hit.xiti?s=123456&idclient=12345678&col=2&ts=1600256597557&vtag=5.22.0&ptag=js&r=1368x912x24x24&re=675x770&hl=12x43x17&lng=en-GB&events=[{"name":"page.display","data":{"page":"Nicolas Hinternesch - Music","adblock":"active"}}]

2 - Building a custom client template

For incoming GA requests, there are built-in clients available. However, they will not work for requests that are structured differently — like the one above. Therefore, we have to build our own client template that is able to handle the request you are planning to manage:

Google Tag Manager Server-Side Screenshot

In order to execute most code in the client- and tag-templates, you will need to make use of the server-side tagging APIs provided by Google. You will also have to grant the relevant permissions in the template editor.

For our simple workflow, the client has to dome some basic tasks:

Claiming the request
Specify to which requests you want this client to respond and claim the matching requests (line 17).

Storing the data in an event model
One of the main tasks of the client is to store incoming data in a structured event model. Consequently, various tags can then leverage this unified event data to populate their outgoing tracking requests.
While there are built-in APIs to automatically structure incoming GA hits and parse the data to the event model, this has to be done with custom code when you are working with other vendors’ endpoints. This can be done by storing the incoming data from the query string in an event object (line 23).
Additionally, we can retrieve header values from incoming requests (line 13) and add them to the event object as well (line 37). The same goes for the IP address, which can be obtained via the getRemoteAddress API (line 15). By passing these on in the event data, we can use them later on to override the request headers of our outgoing requests.

Running the container
The last steps for the client are to return a response for the incoming request, run the GTM container, and pass over the event object, so the tags can use that data (line 42).

You can monitor the event data that the client stored in the preview mode:

3 - Building a custom tag template

From now on, the regular GTM logic kicks in again. We can create triggers and tags to to manage our measurement calls. In this case, I want my tag to be triggered every time, my custom client has handled a request:

Google Tag Manager Server-Side Screenshot

Again, there is a built-in tag template for GA. For other vendors, we have to write a custom one:

Google Tag Manager Server-Side Screenshot

The custom tag template has to perform the following tasks:

Get the desired collection domain from the user
This is the domain to which the data should be sent. It can be gathered in an input field from the user during tag creation:

Google Tag Manager Server-Side Screenshot

Build the tracking request
In order to put together the request URL (line 11), we need to retrieve the collection domain (line 8) as well as the data from the event object (line 9). While this is enough for a basic request, we can also add a few crucial headers to the outgoing request (line 24). These header values were picked up and stored by the client. This is how information like referrers or user agents is handled and forwarded to the custom vendor. In addition, you can override the IP address of the outgoing request to match the actual user’s IP address from the incoming request. Note that it depends on the custom vendor, if and how they accept overriding IP addresses. Common techniques include the x-forwarded-for header (line 27) or a URL parameter. But this is down to the vendor. If we do not override values like IP or UA, the outgoing requests default to sending the values of the server container. Please also note that managing the IP address is considered PII. Some vendors tend to truncate the IP by default, but be sure to keep an eye on privacy compliance.
Note that the URL built does not have to be for an AT Internet hit. Instead of patching together a URL according to the ATI hit crafting standard, we can also refer to the Adobe Analytics implementation guide or any other vendor documentation to use the same event data and build a hit URL abiding by a different request pattern.

Send a GET request to the vendor endpoint
As the final step, we can make a GET request to the URL, in order to eventually pass the data on to the custom vendor endpoint (line 29). Be sure to include the headers (line 31).

This will do it. For each event, the outgoing requests sent by the tag can be reviewed in the preview mode:

Google Tag Manager Server-Side Screenshot

Please note that this is just a bare-bones implementation. A functioning production setup would include other key aspects, such as server-side cookie handling with a (preferably) custom domain. But this tutorial should give you a fairly good understanding of the general process and components involved when configuring custom vendor measurement via server-side GTM.

Closing Thoughts On GTM Server-Side

In conclusion, it is important to emphasize the difference between server-side tracking and server-side tag management. I frequently hear these terms used interchangeably. But it is important to understand the difference when considering various options for server-side implementations:

Server-side tracking is based on sending tracking hits directly from the server that serves the web content. That way, the entire data collection process never passes through any client-side technology. Of course, the data availability here is heavily limited.

Server-side tag management, however, offers a great solution to centrally manage and dispatch collected data across all your different vendor endpoints with the least amount of client load possible. The data is still being collected client-side. But instead of having the client dispatch 100 different hits to 100 different services, the browser can potentially send the data in one single request to a custom domain while the distribution to all endpoints is being handled on the server.

What I personally love most about this redesigned process is the fact that it pushes organizations towards smart data collection and a unified data model.

They are forced

  • … to think about which information actually needs to be included in the tracking requests to meet the demands of different measurement vendors
  • … to create a vendor-agnostic approach of structuring this data at an event-level to make it usable for all endpoints. This will prove very beneficial in terms of data governance.

— If you have questions about this process, found a bug in the code, or if you’re simply up for talking analytics: Feel free to reach out.

UPDATE

I have written a bit more extensively about Step 2: Building a custom client template. You can find the new article here and the corresponding GTM server-side client template on Github.

--

--