Marketing & analytics Available
Google Tag Manager
Tag Manager is where an agency's promise to a client, we measure your quote requests, is actually kept. This integration brings that container within reach: read what is live, stage what needs to change, and publish only once somebody holding that permission has looked at it.
What you need
- The Google Workspace integration switched on, with a Google account that has access to the client's Tag Manager
- The Tag Manager API enabled in the same Google Cloud project as the rest of the Google integration
- A licence covering the Tag Manager module
- The google_tag_manager.settings.manage permission to link a container
How to connect it
- 1 Switch Tag Manager on under Instellingen → Integraties (Settings → Integrations). It needs the Google Workspace integration and pulls it in for you; the screen says so before you save.
- 2 Go to Instellingen → Tag Manager and press Google koppelen (Connect Google). This asks for four extra scopes that are deliberately kept out of the ordinary marketing connection: read, edit a workspace, freeze a version and publish. Somebody who only wanted a traffic chart should not be asked whether they may publish to a client's website.
- 3 Link the container per client, under Instellingen → Tag Manager or from the Marketing panel on the client page, under Tag Manager. Paste the website's GTM tag id (
GTM-XXXXXXX) or search by name among the containers your Google account can reach. Attach the client and, if you like, the website. - 4 Choose the name schakl. works under. By default the container gets a workspace of its own, named after your agency. A Tag Manager workspace is not a private branch but a shared draft: write into the default one and your half-finished work sits in front of the client's own marketeer, whose next Publish ships it.
- 5 Read the container. You get the live version, the tags, triggers and variables, the version history, and the snippet that belongs on the website.
- 6 Under Samenvatting en doel (Summary and goal) on the container page, write in your own words what this container does for the client and what the tracking should prove, for example "measure quote requests". The next person to open the container then does not have to work out from the tag list what it is for.
- 7 Record a conversion. Pick a GA4 event or a Google Ads conversion, say what it fires on (page view, form submission, link or element click, element visibility, or a custom event) and give it the name the client uses. schakl. never invents a measurement id or a conversion id: you supply them, because a wrong one sends your client's conversions to somebody else's property and nothing on any screen would say so.
- 8 Publish when it is right. Freezing a version rides the write permission; going live needs google_tag_manager.version.publish, which is exactly the split you want to hand out separately.
A draft and a broadcast are not the same act
Editing a workspace changes a draft: it is real, it is recorded, and nobody is served it. Publishing changes what runs in every visitor's browser, immediately, with no review step behind it. Those are two acts with completely different audiences, so they are two permissions. With one combined write permission the sentence "let the assistant prepare the tracking for the new campaign and I will look it over" is impossible to express; with this split it is an API key holding tag.write and nothing else. Creating a version deliberately rides the first: a version is the act of writing down what was staged, and gating it behind the publish permission would leave the staging half unable to finish its own work.
- google_tag_manager.settings.manage: link and unlink containers, and the kill switch
- google_tag_manager.container.read: containers, tags, triggers, variables, versions and the snippet
- google_tag_manager.tag.write: edit the workspace and freeze it into a version
- google_tag_manager.version.publish: make a version live on the client's website
A recipe for what you do over and over, and the raw path for the rest
A tag is a type plus a list of parameters, and which parameter names are legal depends on the tag template. There are hundreds of templates and the API does not say. Composing that from first principles goes wrong sometimes, and the unpleasant half of "wrong" is silent: a tag firing into nothing looks exactly like a tag that works. So two tag kinds and six trigger kinds are written out, precisely the ones an agency sets up over and over. Everything else goes through Tag Manager's own type and parameter array, judged by Google's own validator: a hand-written body that is wrong fails loudly, where a half-modelled recipe would deploy quietly.
- Tags: GA4 event and Google Ads conversion (with the conversion linker always on, since without it the tag reports conversions it cannot attribute to a click)
- Triggers: page view, form submission, link click, element click, element visibility and custom event, each narrowable on part of the URL
- Anything else: Tag Manager's own type and parameter array, judged by Google
What Google does not record, we do
Google records that a trigger and a tag exist. It records nowhere that together they are this client's "quote requested", that an agency promised to keep it working, or that it was set up from here rather than by hand. Without that row, the next person to look has to read the container and guess. So schakl. stores per conversion both what was asked for and what was last observed, in separate fields: a conversion whose tag somebody deleted in Tag Manager is then a state you can see, rather than a row that quietly keeps claiming to work. Of the container itself only what a panel needs is mirrored; the tag list and version history are fetched live, because half the edits to them are made by people who do not work for you. What an agency itself knows about the container goes into the summary and the goal: two separate text fields on the container page, which are tracked in the activity log and which only an admin holding the link permission can change.
The nightly count this exists for
Every night at 05:35 each container's mirror is refreshed: the name, the live version, the counts off it, and how many changes are staged and unpublished. That last number is why the job exists. A change staged weeks ago and never published is the commonest way a client's tracking quietly stops being what they were told it is, and nothing else surfaces it: nobody opens a container they have no reason to open. If one container fails, that failure stays on its own row and the other nineteen refresh as normal.
A search box, because a list of everything does not fit the quota
Tag Manager counts its limit per user per minute, and listing every account costs one request per account. At an agency with dozens of accounts, a picker that fetched everything therefore failed exactly on first use. So the picker is a search box: the account list is always read, the containers only for the accounts matching your search, with a fixed ceiling. A pasted GTM tag id is one request. What was not opened is named ("8 of 44"), because a short list that looks complete reads as "we are not in that account". The same search box sits in the settings, in the connect dialog and on the client page.
On the client page: a connection, not a card
A container has no daily numbers, so it is not a marketing source with tiles. It sits in the Marketing panel's picker as a connection beside the sources, and is attached through Tag Manager's own route, with no second row in the marketing module that could disagree with it. The separate Tag Manager card on the client page is gone. The one figure only that card showed, the number of changes staged and not published, now sits on the container's row in the Marketing panel, for whoever may read the container.
Permissions
Grant these to the role that manages this integration (Settings → Roles). Admin-only by default, and never to the client role.
-
google_tag_manager.settings.manageLink and unlink containers, verify a link and operate the kill switch. Admin only by default. -
google_tag_manager.container.readRead containers, workspaces, tags, triggers, variables, versions, the snippet and the recorded conversions. Admin and member by default. -
google_tag_manager.tag.writeEdit the workspace and freeze it into a version. Changes a draft that is served to nobody. -
google_tag_manager.version.publishMake a version live on the client's website. Deliberately its own permission.
What it deliberately does not do
- None of the four permissions ever goes to the Client role. The read alone covers every tag in the container, which includes conversion values, remarketing ids and whatever the previous agency left behind.
- Unlinking touches nothing at Google. An agency that stops working for a client does not thereby delete the tracking off their website.
- schakl. invents no values. A measurement id, a conversion id and a CSS selector all come from you; there is no step that "finds the GA4 property for you".
- Deleting containers, managing users and managing accounts are not included, and those scopes are not asked for on the consent screen either.
- If somebody edited the container in Tag Manager while you had it open, your save is refused rather than overwriting their change. Opening it again resolves it.
Where to find it Instellingen → Tag Manager (Settings → Tag Manager) to link containers, and the Marketing → Tag Manager menu item for the containers themselves. On a client page you attach it from the Marketing panel, where it sits as a connection beside the sources with the number of live tags and unpublished changes.
Read the guide