What is a headless cms anyway?

borsiborsi RSS Feed

The term ‘headless cms’ has been rising in popularity for a while now. But why the hype and what is it all about?


What is a headless CMS?

First, it’s worth mentioning how traditional “monolithic” cms’s work. Wordpress or Drupal are usually included in this category. At monolithic cms’s the modal layer is tightly coupled with the view, and the creators of the platform provide you with a templating engine with which you can implement your frontend. So in this model you’d have:

  • a Database at the “bottom”, where you store your content
  • an App, with a UI that lets you Create, Read, Update and Delete this content
  • and a View layer which displays the content (usually by using templates)

Older versions of sensenet ECM are also following this philosophy, although the platform is more geared towards enterprise features, such as content versioning and collaboration. Thus, the ‘E’ in ECM is for Enterprise.

This is why you could do something like this in sensenet 6.x, or using sn-webpages 7.x:

<div class="sn-article-list">
    <%foreach (var content in this.Model.Items)
      { %>
    <div class="sn-article-list-item">
	<h2 class="sn-article-title">
		<a href="<%=Actions.BrowseUrl(content)%>">
			<%= content.DisplayName %>
		</a>
	</h2>
        <small class="sn-article-info">
		PublishedBy: <%= content["Author"] %> on
                <span class='<%= "sn-date-" + content["Id"] %>'>
			<%= content["ModificationDate"]%>
		</span>
	</small>
        <div class="sn-article-lead">
            <%=content["Lead"] %>
        </div>
    </div>
    <%} %>
</div>

*fig 1. ~ The template is tightly coupled with the data it needs to present.*

In a headless CMS (or ECMS for that matter), though, the backend does not care about how the content is displayed. It just returns with the data needed for the frontend through a RESTful API.

Headless vs Coupled

*fig 2. ~ Traditional (coupled or monolithic CMS) model vs. Headless CMS*

So is sensenet ECM a headless or a coupled CMS?

Why not both?

As mentioned earlier, using sn-webpages, you can have a full-featured ECMS solution, complete with a built-in UI. We are also working on a new UI, using React and Aurelia while fully utilizing sensenet ECM’s OData layer, which provides a complete, flexible and extendable RESTful API.

In the meantime, you can either start writing your own library to latch on the OData endpoints of a sensenet ECM instance at hand, or you can try out our fabulous and open source sn-client-js, the javascript client library for sensenet.

In the end, what you get is something like this 1:

After installing our library from npm, you can import it and connect to your sensenet ECM instance.

import { Repository, Config } from 'sn-client-js';

let repository = new Repository.SnRepository({
	RepositoryUrl: 'https://my-sensenet-site.com'
});

*fig 3. ~ Configuring the repository object.*

Once done, you can start working with content e.g. fetching them for using the results as a sn-client-js Collection


import * as SN from 'sn-client-js';

let collection = new SN.Collection([], repository.Content);

var options = new SN.ODataApi.ODataParams({
	select: ["Id", "DisplayName", "BrowseUrl", "Author", "ModificationDate", "Lead"],
	orderby: 'ModificationDate',
	metadata: 'no' });

let fetchContent = collection.Read('/NewsDemo/External', options);

fetchContent
	.map(response => response.d.results)
	.subscribe({
		next: response => {
			//pass response to your view component
		},
		error: error => console.error('something wrong occurred: ' + error),
		complete: () => console.log('done'),
	});

*fig 4. ~ Configuring and creating a Collection object and fetching data with its read method.*

The collection is ready, so you can start working with your favourite framework to render the article list.

import * as React from 'react'
import * as ReactDOM from 'react-dom'

ReactDOM.render(
  <ArticleList content={articles} />,
  document.getElementById('root')
);

class ArticleList extends React.Component<{ content }, {}> {
  const articles = this.props.content;

  render(){
	  return (
	    <div class="sn-article-list">
	    {
	    	articles.map((article) =>
		    <div class="sn-article-list-item">
			<h2 class="sn-article-title">
				<a href="{ article.BrowseUrl }">
					{ article.DisplayName }
				</a>
			</h2>
			<small class="sn-article-info">
				PublishedBy: { article.Author } on
				<span class="sn-date">
					{ article.ModificationDate }
				</span>
			</small>
			<div class="sn-article-lead">
			    { article.Lead }
			</div>
		    </div>
	    }
	    </div>
	  );
  }
}

*fig 5. ~ Rendering article list with a Reactjs component.*

As simple as that. We are at the beginning of our roadmap and we need your feedback in making a better ECMS development platform. So feel free to chime in either through e-mail, gitter or by sending a homing pigeon. We are eager to hear your voice.


1: You can achieve a similar experience using the .NET client for sensenet ECM.

Disclaimer: Since I am not a developer, my initial code examples were not as fabulous as they are now. Many thanks to @tusmester and @herflis for providing me with meaningful snippets.

Have feedback on this post? Let @sensenet know on Twitter.

Need help or found a bug? Contact us.