The inner workings of GA4 Web conversion tracking



owntag Founder

published June 16, 2020

If you’re looking for a straight-forward manual on how to track an event in GA4 as a conversion – watch Benjamin’s video, it’s pretty easy.

This article is about what’s happening behind the scenes of GA4’s conversion tracking, because I had to spend hours trying to fix an extremely weird bug. That would have been way easier, had I known earlier how conversions in GA4 actually work.

Note that the following only applies to data collected through Web Data Stream and gtag.js.

Conversion identification happens in the frontend

When you mark an event as a conversion in Google Analytics 4, that setting is saved in the client library that is loaded by the browser, gtag.js.
The content of the gtag.js file is altered depending on the settings in your GA4 property.

Whenever an event is registered, the client library checks whether or not its a conversion event. If that’s the case, it appends a _c=1 parameter to the request. This parameter _c=1 identifies the event as a conversion for GA4. It happens client-side and at least not entirely inside the black box that is Google Analytics.

Predefined conversion events such as purchase however will always be interpreted as conversions, whether their requests have a _c=1 parameter or not.

Why this matters

This means that whenever you send events to GA4, you’ll have to use specifically your customized gtag.js file that contains the list of events that you want to mark as conversions.

My bug

You could totally use any gtag.js to send data if you have a way to replace the measurement ID on the way, for example in a Server Side GTM Container. That was exactly the bug I implemented: I wanted to obfuscate my property’s real measurement ID, because… why not?
So I configured my Client-side GTM to load

In my Server Side Container I then made sure to ignore the placeholder measurement ID and send data to the real one, let’s say G-KXXLLDGJCE.

The problem: All my events would be tracked in GA4 without issue, but they wouldn’t be counted as conversions in any of the reports! Even in DebugView, they wouldn’t be marked with the green flag icon.

That was because the gtag.js my users had in their browser (the one specific to GA-1234567890) did not contain any of the event names I had marked as conversions in my GA4 property.

What not to do with your gtag.js

Don’t do anything that would come in the way of you updating your gtag.js and the updates landing in the user’s browser:

  1. Don’t make a static copy of your gtag.js. Everytime you change your conversion events, you’d have to update your copy.
  2. Don’t cache your gtag.js for a long time
  3. Use the gtag.js that is customized to your Data Stream and GA4 property. You can still obfuscate your measurement ID, but you’ll want to find a workaround to make sure your users get the right script file.

How to test this yourself

You can find your conversion events in your gtag.js file. This will be especially easy to find with Ctrl + F if you use one that doesn’t have a standard name. Like this:

After a while (Google says up to 24 hours) you’ll find it here:


Become a Server Side Tagging Pro with owntag

Take control of your digital data collection with Server Side Tagging and Server Side GTM – easily hosted with owntag.

App screenshot