Contentful is a headless CMS, a composable content platform that meets the unique demands of digital content and all the teams that produce and work with it.
Built with an API-first architecture, Contentful orchestrates content from multiple sources and publishes it to any digital channel. It ensures content is discoverable and reusable, provides tailored interfaces, and incorporates governance through role-based access management and workflows.
The Contentful Integration allows Contentful users to run experiments on content directly from Contentful and use Kameleoon’s powerful analytics solution to analyze the performance of those experiments.
Key benefits
- Bringing experimentation capabilities to Contentful for users in charge of managing the website content through Contentful CMS
- Keep Contentful as the single source of truth for your content
- Run advanced no-code experiments on structured content (copy, components, layouts and pages) managed in Contentful
- Reduce the amount of manual work needed and get the best of both world: managing variants of an experiment in Contentful, benefiting from Kameleoon powerful experimentation engine and analytics capabilities
- Marketers don’t have to be dependent on developers to lead experimentation
- No flicker: benefiting from server side instant bucketing by serving variations with no latency
Considerations
Keep these things in mind when using this integration:
- This integration can be used with SDK and hybrid experiments only.
- You need to have the Full Stack Experiment module enabled on your Kameleoon account.
Prerequisites
To configure this integration, you need the following information from Kameleoon:
- Login credentials: Your Kameleoon login credentials are the email address and password combination that allows you to access your Kameleoon account. This integration is using the OAuth authentication to log in your Kameleoon account.
- Sitecode: To know the project that will be used with this integration, you need to provide the Sitecode of your project. See the dedicated Kameleoon documentation to know where you can find your Sitecode.
Terminology
Let’s start by explaining some of the most used terms of this document.
What is an entry?
A piece of content, based on a content type. Entries are comprised of different fields. Think of them as the drawing you create with your content type stencil.
What is a content type?
A content type works like a stencil that defines the structure of an entry. Each content type comprises fields that denote the kind of content that will be included in the entry. Content types are created in spaces. When a content type is created and activated, editors are able to create individual entries using it.
What is a field?
Fields are what content types are comprised of. They are defined by you. Common field types include short text field, media field, and reference field.
- Short text field: Short texts are relatively small tokens of text, often used for titles and names.
- Media field: These include images, videos, PDFs and similar files.
- Reference field: Contentful uses reference fields to create relationships between content types. A basic example of using a reference field is to link a blog post to its author.
What is a Kameleoon Container?
When you install the Kameleoon integration from Contentful’s marketplace, behind the scenes, it will automatically create a new content type called Kameleoon Container.
Kameleoon Container is a special kind of content type that allows users to define the content of their variations (associating each variation with a specific entry).
This content type will be listed in the Content model page as soon as you finish installing the Kameleoon app.
Installation
- Go to your Contentful account.
- Go to Apps → Marketplace and search for Kameleoon.
- Install the Kameleoon app and authorize access.
- Configure the Kameleoon app with the project you want it to use.
- Select the sitecode of your project.
- Click on the Install button at the top right corner.
- The Kameleoon app is now fully installed and ready to be used.
Usage
Step 1 – Create a Kameleoon SDK or hybrid experiment in Kameleoon
- Go to your Kameleoon account and go to the experiment dashboard.
- Create a new SDK or hybrid experiment.
- To create a SDK experiment click New experiment → In the code editor → SDK.
- To create a Hybrid experiment click New experiment → In the code editor → Hybrid.
- Configure your experiment the way you want.
Step 2 – Create a Kameleoon Container entry in Contentful
- Go to your Contentful account and go to the Content page (you can use the navigation menu at the top of the page).
- Click on Add Entry and select Kameleoon Container.
- Configure your Kameleoon Container entry:
- Enter an Entry Name.
- Select an experiment in the Kameleoon experiments dropdown. The variations associated with the experiment you selected will be automatically displayed, along with the percentage of allocated traffic.
- For each variation, click on Create entry and link to create a new entry and use it as your variation content, or click on Link an existing entry if you want to use an existing entry as the variation’s content.
Step 3 – Get ready to publish your content
Your Kameleoon Container will be ready to be published when you will have the four steps marked as checked:
Here’s how you can validate each step:
- Select experiment – You can validate this step by selecting one experiment in the Kameleoon experiments dropdown.
- Add content – You can validate this step by associating an entry for each variation.
- Publish variations – This step will be marked as check when all the entries associated with the variations will be published.
- Start experiment – To validate this step, go to your Kameleoon account and launch your experiment.
Integration with your front end
Kameleoon Container is a new content type that is introduced into the Contentful response. It is a container that points to two or more actual values that we’d like to test. You now need to integrate your front end with Kameleoon and the Kameleoon Container. At this point, we need the help of a developer to change how your front end works to accept and programmatically handle the Kameleoon Container entries.
Programmatically handling the Kameleoon Container is something you only need to do once. Then, the code used to handle the Kameleoon Container can be reused every time you receive a Kameleoon Container entry from Contentful.
From here, we need to take a more technical dive into the setup of the client and how it integrates with Kameleoon. It is beneficial for developers to get acquainted with the content we outlined above before moving onto the technical guide below.
The goals of the setup are:
- Enabling server side experimentation without pushing new code per experiment
- Separating concerns: controlling content in Contentful and experiments in Kameleoon
- Speed: server side selection of variations for fast delivery and to avoid the flicker effect
How the Kameleoon App changes the Contentful API response
As mentioned above, the Kameleoon app creates a new content type: the Kameleoon Container.
The Kameleoon Container is simply a content type that nests the possible values for the experiment and holds metadata about the Kameleoon experiment and the variation names.
Using Kameleoon to pick the right variation
We are going to create a pseudo-backend which takes the Contentful API response and uses the Kameleoon SDK to determine which variation to show to the user.
Let’s start by looking at the Kameleoon Container JSON response returned by Contentful. Notice that the content type exposes a meta, variations and experimentId property.
{ "metadata": { "tags": [] }, "sys": { "space": { ... }, "id": "5gWyJBcobUmLlncnBSAT6E", "type": "Entry", "createdAt": "2023-02-27T21:07:05.344Z", "updatedAt": "2023-02-27T21:11:15.357Z", "environment": { ... }, "createdBy": { ... }, "updatedBy": { ... }, "publishedCounter": 0, "version": 7, "automationTags": [], "contentType": { "sys": { "type": "Link", "linkType": "ContentType", "id": "kameleoonVariationContainer" } } }, "fields": { "entryName": { "en-US": "[KAMELOON] CTA_test" }, "experimentName": { "en-US": "CTA_test" }, "experimentId": { "en-US": "188144" }, "siteCode": { "en-US": "oylrix71c5" }, "meta": { "en-US": { "0": "XsLXDicMUMeoXBMBGp3lw", "827431": "5yElO4ISDwhzqm6sqAsSEy" } }, "variations": { "en-US": [ { "sys": { "type": "Link", "linkType": "Entry", "id": "XsLXDicMUMeoXBMBGp3lw" } }, { "sys": { "type": "Link", "linkType": "Entry", "id": "5yElO4ISDwhzqm6sqAsSEy" } } ] } } }
Before we can choose which entry to pick out of our Kameleoon Container, we need to see how to get the right variation from Kameleoon. Below is an example with a hardcoded test to get a variation for a user.
let { KameleoonClient} = require("kameleoon-client-nodejs"); import datafile from './kameleoonDataFile'; // You project's sitecode: const siteCode = "a8st4f59bj"; let kameleoonClient = new KameleoonClient(siteCode, { datafile }); // Waiting for the client to be properly initialized await kameleoonClient.initialize(); const visitorCode = kameleoonClient.getVisitorCode(req, res, "example.com"); const experimentID = 75253; const variationID = kameleoonClient.triggerExperiment(visitorCode, experimentID);
In the code above, Kameleoon has determined that this user (or visitor) should see the variation option. This is a value we can get from the Kameleoon Container meta field.
Now we will update our code to include pulling the Kameleoon Container itself and using its values to populate the Kameleoon experiment.
let { KameleoonClient} = require("kameleoon-client-nodejs"); import sdk from 'contentful-sdk'; import datafile from './kameleoonDataFile'; // You project's sitecode: const siteCode = "a8st4f59bj"; let kameleoonClient = new KameleoonClient(siteCode, { datafile }); // Waiting for the client to be properly initialized await kameleoonClient.initialize(); const visitorCode = kameleoonClient.getVisitorCode(req, res, "example.com"); // We are using the id of the Kameleoon Container from the JSON sample above // In a real-world implementation, the ID would be set dynamically through, e.g. a slug. const kameleoonContainerEntry = await sdk.getEntry('5gWyJBcobUmLlncnBSAT6E'); // We get the experiment ID from the Kameleoon Container entry const experimentID = kameleoonContainerEntry.experimentId; // We get the ID of the variation that we have to display const variationID = kameleoonClient.triggerExperiment(visitorCode, experimentID); // We get the entry associated with the variation using the variation ID const variationEntry = kameleoonContainerEntry.meta[variationID];
From here, you should be able to make minimal changes to your display logic in order to show the correct entry.