Tracking Fluent Form Success and Abandonment: A Complete Guide to GTM Implementation and Audience Creation in GA4, Google Ads, and Meta

Published Categorized as Tracking

Tracking form success is essential to understand how well your forms convert, but it’s equally important to track abandonment—when users start filling out a form but leave without submitting.

By monitoring both form successes and abandonments, you can create targeted retargeting campaigns that reach users at different stages of their journey.

In this post, we’ll guide you through setting up form success and abandonment tracking using Google Tag Manager (GTM) for Fluent Forms, and how to create custom audiences based on these events in GA4, Google Ads, and Meta.

With this dual-tracking approach, you’ll be able to:

  • Retarget users who abandoned your form.
  • Engage users who successfully submitted with follow-up offers.

Here’s what we’ll cover:

  • How to track both form abandonment and form success using GTM.
  • How to create custom audiences in GA4, Google Ads, and Meta based on these events.

Let’s jump in!


Step 1: Implement Form Abandonment and Success Tracking in Google Tag Manager

First, we need to track two key events:

  • Form abandonment: When a user interacts with a form but leaves without submitting.
  • Form success: When a user submits the form successfully.

We’ll set up a Custom HTML Tag in GTM that tracks both events and pushes them to the dataLayer.

Setting Up in GTM

  1. Create a new tag in GTM:
    • Go to Tags > New in your GTM workspace.
    • Choose Custom HTML Tag.
  2. Copy and paste the script below into the tag editor:

htmlCopy code<script>
(function($) {
var formId = document.querySelector('form.frm-fluent-form').getAttribute('data-form_id');
var formFieldsFilled = {};
var isFormSubmitted = false;

// Track field interactions (but don't push individual events for each field)
$('form.frm-fluent-form').find('input, textarea, select').each(function() {
var fieldName = this.name;
$(this).on('blur', function() {
var fieldValue = $(this).val();
if (fieldVlue) {
var formattedFieldName = fieldName.replace(/[\[\]]/g, '_').toLowerCase();
formFieldsFilled[formattedFieldName] = fieldValue;
}
});
});

// Form submission success
$('form.frm-fluent-form').on('fluentform_submission_success', function() {
isFormSubmitted = true;
var formData = new FormData(this);
var inputValues = {};

formData.forEach(function(value, key) {
inputValues[key.replace(/[\[\]]/g, '_').toLowerCase()] = value;
});

window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'fluent_form_submit',
form_id: formId,
inputs: inputValues
});
});

// Form abandonment
$(window).on('beforeunload', function() {
if (!isFormSubmitted && Object.keys(formFieldsFilled).length > 0) {
var abandonedFields = Object.keys(formFieldsFilled).length ? formFieldsFilled : 'not filled';

window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'fluent_form_abandoned',
form_id: formId,
abandoned_fields: abandonedFields
});
}
});
})(jQuery);
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script><script src="/blog/bindernet/wp-content/themes/twentytwelve-child/github-files.js" type="text/javascript"></script><script>
$(
$.getGithubFileByFilePath("jamesward", "github-files", "src/main/javascript/github-files.js", function(contents) {
$(".howtoembed\\;").html(contents);
SyntaxHighlighter.all();
}));
</script>
[code language="js" classname="howtoembed"]
[/code]
<script>
(function($) {
var formId = document.querySelector('form.frm-fluent-form').getAttribute('data-form_id'); // Dynamically get form_id
var formFieldsFilled = {}; // Track fields that have been filled
var allFields = []; // Track all form fields
var isFormSubmitted = false; // Flag to check if the form is submitted
var sensitiveFieldNames = ['email', 'phone', 'mobile', 'contact', 'telephone'];
// List of system or hidden fields that should be ignored
var ignoredFields = [
'__fluent_form_embded_post_id',
'_fluentform_1_fluentformnonce',
'_wp_http_referer'
];
// Function to hash sensitive field values (SHA-256 hashing)
function hashValue(value, callback) {
crypto.subtle.digest('SHA-256', new TextEncoder().encode(value)).then(function(hashBuffer) {
var hashArray = Array.from(new Uint8Array(hashBuffer));
var hashHex = hashArray.map(function(b) {
return b.toString(16).padStart(2, '0');
}).join('');
callback(hashHex);
});
}
// Function to check if a field is sensitive based on name or value pattern
function isSensitiveField(fieldName, fieldValue) {
var lowerCaseName = fieldName.toLowerCase();
var isNameSensitive = sensitiveFieldNames.some(function(name) {
return lowerCaseName.indexOf(name) !== 1;
});
var emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // Basic email pattern
var phonePattern = /^\+?[0-9\s-]{7,15}$/; // Basic phone number pattern
return isNameSensitive || emailPattern.test(fieldValue) || phonePattern.test(fieldValue);
}
// Helper function to format field names properly (removing trailing underscores)
function formatFieldName(fieldName) {
return fieldName.replace(/[\[\]]/g, '_').replace(/_+$/, '').toLowerCase();
}
// Track all form fields and blur events to push filled field data to the dataLayer
$('form.frm-fluent-form').find('input, textarea, select').each(function() {
var fieldName = this.name;
allFields.push(fieldName); // Store all field names
$(this).on('blur', function() {
var fieldValue = $(this).val();
if (fieldValue) {
var formattedFieldName = formatFieldName(fieldName); // Format the field name properly
if (isSensitiveField(fieldName, fieldValue)) {
hashValue(fieldValue, function(hashedValue) {
formFieldsFilled[formattedFieldName] = hashedValue;
});
} else {
formFieldsFilled[formattedFieldName] = fieldValue;
}
}
});
});
// Track form submission success
$('form.frm-fluent-form').on('fluentform_submission_success', function() {
isFormSubmitted = true;
var formData = new FormData(this);
var inputValues = {};
formData.forEach(function(value, key) {
var keyFormatted = formatFieldName(key); // Format the field name properly
if (isSensitiveField(key, value)) {
hashValue(value, function(hashedValue) {
inputValues[keyFormatted] = hashedValue;
});
} else {
inputValues[keyFormatted] = value;
}
});
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'fluent_form_submit',
form_id: formId,
inputs: inputValues
});
});
// Detect form abandonment when the user attempts to leave the page
$(window).on('beforeunload', function(e) {
if (!isFormSubmitted) {
var abandonedFields = []; // Fields not filled
allFields.forEach(function(fieldName) {
var formattedFieldName = formatFieldName(fieldName);
// Only include user-facing fields and skip ignored fields
if (!formFieldsFilled[formattedFieldName] && !ignoredFields.includes(formattedFieldName)) {
abandonedFields.push(formattedFieldName); // Store only the field name
}
});
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: 'fluent_form_abandoned',
form_id: formId,
filled_fields: formFieldsFilled,
abandoned_fields: abandonedFields.join(', ') // Concatenating field names
});
// Prevent form abandonment action for a few milliseconds to allow the event to fire
var confirmationMessage = "You have unsaved changes.";
(e || window.event).returnValue = confirmationMessage; // Legacy for IE
return confirmationMessage;
}
});
})(jQuery);
</script>
  1. Set up a trigger:
    • Choose All Pages as the trigger to ensure the script runs on any page where the form is present.
  2. Save and publish your container.

Verify the Events

After you publish, test the implementation by:

  • Opening Preview Mode in GTM.
  • Interacting with the form without submitting to trigger the fluent_form_abandoned event.
  • Submitting the form to ensure the fluent_form_submit event fires.

Both events will appear in your GTM Debugger, pushed into the dataLayer.


Step 2: Creating Abandoned and Success Audiences in GA4

With the events now tracked in GA4, you can create audiences for:

  1. Form abandonment: Users who filled out some fields but didn’t submit.
  2. Form success: Users who successfully submitted the form.

Create Abandoned Audience

  1. In GA4, navigate to Admin > Audiences.
  2. Click New Audience > Create a Custom Audience.
  3. Set conditions:
    • Choose Event as the dimension.
    • Select fluent_form_abandoned as the event.
  4. Save the audience.

Create Success Audience

  1. Similarly, go to Admin > Audiences.
  2. Click New Audience and create a custom audience.
  3. Set conditions:
    • Choose Event as the dimension.
    • Select fluent_form_submit as the event.
  4. Save the audience.

You can now track both abandoned and successful submissions in GA4 reports and use these audiences for retargeting.


Step 3: Using These Audiences in Google Ads

Now that your audiences are set in GA4, you can link them to Google Ads for remarketing.

Link GA4 to Google Ads

  1. In GA4, go to Admin > Google Ads Linking.
  2. Link your GA4 property to your Google Ads account.

Import Audiences to Google Ads

  1. In Google Ads, go to Tools & Settings > Shared Library > Audience Manager.
  2. Click + and select Import from Google Analytics.
  3. Choose your Abandoned and Success audiences from GA4.

Create Remarketing Campaign

You can now create Display, Search, or YouTube remarketing campaigns in Google Ads targeting:

  • Abandoned users: Use ads to bring them back and complete their submission.
  • Successful users: Target users with follow-up offers or products.

Step 4: Creating Abandoned and Success Audiences in Meta (Facebook Ads)

Finally, you can also use these audiences for retargeting on Meta Ads Manager.

Create Custom Audiences in Meta

  1. Go to Meta Ads Manager > Audiences.
  2. Click Create Audience > Custom Audience.
  3. Choose Website as the source.
  4. Select FluentFormAbandoned or FluentFormSubmit events as the triggers.
  5. Refine the audience with additional parameters (e.g., time on site).

Create Retargeting Ads

Once your custom audiences are populated, you can create retargeting ads to:

  • Re-engage abandoned users with ads to bring them back to your form.
  • Follow up on successful submissions with additional offers or content.

Conclusion

Tracking both form abandonment and success gives you powerful insights into user behavior and allows for more effective retargeting. With these GTM implementations, you can build abandoned and successful audiences in GA4, Google Ads, and Meta, helping you create targeted campaigns that drive conversions.

Form tracking is a critical part of optimizing your sales funnel. Make sure to test, analyze, and iterate to make the most out of your data. Happy tracking!

Leave a comment

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.