Next & Previous

Headless CMS and Static CMS

In the beginning there were only static sites.

You write a load of HTML. To update your website, you update your HTML and upload it again. When a visitor comes to your website, a simple piece of software like httpd (or now nginx or IIS) says:

Looks like you want index.html! Here you go!

…and transmits it to the visitor’s PC.

This works great at a small scale, but it doesn’t scale for 24/7 news coverage with multiple editors, for example (your files would get in a mess really quickly).

The HTML Continuum*

(*not an accepted term)

Websites are still fundamentally HTML in a browser. The rest of this post is basically about the changing ways that we have delivered HTML to visitors. At the end I’ll zoom out to the who, where, and when of HTML delivery.


Content Management Systems are programs that run on the webserver on top of httpd/nginx/IIS.

The pages use HTML templates but now they can pull fields and sections from a database. Editors can log into the back-office of the website and change what’s in these fields and sections with ease.

When a visitor arrives, httpd says “I’ll let cms.exe handle this…”. cms.exe says:

Hmmm, you want /news/?storyId=12458? Looks like I need to take the news.html template and fill in all the fields with details I find in the story database, record number 12458… let me go find that. Ok, I’ve compiled a page for that story!

…and transmits the stitched-together HTML page to you.

If that sounds slow, it’s because it is. We mitigate against this slowness with various layers of caching.

Headless CMS

Sometime in the 2010s, developers decided they want to build Single Page Apps (SPAs) using all kinds of newfangled JavaScript frameworks, like React.

JavaScript was now good enough in the browser to change the HTML all the time without “reloading” the page. We could even make the address in the URL bar change while the user stays on one continuous page.

Now, to begin with, CMSs didn’t work well in this paradigm because to get a new page, you need to ask the CMS for it (as above) which counts as a navigation event – a reload.

But content authors still like their CMSs because they can edit pages, stories, and entities with ease.

So, Headless CMS retains the back-office, but instead of the CMS serving the site to visitors, some other web app asks the CMS API for the structure of the page. Then it takes responsibility for turning that data into HTML. Most often it’s the aforementioned SPA which does the transformation, using JavaScript in the visitor’s browser.

The CMS API is a special tack-on that lets the CMS tell you about page content rather than giving you the full-fat HTML. SPA frameworks are designed to translate data into HTML so they’re a good fit for this flow.

So now when a visitor arrives:

  1. httpd says “Looks like you want app.html, here you go!” and transmits it.
  2. Your browser loads a very large, very clever, very empty webpage.
  3. app.html runs JavaScript that says “Looks like we’re on /news/12458, let’s ask the server for that data…”
  4. The CMS API returns the structured content for the page
  5. app.html turns the data into HTML
  6. As you scroll, if built a certain way, the app does something clever to fetch more content, changes the address you see, and renders more HTML, ad infinitum (perhaps).

A note on another way

Before “Headless CMS” was a thing, I knew of a company who used Umbraco CMS to manage content, but instead of allowing Umbraco to serve the website to visitors, they had a separate ASP.Net MVC site which processed the XML output of Umbraco. This is still headless CMS but the rendering happens in a seperate app on the server.

Any way that you can exfiltrate data from a CMS allows you to do this kind of thing; it doesn’t have to be an API.

Static Site Generators (SSGs)

By way of intro, I like what I wrote in 2017:

An SSG lets you build reusable templates, and write your content in a flexible format like markdown (both of which make it like a CMS), and compile the source files into static HTML which is then uploaded to the server. This means that page loads are instant (no database lookups, no dynamic page generation) but you still have 90% of the power of a CMS for editing the website in a flexible way. Pushing updates to the site is usually done with source control, so that when a commit has been reviewed, it is pulled into trunk/master, and gets built and published by an automatic script.

I write layout.html which is a template and conatins no page content. I also write,, and a load of blog posts in a simpler language, such as Markdown.

I run a script that compiles the site on my PC (or in the cloud) into plain old HTML and publishes it.

Then the story for serving visitors goes back to where we started; httpd says:

Looks like you want index.html! Here you go!

It’s super efficient, but the editing journey works best for nerds of the command-line, text-editing persuasion.

Static CMS

I see some confusion over what to call “a flat-file CMS bolted on to a static site generator” because some people call this “Headless CMS”. Perhaps, in one way, that’s right because you’ve got the “back” of a CMS and no front, but with a Headless CMS I feel like you should have some software on the server that does CMS-y things. But what’s my definition of “CMS-y things”? Maybe I should think about that…usually there’s a database? Executing back-end code?

Anyway, examples of Static CMSs are Netlify CMS and Publii.

The Static CMS, in practice, is a web app which lives alongside your static site. You log into it, create and edit posts, and in order to save or publish these posts, they are pushed using source control (i.e. git) to the repository of the website. It has no inherent storage in and of itself.

I really think these are great. They strike a great balance. Authors get a friendly experience, visitors get instant page loads of static HTML, and the hosting is generally free (or close to free). The environmental cost is also lower than a CMS as there is no on-demand code execution on the server. Faster page loads because of less processing time means less electricity used. Great!


I think it’s interesting to summarise this in a table:

System What composes HTML When is HTML composed
Static HTML Dev, in a text editor Before uploading the site
Trad. CMS CMS program on the server During page load
Headless JS framework in browser After page load
SSG Site generator on PC/server During site build
Static CMS

May your edits be effortless and your page loads speedy 🍃

Further reading: