Skip to content
  • There are no suggestions because the search field is empty.

How to Integrate Convert.com Experiences with HubSpot Forms

Guide to help integrate Convert.com experience data to HubSpot forms

IN THIS ARTICLE YOU WILL:

This guide will show you how to append Convert.com experience data to HubSpot forms as hidden fields, allowing you to track which experiences and variations your form submissions were exposed to.

Prerequisites

  • Active Convert.com account with experiences running
  • HubSpot account with forms set up
  • Access to modify your website's JavaScript
  • HubSpot hidden fields created for the experience and variation data
  • For HubSpot’s newer form renderer, access to the HubSpot Forms V4 global object on the page

Implementation Steps

1. Create Hidden Fields in HubSpot Form

First, create two hidden fields in your HubSpot form:

  • convert_experience_names
  • convert_variation_names

📒 Note:

In HubSpot’s newer form renderer, field names may be prefixed, for example 0-1/convert_experience_names and 0-1/convert_variation_names. The integration code below accounts for both prefixed and unprefixed field names.

2. Add the Integration Code

Add the following JavaScript code to your website where the HubSpot form is present or add it to the variation JS section of an independent Deploy experience targeted to the form page

<!-- Start of Convert.com A/B Test Form Tracking Code -->
<script>
(function() {
    'use strict';

    var DEBUG = false;

    function log(message, data) {
        if (!DEBUG) return;

        if (data !== undefined) {
            console.log('[Convert→HubSpot] ' + message, data);
        } else {
            console.log('[Convert→HubSpot] ' + message);
        }
    }

    function getConvertData() {
        if (!window.convert || !window.convert.currentData || !window.convert.currentData.experiences) {
            log('Convert data not available yet');
            return null;
        }

        var experiences = window.convert.currentData.experiences;
        var experienceIds = [];
        var variationNames = [];

        Object.keys(experiences).forEach(function(experienceId) {
            var experience = experiences[experienceId];

            if (experience.variation) {
                experienceIds.push(experienceId);
                variationNames.push(experience.variation.name);
            }
        });

        if (!experienceIds.length) {
            log('No active experiences with variations found');
            return null;
        }

        return {
            experienceIds: experienceIds,
            variationNames: variationNames
        };
    }

    function findFieldName(formInstance, fieldName) {
        if (!formInstance || typeof formInstance.getFormFieldValues !== 'function') {
            return Promise.resolve(fieldName);
        }

        return formInstance.getFormFieldValues().then(function(fields) {
            var match = fields.find(function(field) {
                return field.name === fieldName || field.name.indexOf('/' + fieldName) > -1;
            });

            return match ? match.name : fieldName;
        }).catch(function() {
            return fieldName;
        });
    }

    function populateHubSpotFormV4(formInstance, source) {
        var data = getConvertData();

        if (!data || !formInstance || typeof formInstance.setFieldValue !== 'function') {
            return;
        }

        Promise.all([
            findFieldName(formInstance, 'convert_experience_names'),
            findFieldName(formInstance, 'convert_variation_names')
        ]).then(function(fieldNames) {
            var experienceFieldName = fieldNames[0];
            var variationFieldName = fieldNames[1];

            formInstance.setFieldValue(experienceFieldName, data.experienceIds);
            formInstance.setFieldValue(variationFieldName, data.variationNames);

            log('Set HubSpot Forms V4 fields from ' + source, {
                experienceFieldName: experienceFieldName,
                variationFieldName: variationFieldName,
                experienceIds: data.experienceIds,
                variationNames: data.variationNames
            });
        });
    }

    function populateAllHubSpotFormsV4(source) {
        if (!window.HubSpotFormsV4 || typeof window.HubSpotFormsV4.getForms !== 'function') {
            log('HubSpotFormsV4 not available');
            return;
        }

        var forms = window.HubSpotFormsV4.getForms();

        forms.forEach(function(formInstance) {
            populateHubSpotFormV4(formInstance, source);
        });
    }

    function populateLegacyHubSpotForms(source) {
        var data = getConvertData();

        if (!data) {
            return;
        }

        var forms = document.querySelectorAll('form.hs-form');

        forms.forEach(function(form) {
            var experienceField = form.querySelector('input[name="convert_experience_names"]');
            var variationField = form.querySelector('input[name="convert_variation_names"]');

            if (experienceField && variationField) {
                experienceField.value = data.experienceIds.join(',');
                variationField.value = data.variationNames.join(',');

                log('Set legacy HubSpot form fields from ' + source);
            }
        });
    }

    window._conv_q = window._conv_q || [];

    window._conv_q.push([function() {
        populateAllHubSpotFormsV4('initial-check');
        populateLegacyHubSpotForms('initial-check');

        window.addEventListener('hs-form-event:on-ready', function(event) {
            if (window.HubSpotFormsV4 && typeof window.HubSpotFormsV4.getFormFromEvent === 'function') {
                populateHubSpotFormV4(
                    window.HubSpotFormsV4.getFormFromEvent(event),
                    'hs-form-event:on-ready'
                );
            }
        });

        window.addEventListener('hs-form-event:on-interaction:navigate', function(event) {
            if (window.HubSpotFormsV4 && typeof window.HubSpotFormsV4.getFormFromEvent === 'function') {
                populateHubSpotFormV4(
                    window.HubSpotFormsV4.getFormFromEvent(event),
                    'hs-form-event:on-interaction:navigate'
                );
            }
        });

        window.addEventListener('message', function(event) {
            if (
                event.data &&
                event.data.type === 'hsFormCallback' &&
                event.data.eventName === 'onFormReady'
            ) {
                populateLegacyHubSpotForms('legacy-onFormReady');
            }
        });
    }]);
})();
</script>
<!-- End of Convert.com A/B Test Form Tracking Code -->

3. How It Works

  1. The code uses Convert.com's queue system (_conv_q) to ensure all experience data is loaded before execution.
  2. For newer HubSpot forms, it listens for HubSpot’s hs-form-event:on-ready event and uses window.HubSpotFormsV4.getFormFromEvent(event) to access the form instance.

    For multi-step HubSpot forms, it also listens for hs-form-event:on-interaction:navigate so hidden fields can be repopulated when the visitor moves between steps.

  3. When triggered, it:
    • Accesses theconvert.currentData.experiencesobject to get active experiences
    • Creates arrays to store multiple experience IDs and variation names
    • Finds the HubSpot field names, including newer prefixed names such as 0-1/convert_experience_names
    • Uses HubSpot’s Forms V4 setFieldValue() method for newer HubSpot forms
    • Passes values as arrays for newer HubSpot hidden fields
    • Keeps a legacy fallback for older HubSpot forms that still use form.hs-form and unprefixed field names

4. Accessing Experience Data

The code uses Convert.com's updated JavaScript object structure:

convert.currentData.experiences[experienceId] = {
    firstTime: true,
    variation: {
        id: "1000244142",
        name: "Original Page",
        key: "1000244142-original-page",
        status: "running",
        changes: [
            {
                name: "Original Page"
            }
        ]
    }
}

5. Testing the Integration

To verify the integration:

  1. Open your website with both Convert.com experiences and HubSpot form
  2. Open browser developer tools
  3. Submit the form
  4. Check HubSpot submission data to confirm the Convert experience IDs and variation names are being captured in the hidden fields
  5. For newer HubSpot forms, verify that the submitted hidden field values are present even when the visible DOM input value does not appear to change manually

Best Practices

  • Add error handling for cases when Convert.com data isn't available
  • Consider adding timestamp data to track when the experiences were active
  • Do not hardcode a HubSpot portal ID unless your implementation specifically requires it
  • Avoid relying only on direct DOM writes such as input.value for newer HubSpot forms, because React-rendered forms may overwrite those values
  • Keep DEBUG set to false in production
  • Use the optional legacy fallback only when you still need to support older HubSpot forms

Troubleshooting

If experience data isn't appearing in form submissions:

  • Verify Convert.com experiences are running
  • Check browser console for JavaScript errors
  • Confirm hidden fields are properly created in HubSpot
  • Confirm whether the form is using HubSpot’s newer Forms V4 renderer
  • Confirm the hidden field names in HubSpot, including possible prefixes such as 0-1/
  • Confirm window.HubSpotFormsV4 is available on the page for newer HubSpot forms
  • Confirm the hs-form-event:on-ready event fires when the form loads
  • For multi-step forms, test each step and confirm the hidden fields are still populated before final submission
  • If the form is an older HubSpot form, confirm it still uses form.hs-form and the legacy hsFormCallback events