Content-as-a-Service Review: Contentful

contentful-logoIt’s time for the next vendor in my Content-as-a-Service (CaaS) round-up. In this post I’ll be taking a look at Contentful. If you missed my overview of the emerging CaaS market you might want to take a look and then come back.

Contentful came out of beta to be generally available in May of 2014, so it is the youngest vendor of the three in my round-up. The company is based in Berlin and has a number of well-known clients including EA, Disney, Viacom, Asics, Nike, Playboy, and McAfee.

My CaaS overview described functionality you’ll find in all CaaS offerings. Similar to my post on Prismic.io, in this post on Contentful I’ll focus on the areas that typically differentiate one CaaS offering from another, namely:

  • User interface for content authors
  • Creating content types
  • Working with content via the API
  • Security
  • Pricing

Finally, I’ll wrap up with my overall impressions and takeaways.

User Interface

In Contentful you have one or more “spaces”. You can think of a space as a repository. It’s a collection of “entries”, which are instances of content types, and “assets”, which are file-based assets like images. In addition, each space has its own users, roles, and API keys.

When you log in to Contentful you’ll be sitting in one of your spaces (the first one in the list). The Contentful user interface is clean and quite minimal. It’s easy to get going quickly because you have a limited function set. You can define your content model, manage entries, manage assets, or manage your API keys and that’s about it.

contentful user interfaceOptions for organizing lists of entries and assets are limited to filtering based on status (Published, Changed, Draft, Archived), content type (for entries), and file type (for assets). There is a saved search feature and saved searches can be organized into folders. But, there is no notion of hierarchical content storage.

This minimalistic approach to content management is what I characterized as a Good Thing in my Content-as-a-Service overview.

Content Types

Every content management system has a way to describe the data stored in the repository which is referred to as a “content model”. In Contentful, each space has its own content model which is simply a set of content type definitions. A content type is a set of typed properties. There are property types you’d expect, like text, date, number, decimal number as well as “pointer” types that reference other objects in the system, where those objects are either entries or file-based assets.

For example, the screenshot below shows a Promo content type I created. It has a name, a description, and a set of fields such as pubDate, geoCode, image, alt, etc. In the case of the image field, it points to a file-based asset.

contentful content typeUnfortunately, there is no support for cross-cutting concerns (aspects) so if you want to repeat property definitions across types you have to do that manually. For example, a type called “Cat Picture” and a type called “Dog Picture” might both have “height” and “width” properties. In Contentful, you have to repeat similar properties across type definitions.

On a related note, there is no way to clone or copy content types in the user interface. If you have two similar content types you have to re-do the property sets in each one or use the Contentful content management API to do this.

Managing your content model in the Contentful UI takes way too many clicks. I much prefer the approach other CaaS offerings take where you edit the content type definitions using JSON rather than the point-and-click approach. The nice thing with Contentful is that you can use the API for everything, including defining your content model–you don’t have to use the UI at all if you don’t want to.

One thing to watch out for: If you want to change a field on a content type (like maybe change the type of field) you have to deactivate the content type first. That’s not such a bad thing until you realize you cannot deactivate a content type without first getting rid of the instances of that content type. This could be a challenge once you go to production, so make sure you are happy with your content model before you get too far down the road.

Working with content via the API

Content can either be “published” or “draft”. The API keys you generate for a space can either be “production” or “preview”. The production URL and access key can only fetch published content. The preview URL and access key will see everything.

The Contentful Content Delivery API lets you fetch content by space which can be further filtered by query terms that will be AND’ed together. There was not an obvious way to OR query terms.

If you’d rather, Contenful offers client libraries in Java, JavaScript, Objective-C, Swift, and Ruby.

Here is a gist that fetches content using JavaScript:

var contentful = require('contentful');

var spaceId = 'someSpaceId';
var accessToken = 'someAccessToken';
var contentTypeId = 'someContentTypeId';

var client = contentful.createClient({
  space: spaceId,
  accessToken: accessToken,
  secure: true,
  host: 'cdn.contentful.com'
});

client.entries({
    'content_type': contentTypeId,
    'fields.pageId': 'all',
    'fields.geoCode': 'all'
}, function(err, entries) {
    if (err) { console.log(err); return; }
    for (var i = 0; i < entries.length; i++) {
        var entry = entries[i];
        console.log('id: ' + entry.sys.id);
        console.log('name: ' + entry.fields.name);
        console.log('pageId: ' + entry.fields.pageId);
        console.log('--------')
    }
});
id: someId1
name: promo-3
pageId: all,page2,page3
--------
id: someId2
name: promo-2
pageId: all,page5
--------
id: someId3
name: promo-1
pageId: all
--------

(Can’t see the code? Click here.)

If all you need to do is fetch content from Contentful, you’ll stick with their Content Delivery API. To create, update, or delete content, use the Content Management API.

For example, here is a gist that creates content using the Content Management API:

var contentful = require('contentful-management');

var spaceId = 'someSpaceId';
var accessToken = 'someAccessToken';
var contentTypeId = 'someContentTypeId';

var client = contentful.createClient({
    space: spaceId,
    accessToken: accessToken,
    secure: true,
    host: 'api.contentful.com'
});

// a custom "Generic Content" content type
var entry = {
    fields: {
        name: {
            'en-US': "Take a Trip!"
        },
        description: {
            'en-US': "Title for page 4"
        },
        geoCode: {
            'en-US': ["all"]
        },
        loginState: {
            'en-US': ["all"]
        },
        pageId: {
            'en-US': ["page4"]
        },
        placementId: {
            'en-US': ["banner"]
        },
        expDate: {
            'en-US': "2014-10-31T00:00:00-05:00"
        },
        pubDate: {
            'en-US': "2014-10-01T00:00:00-05:00"
        },
        content: {
            'en-US': {title: "Take a Trip", imgSrc:""}
        }
    }
};

client.getSpace(spaceId).catch(function(error) {
    console.log('Could not find space: ' + spaceId);
    throw error;
}).then(function(space) {
    space.createEntry(contentTypeId, entry).catch(function(error) {
            console.log('Error creating entry: ' + error.toString());
            throw error;
    });
});


(Can’t see the code? Click here.)

Note that content is initially created in draft mode. You must publish the content if you want it to be retrievable via the “production” content delivery API.

I should mention that Contentful also offers a sync API, which is particularly useful for mobile applications.

Security

In Contentful, everyone belongs to one or more Organizations. Organization owners can create spaces and can invite users to a space. Users can be editors (edit all content) or developers (edit all content, manage API keys). Space admins can create new content types. The UI shows a “custom role” but this article says that custom roles will be implemented for the enterprise offering at some point in the future.

Contentful also makes it easy for agencies or consultants to administer an organization on their client’s behalf while the client remains the main contact for billing purposes.

Pricing

Contentful offers the following plans:

  • Free plan which is limited to 3 users, 3 spaces, and 1,000 objects
  • Plus plan for $99 per month which includes 5 users, 5 spaces, and 5,000 objects
  • Pro plan is $200 per month for up to 10 users, 10 spaces, and 10,000 objects.

Most of my clients would probably need the “Enterprise” plan which could cost anywhere between the low thousands to the tens of thousands of dollars per month depending on exactly what is needed.

Also, be aware that Contentful, like other CaaS vendors, places limits on additional things such as API requests, API bandwidth, and API keys. These and other details may change so take a look at the pricing page (click “Compare Plans” for the expanded details) to be sure.

Overall Impressions

Contentful is an extremely basic offering in terms of both the user interface and the capabilities of the underlying platform. But the simplicity of the offering is precisely what makes it so attractive. Developers will appreciate the “API-first” approach to content management, and without a lot of extraneous sub-systems getting in the way, they’ll be able to develop a solution quickly, and then let content authors manage the content with the easy-to-use interface. Contentful’s stripped down, pragmatic approach to content management is a category-defining building block you can use to create really cool content-centric solutions.