Ad blockers work by maintaining lists of known tracking domains — google-analytics.com, googletagmanager.com, connect.facebook.net. When a user’s browser loads your page, the blocker checks outgoing network requests against these lists and blocks any that match.
Google Tag Gateway is Google’s answer to this problem. It routes your Google tag requests through a path on your own domain instead of directly to Google’s infrastructure. Since your domain isn’t on any blocklist, the requests pass through.
This guide explains what it does, how to set it up, how it compares to server-side GTM, and whether it’s worth implementing for your site.
What Exactly Is a Google Tag Gateway?
A Google Tag Gateway proxies two types of requests through your domain:
-
The
gtag.jsor GTM loader script — instead of loading fromhttps://www.googletagmanager.com/gtag/js, it loads fromhttps://yourdomain.com/gtag/js(or a similar path you configure) -
Measurement data requests — instead of sending event data to
https://www.google-analytics.com/g/collect, events are sent tohttps://yourdomain.com/g/collect
Your server (or CDN edge function) then forwards these requests to Google’s actual infrastructure. From the browser’s perspective, everything is happening on your domain. From Google’s perspective, nothing changes.
Official reference: Google Tag Gateway documentation
How It Differs from Server-Side GTM
This is the most common point of confusion:
| Google Tag Gateway | Server-Side GTM | |
|---|---|---|
| What it proxies | gtag.js loader + GA4 measurement requests | All tag vendor requests |
| Setup complexity | Low (edge function or web server config) | High (Cloud Run, custom domain, tag migration) |
| Cost | Minimal (CDN edge function costs) | $5–50/month (Cloud Run) |
| Vendors supported | Google only | Google, Meta, TikTok, Snapchat, etc. |
| Business logic | None | Full (Functions, data enrichment) |
| Ad blocker bypass | Yes (for Google tags) | Yes (for all proxied tags) |
| Data ownership | Limited | Full server-side control |
Tag Gateway is simpler and cheaper, but Google-only. If you only care about Google Analytics and Google Ads surviving ad blockers, Tag Gateway achieves that at a fraction of the cost and complexity of full server-side GTM.
Who Should Use a Google Tag Gateway?
✅ Good fit if:
- Your primary concern is GA4 data loss from ad blockers
- You only use Google Analytics and Google Ads (no Meta, TikTok, Snapchat)
- You want a lightweight solution without Cloud Run setup
- Your tech team can configure a reverse proxy or edge function
❌ Not the right choice if:
- You need to proxy Meta Pixel, TikTok Pixel, or other non-Google vendors (use server-side GTM instead)
- You need data transformation or enrichment at the server level
- You want to implement Consent Mode at the server level
- You need full event visibility and control on your own infrastructure
Setup Method 1: Using Cloudflare Workers (Recommended for Most Sites)
Cloudflare Workers run at the network edge, add minimal latency, and are free for most usage levels. This is the simplest and most scalable approach.
Step 1: Create the Worker Script
In Cloudflare Dashboard → Workers & Pages → Create Application → Create Worker
Name it google-tag-gateway and replace the default script with:
// Cloudflare Worker: Google Tag Gateway
// Proxies gtag.js and GA4 measurement requests through your domain
const GOOGLE_TAG_DOMAIN = 'www.googletagmanager.com';
const GA4_DOMAIN = 'www.google-analytics.com';
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const path = url.pathname;
let targetHost;
let targetPath = path;
// Route gtag.js / GTM loader requests
if (path.startsWith('/gtag/js') || path.startsWith('/gtm.js')) {
targetHost = GOOGLE_TAG_DOMAIN;
}
// Route GA4 measurement protocol requests
else if (path.startsWith('/g/collect') || path.startsWith('/collect')) {
targetHost = GA4_DOMAIN;
}
else {
return new Response('Not Found', { status: 404 });
}
// Build the proxied URL
const targetUrl = new URL(`https://${targetHost}${targetPath}${url.search}`);
// Forward the request
const proxyRequest = new Request(targetUrl, {
method: request.method,
headers: request.headers,
body: request.method !== 'GET' ? request.body : null,
});
// Add the real client IP
const clientIP = request.headers.get('CF-Connecting-IP');
if (clientIP) {
proxyRequest.headers.set('X-Forwarded-For', clientIP);
}
const response = await fetch(proxyRequest);
// Return response with CORS headers if needed
const newResponse = new Response(response.body, response);
newResponse.headers.set('Cache-Control', 'public, max-age=3600');
return newResponse;
}
};
Step 2: Add a Route
In Cloudflare → Workers & Pages → your Worker → Settings → Triggers → Add Route:
- Route:
yourdomain.com/gtag/* - Zone: your domain
Also add: yourdomain.com/g/*
Step 3: Update Your GTM or gtag.js Snippet
Replace the standard GTM snippet on your site:
<!-- Standard GTM snippet (loads from googletagmanager.com) -->
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXX');</script>
<!-- Becomes: -->
<script>
(function(w,d,s,l,i){
// Replace the GTM load URL with your proxied path
w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0];
var j=d.createElement(s);
var dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
// Changed: use your domain instead of googletagmanager.com
j.src='https://yourdomain.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXX');
</script>
Then in GTM → Admin → Container Settings → set Tagging Server URL to https://yourdomain.com.
This makes GA4 events send measurement requests to yourdomain.com/g/collect instead of google-analytics.com/g/collect.
Setup Method 2: Using nginx (Self-Hosted)
If you manage your own server and use nginx, add a location block to your site config:
# Google Tag Gateway — nginx configuration
# Proxy gtag.js loader
location /gtag/ {
proxy_pass https://www.googletagmanager.com/gtag/;
proxy_ssl_server_name on;
proxy_set_header Host www.googletagmanager.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_valid 200 1h;
add_header Cache-Control "public, max-age=3600";
}
# Proxy GA4 measurement requests
location /g/collect {
proxy_pass https://www.google-analytics.com/g/collect;
proxy_ssl_server_name on;
proxy_set_header Host www.google-analytics.com;
proxy_set_header X-Real-IP $remote_addr;
# No caching for measurement data
proxy_cache_bypass 1;
}
# Proxy GTM container
location /gtm.js {
proxy_pass https://www.googletagmanager.com/gtm.js;
proxy_ssl_server_name on;
proxy_set_header Host www.googletagmanager.com;
proxy_cache_valid 200 10m;
}
Reload nginx: sudo nginx -s reload
Setup Method 3: Using Apache (.htaccess)
For shared hosting with Apache mod_proxy enabled:
# Enable proxy modules
SSLProxyEngine On
ProxyRequests Off
# Proxy gtag.js
ProxyPass /gtag/ https://www.googletagmanager.com/gtag/
ProxyPassReverse /gtag/ https://www.googletagmanager.com/gtag/
# Proxy GA4 measurement
ProxyPass /g/collect https://www.google-analytics.com/g/collect
ProxyPassReverse /g/collect https://www.google-analytics.com/g/collect
Note: Most shared hosting providers (including IONOS) disable
mod_proxyfor security reasons. Check with your host before relying on this approach. For IONOS shared hosting, the Cloudflare Worker approach is the most practical alternative.
Verifying Your Tag Gateway Works
Check 1: Script Source in DevTools
Open Chrome DevTools → Sources tab. Your gtag.js or gtm.js script should now show your domain as the source (yourdomain.com/gtag/js) rather than www.googletagmanager.com.
Check 2: Network Requests
DevTools → Network → filter by your domain. You should see:
yourdomain.com/gtm.js?id=GTM-XXXXX(or/gtag/js?id=G-XXXXXXXX)yourdomain.com/g/collect?...(GA4 measurement requests)
And you should not see direct requests to www.google-analytics.com.
Check 3: Test with Ad Blocker Enabled
Install uBlock Origin → enable it → visit your site → check DevTools Network.
Without a gateway, you’d see google-analytics.com requests blocked (shown in red or filtered out). With the gateway, your domain’s requests should pass through.
Then check GA4 DebugView — events should still appear even with the ad blocker active.
Check 4: GA4 Data Volume
After running your gateway for 7–14 days, compare your session and event counts to the equivalent period before. You should see a measurable increase (typically 10–25% for general e-commerce audiences, more for B2B and tech audiences).
Performance Impact
A common concern is whether proxying adds latency. In practice:
- Cloudflare Workers add 1–5ms of additional latency — imperceptible to users
- Self-hosted nginx adds latency based on your server’s proximity to users — can be 10–50ms if server is geographically distant from users
- The gtag.js script itself loads faster from your CDN-cached domain than from Google’s servers in some geographic locations
For most sites, the Cloudflare Worker approach is neutral or slightly beneficial on performance compared to loading from Google’s domain.
Tag Gateway vs. Server-Side GTM: Which to Choose?
Choose Google Tag Gateway if:
- You only use Google Analytics and Google Ads
- You want minimal setup and cost
- You don’t need vendor diversification on the server side
Choose Server-Side GTM if:
- You run Meta Pixel, TikTok Ads, Snapchat alongside Google
- You need server-level data transformation
- You want full audit logs of what data leaves your infrastructure
- You’re processing EU data and need fine-grained control
Use both if:
- You need server-side GTM for multi-vendor control but also want to route the gtag.js loader through your domain for maximum script availability
At Aumlytics, we help clients choose and implement the right combination of Tag Gateway and server-side solutions based on their vendor mix, compliance requirements, and budget. Book a free consultation to discuss your setup.