by

Headless doesn’t mean Clueless when it comes to your CMS

Reading Time: 5 minutes

“Headless CMS” is all the rage these days, and for good reason: It’s easier to build the UI the way you want. Your front-end team doesn’t need to know anything about the CMS now, right?

Wrong.

Headless doesn’t mean clueless.

How is a CMS headless when web pages need a <head>

Headful CMS is “Easy”

We see open source (and often, PHP-based) Content management systems where the software that’s managing the content is also the software that serves the content to the end user. You could also call this “tightly coupled content delivery.”

WordPress, Drupal, Joomla, Craft CMS are just a few examples of “tightly coupled content delivery”

On the one hand

These are easy to implement because you’re only dealing with one piece of software. They’re also easy to host and maintain for the same reason: everything is is one thing, in one place.

On the other hand

Customizing the end product takes an intersection of skills: someone has to be good at front-end and the CMS. You’re also sometimes limited in what you can do with the UI because of either how the CMS manages or renders that content.

Headless CMS is a good idea

Headless CMS is the new thing which isn’t really that new. SDL RWS Tridion has been both “loosely coupled” or “headless” for years 1. Other enterprise CMS have been “headlessable” for quite some time, too. Because tight coupling is bad for business.

On the one hand

A headless CMS lets you deliver content the way you want to. It also lets you have more specialized teams: One team does CMS things, the other team does UI things.

On the other hand

Your CMS and UI applications aren’t guaranteed to work together. And this is because front-end teams and back-end teams are now specialized, and may not know how they’re impacting each other.

In other words, they could be pretty damned clueless.

Clueless is not a feature, it’s a bug

Very, very often, I hear something like,

Once you have a headless CMS, the front-end team doesn’t have to know anything about the content

Todd, Senior front-end developer, connoisseur of IPAs and hemorraghing-edge JS frameworks

The front-end team team not knowing anything about how content is managed is a bad thing. A very bad thing. A very, very bad thing.

The front-end team needs a few clues

This is a far-from-exhaustive list of things that a front-end developer needs to know, as they impact how her code is written:

Content Modelsbecause Determines whether to use div, section, article, header, aside, or nav
Required & optional fieldsElements that are empty affect presentation and/or accessibility
Multivalue fieldsThe CSS to lay out 1, 3 or 30 items can be very different
Date fields<datetime> is an element that exists, damnit
Radio / multivalueKnowing that a field can only be certain values creates an assumption for width, or how classes can be generated
Embedded content modelsThat means some pattern of HTML markup could be reused
Plain text / Rich Textvalid markup from a rich text field is not valid when wrapping by certain other elements, like h1h6, p, em, strong, etc
Robust Rich Text vs weak Rich textCSS is needed to account for the possibility of images, tables, and even inline-styles
A few CMS clues for the front-end folks

When you don’t have a clue

I recently encountered one example where the front-end team not having a clue made headless less-than-helpful.

We had a rich text field that allowed inline styles. So that means the content author was able to write something relatively harmless, like this:

<p>If you're havin' skin problems, I feel bad for you, son
I got <strong><span style="font-size: 1.5em;"> 99 problems</span></strong>, but an itch ain't one</p>

The CMS here was Tridion, the field was a designated rich text field, and the field had styles enabled. So Tridion was allowing this markup, and for that matter, Tridion was correctly publishing the field.

But, over in the other corner, we had a front-end application that was removing the inline style attribute, but leaving behind the lovely span.

Neither the API nor the front-end application had any clue that this was a rich text field. Tridion knew, but none of the other applications did.

Getting clues in a headless world

My immediate suggestion in this case was, “we should get together and make sure we’re in sync with how this field works.” That’s fine for a one-off situation. But really, what can you do?

Requirements gathering and steady communication

Ok. Sure. You get yourself some analysts, you have them do stuff like document content models, and then they capture information like, “the description field is rich text, and may contain styles”, and then your front-end developers refer to documentation during their development.

And then you make sure to capture this for all new feature development, and then still regularly meet to develop proper end-to-end tests.

There is a big downside, though

Actual interview with a project manager

In addition to literally anybody having time for that, just… no one wants to do that.

Especially not Senior Front-end Developer Todd who’s busy upgrading to Angular 23 and has a bitchin IPA he’s gotta bottle himself this weekend.

Writing shit down and communicating is lame.

Don’t just publish content, publish your content definitions

What I see strangely missing from headless CMS APIs is content definitions.

I don’t mean types like what GraphQL offers (which is great, BTW).

I mean definitions.

As in, “how do you know this string is going to have plain text, poor text, or rich text?”

Really. How does the front-end developer know? If you’re not documenting your content models and making sure Todd sticks to them, what damned clue does he have that he needs to allow inline styles, or tables, or images for that matter?

If you don’t want to have the meetings, then you need a Content Definition API. Or a Content Restraints API. Whatever you want to call it. But it should be something that is updated when content models change.

Even in a Headless CMS, you still want a tightly-coupled content contract

That’s something that isn’t getting mentioned in headless CMS architectures2. I think it’s because the people building the CMS aren’t the people building the front-end.

Front-end is not an exercise in making a design pretty. It is a practice of making content consumable. And the only way to properly render consumable content is if you know how that content is being managed.

Either have meetings and document stuff on the regular, or produce a Content Definition API so that a front-end dev can find out what to expect from that description or title field.

Footnotes, Sources, and Whatnots

1 Tridion, in a “loosely coupled” model would publish render your HTML, JSP, Ruby, or PHP page and drop it on a file system somewhere. In this way, it’s “loosely coupled” because it’s not attached to the app responsible for putting content in the user’s browsers. But that doesn’t make it headless.
If you were to use Tridion to publish content in a data format and plop it on a file system, or publish directly to a database, now you’re headless. Since Tridion can’t find a shit in an Alabama outhouse to give for how you template your content, that means it’s been headless-capable for as long as it’s existed.
If you were to say, “publishing is for nerds and people who hate craft beer” and insist on a proper God-fearing API that ships with Tridion, then, ok, fine, Tridion wasn’t “headless” until 9.0. But GTFO with that pedantry.

2Strapi and Tridion are just two such examples where I don’t see anything that publishes a definition of the content model that would help a front-end developer prevent such a mistake.

1 Comment


  1. I’ve joked that delivering and consuming content-as-data isn’t really “headless” as much as it’s “faceless.” You still have the bones or structure of the content in the form of those content definitions you mention. But the front end will “flesh out” the rest of the connective tissue, organs, etc. (morbidly evocative enough for ya?).

Comments are closed.