Contentful : Use AB Tasty to Serve the Right Variation

Use AB Tasty to Serve the Right Variation

This integration only needs to be implemented once. However, it requires a front-end developer to update the site’s code so that the AB Tasty Variation Container from Contentful can be connected with the Flagship SDK. It will combine the Contentful API with a Feature Experimentation SDK to decide which content variation should be displayed to a user.

In the example below, a pseudo-backend retrieves the AB Tasty Variation Container from Contentful and leverages Feature Experimentation to select the appropriate variation for the visitor.

When you fetch a variation container entry from the Contentful API, the response includes the main fields:

  • experimentId

  • meta

  • variations

{
  "sys": {
    "space": {
      "sys": {
        "type": "Link",
        "linkType": "Space",
        "id": "test"
      }
    },
    "id": "FAKE_ID",
    "type": "Entry",
    "createdAt": "2025-08-28T13:49:03.977Z",
    "updatedAt": "2025-08-28T13:49:03.977Z",
    "environment": {
      "sys": {
        "id": "master",
        "type": "Link",
        "linkType": "Environment"
      }
    },
    "publishedVersion": 3,
    "revision": 1,
    "contentType": {
      "sys": {
        "type": "Link",
        "linkType": "ContentType",
        "id": "abTastyContainer"
      }
    },
    "locale": "en-US"
  },
  "fields": {
    "environmentId": "ci84rm4uf6t1jrrefeig",
    "environment": "prod",
    "experimentID": "d1ilgv373e5iv8esho80",
    "experimentName": "TEST ContentFull",
    "variations": [
      {
        "sys": {
          "type": "Link",
          "linkType": "Entry",
          "id": "5pDbSiwvTqtBthib8G1opA"
        }
      },
      {
        "sys": {
          "type": "Link",
          "linkType": "Entry",
          "id": "5zKtmbcqb9ndM2wgU1KEmk"
        }
      },
      {
        "sys": {
          "type": "Link",
          "linkType": "Entry",
          "id": "6QJmXjfiu91B7UpbjlKl1Z"
        }
      }
    ],
    "meta": {
      "d1ilgv373e5iv8esho90": "5pDbSiwvTqtBthib8G1opA",
      "d1ili4eg4ajm59kcr1kg": "5zKtmbcqb9ndM2wgU1KEmk",
      "d1j7hjfdv6k265cudqg0": "6QJmXjfiu91B7UpbjlKl1Z"
    },
    "projectId": "ci84rmkuf6t1jrrefejg"
  }
}

Decide on a Variation with Feature Experimentation

Use the Flagship SDK to decide which variation to present.

1. Initialize the SDK

const { Flagship, DecisionMode } = require('@flagship.io/js-sdk');

Flagship.start(process.env.FLAGSHIP_ENV_ID, process.env.FLAGSHIP_API_KEY, {
  decisionMode: DecisionMode.DECISION_API,
  fetchNow: false,
});

2. Create a Visitor

const visitor = await Flagship.newVisitor({
  visitorId: String("VISITOR_ID"),
  context: {},
  hasConsented: true
});

3. Retrieve the Variation ID

async function getVariationForCampaign(visitor, campaignId) {
    if (!campaignId) {
        throw new Error('getVariationForCampaign: missing campaignId');
    }
    // fetch the flags
    await visitor.fetchFlags();
    // get the metadata from the visitor
    const flags = await visitor.getFlags();
    const metaMap = await flags.getMetadata(); // Map

    if (!metaMap || typeof metaMap[Symbol.iterator] !== 'function') {
        throw new Error('getVariationForCampaign: invalid metaMap');
    }

    // Find the right campaignId → variationId mapping
    for (const [flagKey, meta] of metaMap.entries()) {
        if (!meta) continue;
        if (meta.campaignId !== campaignId) continue;
        return meta.variationId;
    }
    throw new Error(`getVariationForCampaign: no metadata for campaignId=${campaignId}`);
}

const variationId = await getVariationForCampaign(visitor, campaignId);

AB Tasty selects the correct variation for the given visitorId based on the flag decision. You can then use the variationId to retrieve the matching content entry from the variation container’s meta field.


Retrieve the Variation Entry from Contentful

// Import the official Contentful SDK
const contentful = require('contentful');

// Create a Contentful client using environment variables
const client = contentful.createClient({
  space: process.env.CTF_SPACE_ID,          // Contentful Space ID
  accessToken: process.env.CTF_CDA_TOKEN,   // Content Delivery API (read-only) token
});

// Fetch entries of type "abTastyContainer"
const containerResp = await client.getEntries({
  content_type: 'abTastyContainer',
  limit: 1,
  include: 2,
});

// Extract the first container
const container = containerResp.items[0];

// AB Tasty campaign ID linked to this container
const campaignId = container.fields.experimentID;

// Includes contain all linked entries and assets
const includes = containerResp.includes;

// Retrieve the variationId for this campaign and visitor
const variationId = await getVariationForCampaign(visitor, campaignId);

// Map variationId → entryId from the container
const containerMeta = container.fields.meta;
const entryId = containerMeta?.[variationId];

// Find the linked entry in the includes
const entry = includes.Entry?.find(e => e.sys.id === entryId);

Result

This approach ensures a seamless link between the Flagship SDK and Contentful by mapping variationIds to content entries. For each visitor, the correct variation is automatically selected and delivered—scalable, reliable, and consistent.

Last updated

Was this helpful?