Last update: October 18, 2021. The preview now works with the container for which a proxy was created even if the container ID is exceeded..
Although server-side tagging already has a great built-in client for connecting a Google Tag Manager container across your first-party domain, it’s not ideal.
The main issues are that it doesn’t allow you to specify access on a per-origin basis, so requests for allowed container ids can be sent from anywhere, and it doesn’t give you the freedom to choose the path through which the container id is loaded.
To address these issues, I am happy to reveal that I wrote a file New customer model for server containers, named GTME Loader.
The main features of this model are:
- Freely choose the order path to which the customer responds. You can keep the default
/gtm.js, or you can look for something more creative, like
- Always load a container with a certain ID, regardless of what (if any) in a file
- Only allow requests from specific origins.
Read on for more information!
Simmer . Newsletter
Subscribe to the Simmer newsletter to get the latest news and content from Simo Ahava right in your inbox!
Get the form
Since the Community Template Gallery does not distribute client templates yet, you will need to import the template file manually.
First, get the raw
template.tpl File from GitHub repo by following this link and saving the page as a file
template.tpl in your computer.
Then, in a file server container, go to templates and click new in the Customer Templates box.
In the full list In the upper-right corner of the screen, choose import.
Locate a file
template.tpl file from your container, wait for the editor to update with the GTM Loader form, then click Memorizes to save the form.
Create a new client
Head over to Client in your container, and click new To create a new client.
From the list of available clients, choose GTME Loader Client.
You should now be ready to customize the new client!
Here is what the client looks like with all available fields displayed:
Set this to a path (including the leading slash). You can also keep the default setting
/gtm.js if you want to.
The customer will listen to requests for this track, and if perfect match The order is placed, the customer will claim the order and work its wonders.
For example, if you set the path to
/google_tag_manager.js As in the screenshot above, then order https: //
Remember that perfect match! The request must be with a path that exactly matches the setting you have configured in this client.
Container ID override
Importance! If you override the container id, preview The containers will be loaded, but the browser must make an additional request for
www.googletagmanager.com. So if your site has a content security policy,
https://www.googletagmanager.commus is still added to it for preview mode to work properly.
If you select this setting, you can then add a valid Google Tag Manager container ID to the respective field.
This setting means that Regardless of what is in
?id= Labs, a container will be returned with the configured ID.
When you select this setting, you can actually drop a file
?id= parameter from the request exactly, as the container with the configured identifier will be loaded in all cases.
In this field you can add a comma separated list of origins Only requests will be honored.
For example, if you add
https://www.teamsimmer.com,https://www.simoahava.com to field, only requests from these two origins will be able to fetch the container.
Remember that the origin is the schema (
:// Plus the hostname plus the port. So basically it all comes down to the order path.
You can also add files
* In this field, and in this case, the client will prompt the order regardless of its source.
If you need to render the asset manually (for example, when working with an embedded resource or when testing), you can add
&origin=<origin> to the request URL. For example, to load the container even when I’m not running
https://www.simoahava.com And I set that in the Allowed assets field, I can browse to this:
How it works
The client created with the template listens for requests that are sent to the request path specified in the client settings.
Check the validity of the request
Upon receiving a request like this, the customer performs two checks:
- Do Container ID override The setting is checked and a valid GTM container ID is configured, or is there a valid GTM container ID as a value for
idQuery parameter in request?
- is the value of Allowed assets wildcard (
*) or does the request come from an origin allowed or does it have an origin allowed as a value of
originQuery parameter in request?
// If the incoming request matches the request configured in the Client if (requestPath === data.requestPath) // If the request is for a valid GTM container ID if (!containerId.match('^GTM-.+$')) return; // If the request comes from a valid origin if (!validateOrigin()) return; ...
If they both decide
true, the request claimed.
Bring the preview container
If the request for preview container, which means it contains a file
gtm_preview Query parameters, the client acts as a transparent proxy.
It simply redirects the request to the GTM servers with all headers and parameters intact, and returns the result to the source of the request.
const fetchPreviewContainer = () => sendHttpGet( httpEndpoint + '&id=' + containerId + '>m_auth=' + gtm_auth + '>m_debug=' + gtm_debug + '>m_preview=' + gtm_preview, (statusCode, headers, body) => sendResponse(body, headers, statusCode); , timeout: 1500 ); ;
Most importantly, when the preview container is fetched, the result Not cached. This is vital to make the preview useful, otherwise the user will need to wait for the cache to expire before the updated preview container becomes available.
Bring live container
When He lives The container is fetched, on the other hand, the process changes a bit.
The form is used
templateDataStorage, which is an API designed to persist information via requests in a server container.
When a request comes to the live container, the client checks to see if there is already a cached copy of the library And If the resource is cached less than 7.5 minutes ago. In this case, the cached library (and any cached headers) are returned to the source of the request.
In this way the customer saves resources by Not having to fetch the resource from Google servers anymore.
Why 7.5 minutes cache duration? good this Half subordinate Browser cache time For the GTM library itself (15 min). This way, the browser cache still has the final say on how long the resource is cached, but unlike the browser cache, All users Take advantage of server-side cache even if the user has not downloaded the resource before.
If the resource is not cached or if the cache has expired, the container will be fetched from Google servers.
const fetchLiveContainer = () => templateDataStorage.getItemCopy(storedTimeout) < storageTimeout) sendHttpGet( httpEndpoint + '&id=' + containerId, (statusCode, headers, body) => if (statusCode === 200) templateDataStorage.setItemCopy(storedJs, body); templateDataStorage.setItemCopy(storedHeaders, headers); templateDataStorage.setItemCopy(storedTimeout, now); sendResponse(body, headers, statusCode); , timeout: 1500 ); // Otherwise, pull the item from cache and do not make a request to Google servers else sendResponse( templateDataStorage.getItemCopy(storedJs), templateDataStorage.getItemCopy(storedHeaders), 200 ); ;
templateDataStorage It acts as an additional layer of caching here, reducing server response time and network exit costs.
Why create a form like this when the built in web container client works just fine?
Pessimists could say that this is an improved way to get around ad blockers. And they would be right! This is amazing Do They make it easy to circumvent ad blockers, as their inferential purpose is not only
googletagmanager.com domain but also
gtm.js file and
GTM-... container identifier.
However, I designed the template to give more flexibility to move the Google Tag Manager into a first-party context. The ability to optimize request paths and query parameters seems like an obvious improvement. The
templateDataStorage The setup adds an extra layer of cost optimization.
But there’s also the twist that ad blockers targeting Google Tag Manager may be causing the child to be flushed with the bathwater. GTM itself is not a tracking tool, and many use it for purposes unrelated to tracking or data collection.
Having said that, if I were to design an ad blocker today, I would probably ban the GTM as well, because the shower water would likely be so dirty that it would have to be disposed of regardless of the collateral damage it causes.
So it’s a difficult balance. The only things I can recommend are:
- You have to handle server-side tagging with The best intentions are in the heart.
- Do your best to to improve instead of eroding Transparency.
- He is honest and respectful to your site visitors.
- Make sure that these mechanisms Documented Somewhere so that if someone audits the data flows on the site and server, your tags won’t get in the way of this important work.
This way we will all have a good time with server-side tagging.