GTM Proxy · open source
Ad blockers dropped 30% of your analytics. The fix became another SaaS bill.
GTM Proxy is a single edge function that runs server-side Google Tag Manager on your own domain. Deployed to your Vercel account in an afternoon. No vendor, no monthly fee, no black box.
One TypeScript file · Vercel edge function · First-party by default
-'https://www.googletagmanager.com/gtm.js?id='+i+dl;+'https://yoursite.com/prxy/enc__www.g00gl3t4gm4n4g3r.c0m__enc/gt4g/j5?id='+i+dl;// that’s it. that’s the integration. Two strings. No GTM container changes.
Act 1 · Problem
The blocking isn’t a rumor
Three numbers that every analytics team has already seen in their own data.
1.77B
people use an ad blocker at least sometimes — 29.5% of internet users worldwide as of Q2 2025.
GWI, Q2 2025
32.5%
of Americans run an ad blocker. On desktop the share rises to roughly 37%.
GWI, Q2 2025
iOS 17 + Safari
Advanced Tracking and Fingerprinting Protection blocks GTM and GA outright in Private Browsing — on by default.
Apple, iOS 17 / Safari 17 (2023)
The pattern is consistent: the cleaner your audience, the worse your data.
What breaks downstream
Missing events aren’t a measurement problem. They’re a decision problem.
When a third of your pageviews never land in GA4, your conversion rate is wrong, your attribution model is wrong, and the remarketing audiences you’re pushing to Meta and Google Ads are missing the exact users who installed an ad blocker — often the ones you most want to reach again. Teams then spend real money optimizing against reports that disagree with their own order database. The usual response is to paper over it: buy a server-side tagging SaaS, wire up Google’s server-side GTM on App Engine, or quietly stop trusting the dashboard. All three are expensive in different currencies — dollars, engineering hours, or confidence — and none of them need to be the answer.
Act 2 · Product
Meet GTM Proxy
A single TypeScript file you deploy to Vercel Edge that forwards GTM, Google Analytics, and Facebook tag requests through your own domain. Every outbound request looks like a call to yoursite.com — because it is.
How it works
Ad blockers match a list of domains and URL patterns. Change both, and there’s nothing to match.
Standard GTM installs call googletagmanager.com/gtm.js
and google-analytics.com/collect
— those exact strings are in every ad blocker’s default
rule set. GTM Proxy serves the same payloads from a path on your
own domain, with the upstream domain name encoded
(enc__...__enc)
so neither the hostname nor the URL path matches anything a
blocklist is looking for. This is not a header trick or a
user-agent dodge — the request is genuinely first-party.
Two details keep analytics intact while that happens: GA cookies
get their Domain
attribute rewritten from .google-analytics.com
to your domain so sessions persist, and the client IP is injected
into GA’s _uip
parameter so geographic reports still work. Without those two
pieces, the proxy would “work” and your GA data would
quietly be wrong.
Request flow
Before
- google-analytics.com/g/collect blocked · 0 B
- googletagmanager.com/gtm.js blocked · 0 B
GA4 DebugView
— no events —
After
- yoursite.com/prxy/enc__...__enc/c0ll3ct 200 OK · 84 B
- yoursite.com/prxy/enc__...__enc/gt4g/j5 200 OK · 36 KB
GA4 DebugView
→ purchase
value: 49.00 · geo: CA-ON
Demonstration
Two lines of HTML. Ad blocker still on. Events arrive.
The request leaves as first-party, the cookie stays first-party, and GA4 sees the data it would have seen if no one had ever installed a blocker.
How it’s different
You’re already comparing three options in your head. Here they are side by side.
| Google sGTM | Stape | Dataunlocker | GTM Proxy | |
|---|---|---|---|---|
| Hosting model | Your GCP project | Their SaaS | Their SaaS | Your Vercel account |
| Typical monthly cost | $100+ (Cloud Run + egress) | $20–$200+ per site | Commercial, contract-based | $0 on Vercel’s free tier |
| Time to first event | Hours to days | ~1 hour | ~1 hour | ~20 minutes |
| Code you can read and fork | Partial (client templates) | No | No | Yes — one TypeScript file |
| Vendor lock-in | Low (GCP) | High (their dashboard) | High (their dashboard) | None |
| Ad blocker evasion | Partial | Yes | Yes | Yes |
| First-party cookie domain | Manual | Yes | Yes | Yes — automatic |
Every row in that table is a tradeoff a technical owner already knows they’re making. The three paid options all win on “someone else runs it” and lose on cost, lock-in, and how much of the stack you can actually read. GTM Proxy is the inverse: it’s yours, it’s a few hundred lines of code, and the bill is what it costs to run a Vercel edge function — which for most sites is zero. If you were going to read the source of a SaaS tool before trusting it with your analytics anyway, you may as well own it.
The whole thing is ~800 lines. We’ll walk you through it.
Act 3 · Result
What you get back
Three things change the moment GTM Proxy is live, and all three are measurable in your existing GA4 property.
Outcome 01
Recover the events ad blockers were dropping.
Teams who switch see GA4 event volume rise 20–40% within the first week with no other changes, because the proxy catches the traffic that was previously getting blocked at the browser — conversions, add-to-carts, custom events, all of it.
Outcome 02
Cancel the server-side tagging subscription, or never start one.
The proxy runs on Vercel’s free tier for almost every site under a million monthly events, which means the line item for Stape, Dataunlocker, or Cloud Run — typically $30 to $500 a month depending on volume — goes to zero.
Outcome 03
Own the instrumentation end to end.
Everything the proxy does is in one readable TypeScript file. No vendor dashboard to log into, no renewal calendar, no “we’re changing our pricing” email next quarter — just a dependency you control, in the same repo as the rest of your code.
See it run against your own site.
A 30-minute walkthrough on how the proxy works, what it would look like running on your domain, and the two-string GTM snippet change that puts it live. We’ll show you the file, the diff, and the DebugView lighting up — no slide deck.
Maintained by The Adpharm · running since 2024