Watch Webinar: Figma - Design to Code in 80% Less Time

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Talk to Us
Contact Sales
Platform
Developers
Talk to Us

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

With Builder, A/B testing works out of the box for Page and Section models, but data models require a bit more set up. In this article we will learn about A/B testing structure in Data models, rendering A/B tests, and delivering the correct variant to users.

To get the most out of this document, you should already be familiar with:

Running A/B tests on a data model within the visual editor follows the exact same flow as setting up an A/B test for a page or section model. Simply create the data model content entry, and then within the entry, create any number of variants. However, in order to access the variants within youir code, there is a bit of set up. 

Simply wrap where you use your data model content in a <BuilderContent/>component, and it will handle picking the correct variant and persisting the data across a user's session for you.<BuilderContent/>even supports Server Side Rendering, just pass the Builder content to the content prop the same as you would in a <BuilderComponent/>

In the example below, we have a buy-button-cta data model that has text for a CTA that we want to run an A/B test on. The variant is chosen and that data is rendered as the CTA text

import { BuilderContent } from '@builder.io/react'

export function MyComponent() {
  return (
    <BuilderContent model="buy-button-cta" content={buttonCTAContent}>
      {(variant, loading, fullContent) =>
        //variant is the data property after the correct variation is chosen
        //loading is the loading state, that returns true while content is being fetched
        //fullContent represents the raw data from the server that contains all variations
        loading ? (
          <Spinner />
        ) : (
          <button>{variant.ctaText}</button>
        )
      }
    </BuilderContent>
  );
}

The JSON below represents the data returned by a Data model entry that contains an active A/B test. A/B testing is implemented with the standard data property for the default option and a variations property containing key/value pairs for each data object for a given variant of the A/B test.

Additionally, the testRatio sub-property indicates the percentage of time each variation should be shown.

{
    "results": [
        {
            "lastUpdatedBy": "2ej3Ldf2pKYWQiEMPKzdUGcUvU53",
            "folders": [],
            "data": {
                "date": 1699257600000,
                "image": "https://cdn.builder.io/api/v1/image/assets%2F988e5176e08a4773bb301a97f9e56493%2F2c2e0b2072104385b721d941710c8a2b",
                "author": {
                    "@type": "@builder.io/core:Reference",
                    "model": "author",
                    "id": "bbbc29f3d2dc43b7ad820c7709749e42_3e9fc0cb1016406299b45ac368641c99"
                },
            "createdBy": "2ej3Ldf2pKYWQiEMPKzdUGcUvU53",
            "meta": {
                "kind": "data",
                "lastPreviewUrl": ""
            },
            "variations": {
                "1111aaddca3843029a7c5fafaed58ba4": {
                    "testRatio": 0.5,
                    "createdDate": 1699057084439,
                    "data": {
                        "date": 1699257600000,
                        "image": "https://cdn.builder.io/api/v1/image/assets%2F988e5176e08a4773bb301a97f9e56493%2F70bc2dc8de36427bb19a86be64f1ba6c?format=webp",
                        "author": {
                            "@type": "@builder.io/core:Reference",
                            "model": "author",
                            "id": "bbbc29f3d2dc43b7ad820c7709749e42_3e9fc0cb1016406299b45ac368641c99"
                        },
                        "articleText": "The Pats defeated the Commanders 17-13 in a defensive battle on Sunday. Lorem Ipsum blablablablablabl bal bla b lablaa",
                        "genre": "sports",
                        "title": "Patriots Defeat Commanders In Close Game",
                        "blurb": "New England bounces back in week 9",
                        "slug": "pats-commanders"
                    },
                    "meta": {},
                    "name": "Variation 1",
                    "id": "1111aaddca3843029a7c5fafaed58ba4"
                }
            },
            "name": "pats-commanders",
            "id": "bbbc29f3d2dc43b7ad820c7709749e42_654c3085cc514cab8d028a5ab581c768",
            "rev": "cp41au6hjiv"
        },
    ]
}

The Builder.io content ID for a given content entry usually either consists of a unique ID alone, or your API Key, an underscore, and the unique ID. Builder.io uses a cookie with a name like builder.tests.{builderId} to track A/B tests. The value of this cookie can either be the Builder id itself (indicating the default value) or the key of the chosen variation.

In this example, the chosen variation would be 1111aaddca3843029a7c5fafaed58ba4. This behavior is how Builder handles any A/B Test, so this cookie is not exclusive to data model A/B testing.

When rendering data from a data model within a Builder components (for example, when setting up blog templates), it's vital to wrap the <BuilderComponent> within a <BuilderContent> tag. If you don't, the <BuilderComponent> won't be aware of the A/B test cookie for the given data m and will only return the default data (from the data object in the JSON).

Consider the following example. Begin with raw data stored in the articleData variable, obtained through a builder.get() call. Pass this data to the content prop within the <BuilderContent/> component.

Inside, the Builder SDK processes the data and selects the winning variant based on the A/B test cookie (builder.tests.{builderDataId}). This selected variant becomes the data object containing only the winning variation, excluding the others.

return (
    <>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        {!articleData && <meta name='robots' content='noindex' />}
      </Head>
      <BuilderContent model="article" content={articleData}>
        {(data, loading, fullContent) => {
          //data is the data property after the correct variation is chosen
          //loading is the loading state, that returns true while content is being fetched
          //fullContent represents the raw data from the server that contains all variations
          return (
            <>
              <BuilderComponent model="blog-template"
                content={articleTemplate}
                data={{article: data}}
              />
            </>
            )
        }}
      </BuilderContent>
    </>
  );

You can now use this data object for rendering with the <BuilderComponent>. The articleTemplate variable specifies the desired section model, indicating that you want to render that specific segment with the winning variation provided as the data field.

Was this article helpful?

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Newsletter

Get the latest from Builder.io

By submitting, you agree to our Privacy Policy