Was this page helpful?

Extensibility - Personalisation of structured content


This article explains how personalisation of structured content can be implemented. The guide is covering the following areas:

  • Decorating structured content with metadata
  • Using a UI Extension to integrate with a personalisation service

Decorating structured content with metadata to enable personalisation

Personalisation is about making choices for the user optimized by relevance. Applied to content this might be as simple as choosing between two available content items. To illustrate that better, we will have a look at our example app which mimics a digital learning platform. The app highlights a specific course on its landing page. Which course to highlight is a choice an editor makes. This might look like:

On the left you see the content model which consist of a content type called highlightedCourse which holds a reference to the actual content item (the course). On the right the content model is rendered showing the Hello Contentful course which is intended for a general audience.

In contrast, a personalisable implementation might look like this:

The content model on the left was changed in two important aspects:

  • the highlightedCourse module holds references to two courses instead of one
  • the course was decorated with metadata which holds audience information

The personalised experience on the right now renders the Hello SDKs course which was made for a developer audience. The client application would implement a third party service which detects the audience and could then make an optimized decision on which of the courses to highlight for the user.

Setting up a personalisation service

Editors are usually working in the Contentful web app to curate content. Now we need to enable the editor to make decision on which content is meant for which audiences. To solve that we need to do a few things:

  • choose a third party service with personalisation features such as audience creation and targeting andwith access to those through an API
  • create audiences in the personalisation service
  • enable the editor in the Contentful web app to load those audiences and assign them to content items

In this tutorial we chose Optimizely as they offer personalisation as well as a REST API.

We will not go into details on audiences but basically they have a name, an id and are based on targeting criteria such as cookies or other context parameters such as device or location.

For this exercise we created three audiences: Developer, Digital Leader, Editor. After creating an access token with read-only access we can use Optimizelys REST API to load the audiences from our project in Optimizely.

        "archived": false,
        "conditions": "[\"and\", [\"or\", [\"or\", {\"match_type\": \"exact\", \"name\": \"editor\", \"type\": \"cookies\"}]]]",
        "created": "2018-04-12T11:54:28.672970Z",
        "description": "",
        "id": 10557426895,
        "is_classic": false,
        "last_modified": "2018-04-12T11:54:28.672990Z",
        "name": "Editor",
        "project_id": 10467324025,
        "segmentation": false
        "archived": false,
        "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"saw developer docs\", \"type\": \"custom_attribute\", \"value\": \"true\"}]]]",
        "created": "2018-04-11T09:44:33.381380Z",
        "description": "",
        "id": 10583060017,
        "is_classic": false,
        "last_modified": "2018-04-11T11:27:31.430900Z",
        "name": "Developer",
        "project_id": 10467324025,
        "segmentation": false
        "archived": false,
        "conditions": "[\"and\", [\"or\", [\"or\", {\"match_type\": \"exact\", \"name\": \"foo\", \"type\": \"cookies\", \"value\": \"bar\"}]]]",
        "created": "2018-04-12T11:54:58.072270Z",
        "description": "",
        "id": 10587732368,
        "is_classic": false,
        "last_modified": "2018-04-12T11:54:58.072280Z",
        "name": "Digital Leader",
        "project_id": 10467324025,
        "segmentation": false

We now have everything ready to load audiences from Optimizelys REST API into the web app through a UI Extension. So an editor can use the UI Extension to decorate content with the IDs of audiences.

Connecting the personalisation service to the Contentful web app

To connect the Contentful web app to Optimizely we are using a custom UI Extension. The UI Extension needs to do the following:

  • fetch data from Optimizely with a GET request
  • set the project ID in the query string and send an Authorization header with our read-only token
  • render the audience data in a dropdown which supports the selection of multiple values
  • make the IDs of the selected audiences persistent in Contentful as metadata of other content
WARNING: This example uses a read-only token to read from a third party service. The token is shared with all users which have read access to the space's content model on the Content Management API. This can be fine but should be evaluated case-by-case.

The screenshot above shows the UI Extension being assigned and configured with parameters. We open sourced the Optimizely audiences UI Extension so you can have a look at the implementation details.


  • Decorating structured content with metadata is a great way of keeping content re-usable, yet enabling more advanced use cases
  • Third party services with an API can be easily connected to the Contentful web app through UI Extensions
  • UI Extensions configuration parameters can be used to encapsulate configuration from code