GA4 sees the click even when the ad blocker doesn't.
Browser gtag plus server-side Measurement Protocol mirror, deduplicated by event_id. Restaurant analytics that survives the ad-blocker apocalypse.
- Every platform tap fires both browser gtag and Measurement Protocol server-side.
- Same event_id + same client_id across both — GA4 reports one event per click.
- Ad-blocker resilient. Our customers see 20-35% more events than pure-browser GA4 setups.
Your GA4 reports lie because ad blockers strip the gtag call.
Roughly 30-40% of US web traffic now runs an ad blocker — uBlock Origin, AdGuard, Brave Shields, the default Pi-hole on someone\'s home network. All of them block google-analytics.com and googletagmanager.com requests.
The practical consequence: your GA4 platform_click count is systematically 20-40% lower than your actual click count. The diners who order most reliably — the savvy, repeat-customer, privacy-conscious ones — are also the ones most likely to block analytics. Your "best customer" cohort is silently absent from every GA4 funnel report you build.
The fix is Measurement Protocol, Google\'s server-to-server analytics ingestion endpoint. Events shipped from a server origin (not from the diner\'s browser) bypass ad blockers entirely. DineRoute mirrors every browser gtag call with a Measurement Protocol POST from our Cloudflare Worker, deduplicates on the way in, and lands a clean single event in your GA4 property.
The result: GA4 reports that actually match your real platform click volume, and audience definitions (Add to Audience → "people who tapped DoorDash in the last 30 days") that aren\'t silently missing your highest-value diners.
Browser + server fire together, GA4 sees one event.
Same architectural pattern as Meta CAPI — browser fires, server mirrors, deduplicated.
Browser gtag fires immediately
On every platform tap, gtag('event', 'platform_click', { ... }) ships from the diner's browser with the standard GA4 client_id, session_id, and ga_session_number.
Server Measurement Protocol mirror
A simultaneous POST to https://www.google-analytics.com/mp/collect ships the same event with the same client_id from our Cloudflare Worker. Bypasses ad blockers entirely.
GA4 dedupes by event_id
Both events carry the same event_id parameter. GA4 dedupes to one event in the same session, but counts the server one if the browser side is blocked.
POST https://www.google-analytics.com/mp/collect
?measurement_id=G-XXXXXXXXXX
&api_secret=YOUR_API_SECRET
{
"client_id": "1234567890.1717545600",
"events": [{
"name": "platform_click",
"params": {
"event_id": "c2c7e62a-9a4b-4f5a-b6f1-2b7e3a9a8c2d",
"platform": "doordash",
"location_slug": "southlake",
"brand_name": "Malai Kitchen",
"engagement_time_msec": 280,
"session_id": "1717545600",
"page_location": "https://malai.dineroute.com/southlake"
}
}]
} Up 34%. Same ad spend. The orders were always there.
Five steps to a complete GA4 setup.
The whole flow happens once during onboarding.
Get your Measurement ID
GA4 → Admin → Property → Data Streams → Web. Copy the G-XXXXXXXXXX Measurement ID and paste it into DineRoute settings.
Generate a Measurement Protocol API secret
In the same Data Stream settings, expand Measurement Protocol API secrets and create one. Store it in DineRoute (encrypted, never logged).
Map your custom event name
We default to platform_click. If your existing GA4 dashboards use a different event taxonomy (e.g. select_promotion), map to that instead. Keep it consistent across the property.
Add custom dimensions if you want them
In GA4 → Admin → Custom definitions, add custom dimensions for platform, location_slug, and brand_name. We send all three as event parameters by default.
Watch DebugView
Open GA4 → Configure → DebugView, hit your live link with ?_dbg=1, watch the platform_click event tick in within ~5 seconds. Confirm both engagement_time_msec and your platform parameter appear.
Build an audience
In GA4 → Configure → Audiences, build "People who clicked DoorDash in the last 30 days" — filter by event = platform_click and parameter platform = doordash. Push to Google Ads or Meta for remarketing.
The two real ways to ship Measurement Protocol events.
GTM Server-Side is the standard answer if you have an analytics engineer on staff. DineRoute is the standard answer if you do not.
| Capability | DineRoute | GTM Server-Side container |
|---|---|---|
| Browser gtag installed | Auto on every platform tap | Manual in GTM or hardcoded |
| Measurement Protocol server-side mirror | Built-in | GTM Server-Side container |
| Cost | Included | $150-300/mo for GTM SS |
| Ad blocker resilience | ~95% of events captured | ~65-75% browser-only |
| event_id dedup logic | Built-in | You build it |
| Restaurant-specific custom dimensions | Pre-mapped (platform, location) | Manually configured |
Six questions analytics leads actually ask.
Why do I need server-side GA4 if I already have gtag installed?
Ad blockers strip the browser gtag call. uBlock Origin, Brave Shields, Pi-hole — all of them block analytics.google.com requests. Server-side Measurement Protocol fires from our worker origin, which is not on the blocklist. Restaurant marketers typically recover 20-35% of platform_click events that were silently disappearing.
What is GA4 Measurement Protocol?
Measurement Protocol is Google's server-to-server analytics ingestion endpoint. You POST a JSON payload with your client_id, event name, and parameters directly to https://www.google-analytics.com/mp/collect, and it lands in your GA4 property identically to a browser event. We use it for every platform click.
How does GA4 dedupe browser + server events?
GA4 itself does not have explicit dedup like Meta CAPI. We handle dedup on our side by suppressing the server-side event if the browser event posts back a success ping within 800ms. If the browser is blocked, the server event lands; if not, only the browser event counts. Net result: one event per click in GA4 reports.
Can I use this with GTM's server-side container?
You do not need to. GTM Server-Side ($150-300/mo + setup) is one way to fire Measurement Protocol events; DineRoute is another. We do the same job for $29-$49/mo, scoped to your restaurant smart-link flow. If you already have GTM SS for the rest of your site, fine — DineRoute still complements it without conflicts.
What custom dimensions should I add for restaurant analytics?
At minimum: platform (doordash, ubereats, grubhub, chownow), location_slug (southlake, uptown, etc.), and brand_name. If you run multi-brand from one GA4 property, add brand_name as a User-scoped dimension. These three unlock per-platform, per-location, per-brand funnel reporting.
How is this different from Google Ads Enhanced Conversions?
GA4 and Google Ads are separate products. GA4 is for analytics — funnel reporting, audience definitions, attribution modeling. Google Ads conversions are for bidding optimization. We feed both. See the Google Ads tracking deep dive for the conversion side.
Stop losing 30%+ of your platform clicks to ad blockers.
Paste your G- Measurement ID and Measurement Protocol API secret. The events land in DebugView within seconds.
No credit card. 14-day trial. Cancel any time.