Moving tags to a server feels like it should put you beyond the reach of consent rules, and that assumption is exactly how teams end up non-compliant. A tagging server is bound by the same consent choices as the browser. Here is how to handle consent correctly in server-side GTM.
The core principle
Server-side tagging does not bypass consent; it relocates it. The user still chooses in the browser, and your server is obligated to honor that choice before forwarding anything to a vendor. The job is to carry the consent state from the browser to the server and then let it gate what each server tag is allowed to send.
Get consent to the server
The browser has to tell the server what the user agreed to, with every hit. In practice the consent state travels in the request payload, in headers, or in a first-party cookie, and Google's consent signals such as gcs and gcd ride along with the data. If those are missing, the server simply cannot know what the user chose, and it must then assume the most restrictive state.
Set consent defaults in the browser first
Consent handling starts client-side, where you declare defaults before any tag fires and update them when the user responds:
// Default to denied before anything fires
gtag('consent', 'default', {
ad_user_data: 'denied',
ad_personalization: 'denied',
ad_storage: 'denied',
analytics_storage: 'denied'
});
// Update once the user accepts in your banner
gtag('consent', 'update', {
ad_user_data: 'granted',
ad_personalization: 'granted',
ad_storage: 'granted',
analytics_storage: 'granted'
});
Turn consent into server variables
In the server container, map the incoming consent signals into variables, for example a variable that reads whether ad_storage is granted. Those variables are what your tags check. Without them the server has the consent data sitting in the request but no way to act on it, so building the variables is the step that makes consent enforceable rather than merely present.
Gate each tag on the right signal
Different vendors depend on different signals, so wire each tag to the one that matters:
- Google Ads and Meta tags should fire only when ad_user_data is granted, enforced for EEA and UK users since March 2024.
- Analytics tags depend on analytics_storage, and can fall back to cookieless pings when it is denied.
- Advertising personalization depends on ad_personalization being granted.
Do not forget modeling and cookieless
Honoring consent does not have to mean losing all declined users. With consent mode, denied analytics traffic can still send cookieless pings that Google uses to model the gap, so configure your analytics tags to send those rather than nothing. That keeps you compliant and preserves as much signal as the rules allow.
Test both states
Verify the setup by exercising both paths in Preview: decline consent and confirm no ad data leaves the server, then grant it and confirm the tags fire. Testing only the granted path is the classic oversight, because the compliance risk lives entirely in what happens when a user says no.
Document which signal gates which tag
Consent logic rots quietly when it lives only in one person's head, so write down the mapping: this tag fires on ad_user_data, that one on analytics_storage, this other one always. A short table of tag-to-signal, kept with your tagging documentation, means the next person to touch the container does not accidentally loosen a rule, and an audit can be answered in minutes instead of a nervous afternoon of clicking through every tag.
A server does not put you beyond consent; it just moves where you enforce it, and assuming otherwise is how compliance quietly breaks. Carry the consent state from the browser, turn it into server variables, gate each tag on the signal it needs, and lean on modeling for the declines. Do that and your server-side setup respects the user's choice as faithfully as the browser ever did, which is exactly what the rules require.
Want a stronger data analyst role or a raise? Grab the FREE Product Analyst Playbook and get the exact roadmap to your next offer.
