Send the Client ID and UTM Parameters to Your CRM with Form Submission

Published · Tags: GTM, Google Analytics, CRM, Salesforce, Client ID, UTM Parameters, Form Submission, Window Loaded Trigger

Salesforce describes connecting lead data to Google Analytics in general terms in "Google Analytics Audience Activation," and Google adds more specifics in its support article "Configure the Google Analytics Salesforce Sales Cloud integration." Neither addresses UTM campaign parameters, and neither addresses what happens when the form isn't the site's landing page. Connecting a Salesforce lead back to the incoming web campaign — down to the specific digital placement — is pivotal to knowing whether your advertising spend is actually working. This applies equally to lead generation through any CRM, not just Salesforce.

Part One: UTMs Already Solved

The first piece of this puzzle is passing UTM campaign parameters from the site's landing page to a contact or lead form that might be several pages further down the visitor's session journey. That problem is already solved in an earlier post, "Pass UTM URL Query Marketing Parameters to Contact / Lead Form." Read that piece first — what follows assumes the UTM values are already available to the form.

Part Two: Getting the Anonymous Client ID Into the Form

The next piece is getting the anonymous browser client ID into the form, and from there into the CRM. So what exactly is an anonymous browser client ID? In GA4, it's the value GA4 stores in the _ga first-party cookie — a random number paired with a timestamp. It's unique to the site visited, isn't shared across sites, and expires according to that cookie's own expiration rules. It does not identify an actual person in any way.

A note on the original technique: the original version of this post read the client ID with ga.getAll()[0].get('clientId') — the Universal Analytics tracker object's getAll() method. Universal Analytics has since been fully sunset by Google, and that API no longer exists on a GA4-only property. The corrected, GA4-appropriate approach below reads the client ID straight out of the _ga cookie instead, using a GTM 1st-Party Cookie variable rather than a tracker object call.

Reading the GA4 Client ID From the _ga Cookie

Create a GTM 1st-Party Cookie variable named, for example, {{Anonymous Browser Client ID Cookie}}, configured to read the _ga cookie. The full _ga value looks something like GA1.1.1234567890.1700000000; only the last two dot-delimited segments are technically the client ID, but there's no harm in passing the entire string through to the CRM if you'd rather not parse it apart.

For the property identifier, GA4 doesn't have a single "tracking ID" the way Universal Analytics did — instead, create a GTM Constant or Custom JavaScript variable, for example {{GA4 Measurement Stream ID}}, holding the Measurement ID for the relevant GA4 data stream (formatted like G-XXXXXXX).

With those two variables in place, the field-population script collapses to a single Custom HTML tag with no tracker object dependency at all:

<script>
document.querySelector('input[data-sc-field-name="lead_id"]').value = {{Anonymous Browser Client ID Cookie}};
document.querySelector('input[data-sc-field-name="property_id"]').value = {{GA4 Measurement Stream ID}};
</script>

The genuinely tricky part of this whole recipe isn't the JavaScript — it's knowing how your own web developers identified these fields on the form. What attribute or selector will actually match your hidden fields? That detail is implementation-specific and worth confirming with whoever built the form before you wire this tag up.

A Trigger Gotcha: Confirm the Cookie Is Already Set

The original Universal Analytics version of this recipe called out a Window Loaded trigger requirement, because the ga.getAll() tracker object wasn't guaranteed to be populated on a Pageview or DOM Ready trigger. With GA4, the situation is different: the _ga cookie is typically set as soon as the GA4 configuration tag fires, which usually happens well before Window Loaded.

That said, the safest practice is still to trigger this field-population tag after the GA4 configuration tag has actually fired and the _ga cookie has been written — either by sequencing this tag to fire after the GA4 tag (using tag sequencing in GTM), or by triggering on the visibility of the form itself, which by the time it appears has almost always outlasted the GA4 initialization. Avoid relying on a bare Pageview trigger fired before any tags have had a chance to run.

That's It

With UTMs already solved by the earlier post and the client ID now landing in the form via a Window Loaded trigger, you have everything needed to evaluate the success of your marketing campaigns based on the actual quality of the leads your CRM reports back — not just on click or impression volume.

For another solid treatment of this same general topic, see "Salesforce Sales Cloud Data into Google Analytics 360" by Bounteous. It predates this post by several years, and was only discovered afterward.


This post is a Blogger rewrite of an earlier piece originally published on Weebly.

Comments

Popular posts from this blog

Site Landing & Site Referrer Preservation

GTM Browser Viewport Measurement

UTM & URL Query String 2 Cookies