Manually set location in GA4

Hello,

I am working on setting up GA4 for a website that has compliance/privacy requirements so we cannot send the users actual IP address. What we would like to do is to use Stape’s GEO Headers powerup to get the Country/Region data and manually set that when sending events to GA4.

I do see that the GA4 Measurement Protocol supports this with the user_location attribute, but I can’t figure out how to set it with a Transformation in Tag Manager.

We are currently using the official GA4 tag, but are not opposed to using Stape’s GA4 Advanced tag if that can provide a solution. I feel like we could also fork Stape’s tag to add this functionality, but I would like to avoid that if at all possible.

Hi @pthurston

The native GA4 tag does not support the “user_location” parameter.
It is only available for the Measurement Protocol.

In your case, the simplest solution would be to use “X-GEO-Ipaddress” (Geo Headers power up) and set a value for the ip_override parameter.
GA4 can then use the ip_override parameter to automatically determine the rest of the geo parameters.

Thank you for the clarification. Is there any documentation on what X-GEO-Ipaddress represents? Ie is it the original users IP address? Or is it a random IP that matches their GEO location? GEO Headers power-up | Stape Doesn’t seem to make that clear

X-GEO-Ipaddress is the visitor’s actual IP, resolved via MaxMind GeoLite2 on the server side. So mapping it into ip_override gives Google the real address for geo lookup, which fixes location reporting but doesn’t satisfy a no-real-IP requirement.

The GA4 Measurement Protocol now supports user_location with country_id and region_id fields that need no IP at all. You can map Stape’s X-GEO-Country and X-GEO-Region headers into those fields on the GA4 Advanced tag, keep Redact visitor IP enabled, and get geo without transmitting the address.

Thank you, I have tried this approach but it did not work. My understanding after reviewing the source code of Stape’s Advancted tag is that it is not using the Measurement Protocol (which would call the ‘/mp/collect’ API) but instead uses the same API endpoint used for client side tracking (‘/g/collect’)

You’re right. I looked at the tag source after your reply and confirmed it sends to /g/collect. user_location is Measurement Protocol-only, so it isn’t supported by that endpoint.

The path that works without ip_override is calling /mp/collect directly via an HTTP Request tag. You’d POST to https://www.google-analytics.com/mp/collect?measurement_id=G-XXX&api_secret=YYY with user_location as a top-level body object containing country_id and region_id mapped from Stape’s GEO Headers.

Watch out for session handling though. /mp/collect doesn’t generate session_start or first_visit automatically, and events without a matching ga_session_id show up as isolated hits. If you’re running a parallel client-side GA4 tag, extract the session ID from the _ga_XXXX cookie and include it as an event parameter in every MP call. Also include engagement_time_msec if you expect the events to appear properly in Realtime.