# Contentful : Use AB Tasty to Serve the Right Variation

## Use AB Tasty to Serve the Right Variation&#x20;

This method 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`

```json
{
  "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

```js
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

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

#### 3. Retrieve the Variation ID

```js
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

1. From **Contentful**>**Settings Menu**> **API keys**
2. **Retrieve** SpaceID & **Content Delivery API token**
   1. Click on [**Add an API key**](#user-content-fn-1)[^1]
      1. Copy the Space ID&#x20;
      2. Copy the Content Delivery - access token&#x20;
      3. Click **save** if you've made any changes (You will be able to look back at both the space ID & the access token by clicking on your [API name](#user-content-fn-2)[^2])
3. Use this code example to retrieve a variation entry // (replace the variable accordingly)

```js
// 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 `variationId`s to content entries.\
For each visitor, the correct variation is automatically selected and delivered—scalable, reliable, and consistent.

[^1]: ![](https://2350286830-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6Yw9IRJ6KbbucQPwZUCZ%2Fuploads%2FiAODtHraHhZjt2132sG8%2FCapture%20d%E2%80%99e%CC%81cran%202025-10-27%20a%CC%80%2016.40.24.png?alt=media\&token=27316f65-c8fe-4c51-ab2b-a410cb92b6c5)

[^2]: ![](https://2350286830-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6Yw9IRJ6KbbucQPwZUCZ%2Fuploads%2FXWfhCw85FdamVSttkMK5%2FCapture%20d%E2%80%99e%CC%81cran%202025-10-27%20a%CC%80%2016.43.16.png?alt=media\&token=ea412182-7402-4d46-a919-a3921ae354ff)
