Enabling cross-domain tracking for GA4

Cross-domain tracking works differently for GA4, in comparison to Google's Universal Analytics (now deprecated).

For most scenarios, enabling GA4 cross-domain tracking is easier to configure now, as GA4 will automatically decorate hyperlinks on your website to pass over cross-domain tracking information.

However, for javascript-based redirects like the ones utilized by ConvertFlow for conversion elements such as buttons, forms, quizzes, etc, GA4 takes a step backward compared to Universal Analytics, now requiring manual setup of the gtag implementation code of the destination website, to retrieve the client_id and session_id from URL parameters.

Here's how to set this up:

1. Register your domains in your web data streams

In GA4, head to your web data stream. Then click through to Configure tag settings > Configure your domains.

Here you can add all the domains you want to enable cross-domain tracking for. This means hyperlinks from your website to one of these domains, will be decorated with cross-domain tracking info, allowing the linked website's GA4 property to persist the tracking.

2. Enable cross-domain tracking in ConvertFlow

To have ConvertFlow's javascript-based redirects from buttons, form submissions, quiz outcomes, etc, tracked cross-domain in GA4, head to Settings > Integrations > Google Analytics in your ConvertFlow website.

Then, enter your GA4 property's web stream measurement ID and toggle on cross-domain redirect URL decoration.

ConvertFlow will now start passing over clientId and sessionID parameter values to your conversion elements' redirect destination URLs.

3. Update your destination website's gtag code to support cross-domain tracking

Last, for any website you're linking to cross-domain from ConvertFlow, you'll need to update that site's gtag code implementation to catch the clientId and sessionID values from the URL.

Here's some sample code of how to do this (remember to replace both instances of  G-MEASUREMENT_ID):

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-MEASUREMENT_ID"></script>
  function getURLParameter(name) {
    const params = new URLSearchParams(window.location.search);
    return params.get(name) || undefined;

  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  var configOptions = {};
  var clientId = getURLParameter('clientId');
  var sessionId = getURLParameter('sessionId');

  if (clientId) configOptions['client_id'] = clientId;
  if (sessionId) configOptions['session_id'] = sessionId;

  gtag('config', 'G-MEASUREMENT_ID', configOptions);

This gtag implementation checks for the presence of the URL parameters clientID and sessionId, and if they exist, initializes gtag with the configuration options client_id and session_id populated. These are needed for any GA4 properties configured through this gtag implementation, to know the GA tracking session of the originating website.

Note that ConvertFlow gtag implementation on our hosted landing pages handles this on your behalf, so any cross-domain linking between ConvertFlow landing pages should persist GA4 tracking, assuming each GA4 property has cross-domain tracking properly configured.