Published at

How to A/B Test Gravity Forms

How I A/B test Gravity Forms without breaking anything

Authors
  • avatar
    Name
    AJ Dichmann
    Twitter
  • VP of Digital Strategy at Globe Runner
Table of Contents

If you’ve been wanting to A/B test different Gravity Forms on your WordPress site but don’t want to deal with clunky third-party tools or risk slowing things down, this method might be exactly what you need.

We’re going to walk through a simple way to test A/B multiple forms using a custom shortcode. It’s fast, lightweight, and everything runs on the server, so you avoid all the flickering and loading issues that can come with other CRO tools.

Why Test Different Gravity Forms?

You probably already know the value of A/B testing, but here’s a quick refresher.

Testing your forms can help you:

  • Increase leads and conversions
  • Try out different headlines, layouts, or incentives
  • Understand what works best for your audience
  • Test different form types (1 step vs 2 step)

Even small changes, like updating the button text or tweaking your call to action, can have a measurable impact. But if you’re not testing, you’re just guessing.

Why Most A/B Tools Aren’t Great for Forms

Most A/B testing tools like Google Optimize, Optimizely, or VWO work by using JavaScript to change content after the page loads.

That creates a few problems:

  • Visitors often see the original version flash briefly before it switches
  • Extra scripts can slow down the page and delay your form from loading
  • Some users block tracking scripts, so your data might not be reliable
  • Complex forms with conditional logic or AJAX steps often break when the DOM is changed on the fly

These tools just weren’t built with Gravity Forms in mind.

A Simpler Way That Actually Works

Instead of using JavaScript to swap out forms after the page loads, we’re going to use a PHP shortcode that picks which form to show before the page is even sent to the browser.

Here’s how it works:

  1. When a visitor lands on your page, a cookie assigns them to a random form version
  2. That version is served directly from the server
  3. The same version will show again when they return, for up to 30 days

No flicker. No scripts. Just a consistent, smooth experience for your visitors.

The Code You’ll Need

Add this function to your functions.php file or your site’s custom plugin:

/**
 * Shortcode: [gf_ab_test formid="1|5"]
 * - Splits "1|5|9" into an array of form-IDs.
 * - Pre-renders each Gravity Form via do_shortcode().
 * - On the client, picks (and stores) a variant index in localStorage.
 * - Injects only the chosen form's HTML into the page.
 */
if ( ! function_exists( 'gf_ab_test_shortcode' ) ) {
    function gf_ab_test_shortcode( $atts ) {
        // Parse “formid” attribute, e.g. formid="1|5|9"
        $atts    = shortcode_atts( array( 'formid' => '' ), $atts );
        $ids     = array_filter( array_map( 'trim', explode( '|', $atts['formid'] ) ) );
        $count   = count( $ids );
        if ( $count < 1 ) {
            return '';
        }

        // Pre-render each Gravity Form into an array, preserving the same index order as $ids
        $forms = array();
        foreach ( $ids as $id ) {
            $forms[] = do_shortcode( "[gravityform id=\"{$id}\" title=\"false\" description=\"false\"]" );
        }

        // JSON-encode arrays for inline script
        $ids_json   = wp_json_encode( $ids );
        $forms_json = wp_json_encode( $forms );

        // Build a unique wrapper ID so multiple shortcode instances can coexist
        static $instance = 0;
        $instance++;
        $wrapper_id = "gf_ab_test_wrapper_{$instance}";

        ob_start();
        ?>
        <div id="<?php echo esc_attr( $wrapper_id ); ?>"></div>
        <script type="text/javascript">
        (function(){
            // Array of form IDs (strings) and corresponding pre-rendered HTML snippets
            var ids   = <?php echo $ids_json; ?>;   // e.g. ["1","5","9"]
            var forms = <?php echo $forms_json; ?>; // e.g. ["<form id='gform_1'…>…</form>", ...]

            // The localStorage key includes the exact "formid" string to avoid collisions:
            var storageKey = 'gf_ab_chosen_<?php echo esc_js( $atts['formid'] ); ?>';
            var storedId   = localStorage.getItem(storageKey);
            var chosenIndex = -1;

            // If storedId matches one of our IDs, use its index
            if (storedId && ids.indexOf(storedId) !== -1) {
                chosenIndex = ids.indexOf(storedId);
            }

            // Otherwise, pick a random index, store its actual ID, and set chosenIndex
            if (chosenIndex === -1) {
                chosenIndex = Math.floor(Math.random() * ids.length);
                try {
                    localStorage.setItem(storageKey, ids[chosenIndex]);
                } catch(e) {
                    // Fail silently if localStorage is not available
                }
            }

            // Now inject the chosen form HTML and rename the wrapper div to include the form ID
            var wrapper = document.getElementById('<?php echo esc_js( $wrapper_id ); ?>');
            if (wrapper) {
                var formId = ids[chosenIndex];
                var newId  = 'gf_ab_test_container_' + formId;
                wrapper.id = newId;
                wrapper.innerHTML = forms[chosenIndex];
            }
        })();
        </script>
        <?php
        return ob_get_clean();

Now use this shortcode wherever you want the test to run:

[gf_ab_test formid='1|5']

You can include as many form variations as you want. Just separate them with a pipe symbol (|).

A Few Tips to Make Your Test Even Better

If you want to track performance, it’s easy to do with Google Tag Manager and Google Analytics 4. Here’s how:

  • Set up an Impression Trigger in Tag Manager to fire when the form becomes visible on the page
  • Create a Form Submit Trigger to fire when someone completes the form
  • Send both events to GA4 and pass the form variant as a parameter or event label

This gives you clean, reliable tracking without relying on extra scripts from a testing platform.

A few more quick tips:

  • Keep your changes minimal. Just test one or two differences at a time so you know what’s making the impact
  • Let the test run long enough to get useful results. The more traffic, the quicker you’ll get your answer
  • This server-side method avoids all the issues that come with DOM manipulation, especially on forms with conditional logic or multiple steps

Wrap-Up

You don’t need a complicated tool or a bloated script to test Gravity Forms. This shortcode approach is fast, flexible, and doesn’t mess with your site speed or break your forms.

It’s easy to drop in and just works. No flicker. No weird behavior. No extra cost.

If you try it out, I’d love to hear what kind of results you see. Let me know which version wins for you.

Sharing is caring!