Set up server-side tagging with Google Tag Manager
In this hands-on tutorial, we’ll look at how to set up your own server-side container in Google Tag Manager (GTM) to unlock the full potential of server-side tagging.
Server-side tagging allows you to move tracking and marketing tags from your web client to a server. This offers numerous benefits, such as improved privacy policies, faster page load times, and the ability to consolidate multiple tools and services. With Google Tag Manager as a powerful tool, you can easily build and manage this server-side infrastructure.
In this article, I’ll focus on the practical implementation and walk you through the process step-by-step. You’ll learn how to set up your own server container and deploy a server to the Google Cloud. We will also implement the first two clients and tags: the GTM Web Container Proxy and the tag for GA4.
The basics of server-side containers
In the server container, the already known entities tags, triggers and variables work a bit differently than you know from the classic client-side tagging. In addition, there are now also clients that accept data as an endpoint. As well as transformations, with which you can change parameters in the data stream.
Clients & Tags
Clients are a new type of entity in GTM and play a central role in server-side tagging. They are responsible for processing incoming requests. When a request is received, the client checks whether it is responsible based on predefined conditions. If so, the request is converted into an event model. This model contains information such as the name of the event and associated parameters. Then, the client runs a virtual container in which tags send requests and hits to the tools based on the information from that event model.
Transformations
As the name suggests, transformations allow you to change, add or truncate (in short: transform) the data that passes through the server-side container. This gives you even more control over the data flow. Especially if you use prefabricated templates for clients and tags and thus cannot see or influence their functionality. This creates a virtual clone of the event model described above, which is then modified. You can also specify whether transformations should only apply to certain clients or tags.
Trigger
In the server-side container, there are no triggers such as “click” or “page view” in the traditional sense. Instead, tags are executed based on the matching event or client. When a particular hit or client is identified, the corresponding tags are instructed to execute. This is done in the context of the virtual container.
Variables
In the server-side container, there are also variables, but unlike the website-specific circumstances, they now reflect the work of servers. These variables mainly relate to requests, events, queries and similar aspects. They enable the dynamic processing of information within the server-side container.
By understanding these basics of the Server-side Container, you’ll be ready to dive deeper into the setup. In the next sections, we’ll get into the practice of setting up the server container step-by-step, deploying a server to the Google Cloud, and implementing the first tags and clients.
Set up the server container
First, we need to create a new server-side container. To do this, we log into Google Tag Manager and navigate to our account. There we click on “Create new container” and select the option “Server”. Then we enter a name and description for the container.
Once you’ve created the container, you should get a prompt to automatically deploy the server to the Google Cloud. I don’t advise you to use this automatism. Why? We’ll discuss that next.
How to deploy a server in Google Cloud?
By choosing the manual way, we have the possibilities to make a few important settings that we would not have any influence on in the automatic process. This is essentially the region of your server, which should be deliberately chosen for privacy reasons alone.
To set up the corresponding services, you need to have a Google Cloud account and then create a project.
Once the region is set in your project for any service, you cannot change it afterwards!
Configure App Engine service
Next follow the steps below to configure the server aka the App Engine service:
- Click “App Engine” in the Google Cloud Console menu while in your GCP project.
- The setup screen will open where you can select the region for the server. Choose the region that is closest to your market. For example, if your offer and website are aimed at the German market, then Europe West 3 (Frankfurt) is probably the right region for you.
After the App Engine has been set up for the first time, open the Cloud Shell by clicking the Cloud Shell button in the blue bar at the top right. Make sure you are in the correct project by running the gcloud config set project <PROJECT_ID>
command. The project ID is usually displayed in yellow on the command line.
Run the following command in the cloud shell:
bash -c "$(curl -fsSL https://googletagmanager.com/static/serverjs/setup.sh)"
It is pointed out that the current configuration is overwritten. That’s fine, since this was mainly about the server location, which we had to set once. In the next step, you need to enter the container configuration that is displayed when you click on the GTM ID in the server container and select “Manually provision server”. Leave the “Policy Script URL” empty and enter “testing” as “Deployment Type”. Confirm the entries and the setup script will set up your server.
Linking with the Server Container
After the setup process completes successfully, enter the following command in the cloud shell:
gcloud app browse
Copy the displayed URL and enter it in the GTM container under “Admin” > “Container Settings” in the “Server container URLs” field. Save the settings. If you start the container preview mode and it successfully opens in a new window, the process is complete. In the next step we will replace the current cryptic server URL with a custom domain.
Assign a custom domain
By default, Google Cloud servers run under the appspot.com domain, which means that they are considered third party pages seen from your website’s domain. To avoid this and make sure that the hits are considered first party, you should create a subdomain for them. So find a suitable subdomain and talk to your IT about it. In most cases this subdomain has to be created first.
Then open the dashboard of your Google Cloud project and navigate to “App Engine” > “Settings” > “Custom Domains”. Click on “Create new custom domain” and enter the agreed subdomain.
You will be redirected to Google Search Console, where you need to confirm the subdomain ownership. Follow the instructions to complete the verification. This may involve adding a TXT record or uploading an HTML file to your website or DNS records. If you can’t do it yourself, again ask your IT for help. After successful verification, the subdomain will point to the tagging server.
Don’t forget to customize the new custom domain in the GTM Server container under “Admin” > “Container Settings” in the “Server Container URL” field (see previous step). This will ensure that the connection between the server and the container works properly.
Your first client: GTM Web Container Proxy
To switch completely to server-side, you can load the GTM Web Container from the server. To do this, you need to create a client from the pre-build template in the GTM Server Container. In the configuration of the client you have to define which container IDs are allowed to be loaded to make sure that the server is not misused for other web containers.
Next, you need to customize the GTM snippet on your page to query the web container from the server. Usually these scripts look like this:
<!-- Google Tag Manager -->
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':</p>
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-123456');</script>
<!-- End Google Tag Manager -->
At the marked position the GTM container (or the gtm.js library) is loaded directly from the Google domain. You now need to replace this domain with the one for your server. For example, this could look like this:
<!-- Google Tag Manager -->
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':</p>
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://gtm.julianpolley.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-123456');</script>
<!-- End Google Tag Manager -->
Now the web container is requested via your server. Note that the domain must also be replaced in the <noscript> part in the <body>.
Your first tag: GA4 server-side setup
Let’s set up GA4 server-side next. This actually requires two things. First, we need to be able to receive the data stream from the end device in the first place. Therefore, we need to set up a GA4 client first, before we pass the data to a GA4 tag afterwards.
The GA4 hit format has become a common data stream format for other tools, such as Google Ads and the Facebook Conversion API. Therefore, it makes sense to set up basic GA4 tracking in the web container to receive it via your GA4 client on the server and then distribute it to many different tools.
Let’s set up the GA4 client for the single data stream. For this you can use the predefined client template for GA4. Specify the GA4 measurement IDs in the tag’s settings so that the corresponding client libraries can also be loaded via the server.
Then you need to set up a GA4 tag. There are usually no further configurations needed here, except that you can remove the IP addresses of the users from the hits. I would recommend this for privacy reasons. To fire the tag, you then need a trigger that fires based on the GA4 client.
Redirect the client-side setup
To take full advantage of server-side tagging, it is recommended to switch completely to the server-side container. Otherwise, the classic tagging in your web container will continue to communicate directly with Google. To change this, you need to tell your tags in the web container to send their hits to your server instead of directly to Google (or other tools).
This is also true if you decide to test the setups in parallel and set this up. In this case, you will need to create two setups in the Web Container, just as you would need to create two GA4 properties.
Also, since the goal is to send only one stream of data to the server instead of having separate streams for each tool (which would hurt performance), we will modify the GA4 configuration tag.
For GA4 the redirection is very simple. Here you have to specify the new server domain in the “Send to server container” field in the configuration tag (e.g. https:gtm.julianpolley.com). This will redirect a normal measurement log request (https://www.google-analytics.com/collect?v=2&[…]) to your server endpoint (e.g.: https://gtm.julianpolley.com/collect?v=2&[…]).
That’s it for a foundational setup. Let’s take a look at how you can test the whole thing now.
Debugging
After you set up the server-side container, you can also use the preview mode to perform debugging. The structure of the preview mode is similar to that of the Web Container, but has some differences because the functionality of the server-side container is different. In addition to the familiar tabs for tags and variables, there are now also “Requests” and “Event Data” tabs. Instead of a list of events on the left side, requests are shown here.
Each hit sent to your server is logged here as a request. Individual requests can also contain events, similar to the web preview mode (e.g. pageviews).
For example, on the screenshot you can see the request for the Web Container (1), followed by the request for the gtag library for GA4 Web Integration (2) and a PageView request to the Measurement Protocol (3). Ideally each of these requests is received by a client that can handle them. The clients for the first two requests return the requested libraries. The last request is received by the configured GA4 client and converted into the unified event format.
If the necessary conditions are met, a tag is triggered that uses the data in the uniform event format to prepare and send it for the corresponding tool. If you want to display the data in the event format, you can find it in the “Event Data” tab of the corresponding request.
The variables can be found in the named tab as usual, although they are less interesting in the server-side container, since most data is processed within the event data model.
Under the “Tags” tab you will find the tags that have been triggered for the current request. For example, there might be a GA4 tag and a Facebook tag that can be triggered for an incoming GA4 request.
Finally, the Requests tab provides various information. You can take a closer look at the received request, including the client that received it. You can also see which requests went out, i.e. which requests were sent to the different tools by the tags.
Go live with the production server
After you have thoroughly tested your server-side tagging and are ready to deploy it, you can switch your server with a simple console command. Please note that there will be money charged from this point on.
For this, we will use the App Engine Flexible model. This means that our server can dynamically add resources when the load is high, and in turn use fewer resources when there is little going on.
It is recommended to set up a setup with at least 2-3 instances (or servers) to ensure that your setup is never underpowered. Each instance can process about 100 requests (i.e. hits) per second. The exact number of requests you receive may vary depending on the number of tags set up, their functions and the expected traffic.
We repeat the same commands as described in deployment of the testing server, but set a different configuration. So first open the Cloud Shell in your Google Cloud project:
- When you open the Cloud Shell for the first time (in a while), it will initialize, which may take a moment. Then the console will open at the bottom of the window.
- First check if you are in the right project. The project ID is displayed with a yellow background. If not, you have to enter the following command with your project ID:
gcloud config set project <PROJECT_ID>
- A new input line appears. Is the project ID correct now? If yes, execute the following code:
bash -c "$(curl -fsSL https://googletagmanager.com/static/serverjs/setup.sh)".
This command starts a script (the same as the first setup) that guides you through the configuration process. Here you still have to make some settings.
Most of the settings you can simply accept by pressing the Enter key. However, there are some settings that you should adjust:
- Deployment Type: production (since you are now switching to a production configuration)
- Minimum Number of Servers: 2-3 (this is the recommended number of instances that will always be running and it will not fall below. However, you can adjust it if necessary).
- Maximum Number of Servers: 6 (instances can be scaled up to this number)
The number of instances you set depends very much on the size of your tracking setup and the traffic that lands on your website. Just carefully approach the correct configuration (you can always change it later). Keep in mind that each instance costs additional money.
That’s it! Now you just have to confirm with “y” and “Enter”, and then the script will do everything automatically. The process can take a while (about 10-15 minutes), so make yourself a coffee in the meantime. Now everything is set up. Afterwards, it’s best to check directly if all data is coming in normally.
Congratulations on your first successful server-side tagging setup with Google Tag Manager!
If you still have questions or need support, feel free to contact me.