Google Analytics 4
Browser gtag as the primary channel, optional server-side Measurement Protocol.
For GA4, PixelFox injects the gtag snippet (unless your site already loads one) and
fires mapped e-commerce events - view_item, add_to_cart, begin_checkout,
purchase, search, generate_lead, sign_up - from the browser.
Credentials
| Field | Where to find it |
|---|---|
| Measurement ID | GA4 Admin → Data streams → your web stream → the G-XXXXXXX id top-right. (screenshot placeholder) |
| API secret | Same data stream → Measurement Protocol API secrets → Create → copy the secret value. (screenshot placeholder) |
Event routing
Unlike Meta and TikTok, GA4's Measurement Protocol has no event deduplication - a browser event and a server event for the same purchase count twice. So exactly one side fires the funnel, chosen by the destination's Event routing:
| Mode | Browser gtag | Measurement Protocol |
|---|---|---|
| Auto (default) / Browser | loaded by the tag, fires every mapped event | only server-only events, and only with Send server-only events on |
| Server | not loaded for GA4 | every conversion |
A connected GTM container always forces browser routing - its GA4 tags cannot be told to stand down. Server routing needs an API secret.
Server-only events are the ones that never had a browser counterpart: purchases sent
by the WooCommerce, Laravel and Python helpers, and COD deliveries. PixelFox recognises
them by the absence of the browser tag's viewport fields (or an explicit $action_source
other than website), so a browser event is never sent twice even with the toggle on.
What the server sends
Measurement Protocol events carry what GA4 needs to attribute and report them like a browser hit:
client_idfrom the visitor's_gacookie ($ga_client_id), or a stable synthetic id derived from the device id when the cookie is absentsession_idfrom the_ga_<stream>cookie ($ga_session_id), so the event joins the browser session instead of (not set); server-only events get a 30-minute bucketuser_idwhen identity stitching has resolved the visitorvalue,currency,transaction_id(always present onpurchase),shipping,tax,couponitems[]withitem_id,item_name,price,quantity,item_category,item_brand,item_variant- from the event's line items, or the single productsearch_termonsearch,page_location,page_title,page_referrer
Pageviews are never sent server-side; the browser tag owns them.
Validate before you trust it
The production endpoint answers 204 to anything that parses as JSON - it validates
nothing. To check a payload, prefix the API secret with DEBUG_ (e.g.
DEBUG_abc123DEF456). PixelFox then posts to Google's validation endpoint and surfaces
every validationMessages entry on the destination card's delivery state. Nothing is
recorded in GA4 while the prefix is in place; remove it to go live.
Verify
GA4 → Admin → DebugView shows browser events live. Server-side events show in
Realtime after a server-only purchase, attributed to the same session as the browser
hits when the visitor's _ga_<stream> cookie was present.