So you’ve built a static website, all is going well, but then it turns out that the client needs a small news section (which will be updated frequently). What do you do? A headless CMS might be an answer.

Headless?

Headless software is software capable of working on a device without a graphical user interface.

— Wikipedia

A regular CMS, like WordPress or Drupal, has three basic parts:

a database to store content

a CRUD API to edit it (an admin panel)

a way of displaying the content — basically what the end users see

This third part though won’t be needed. What end users see will be the static website you already have, and all we want from the CMS is a way to provide the content as data, not as HTML views. The CMS will not be concerned at all about how the site looks like, it will just handle data input and output.

Enter WordPress.

We’ll skip any paid and/or cloud-hosted options for a couple of reasons. Firstly, no client would accept any fees for a small news section. Secondly, in the event of our cloud-hosted CMS provider going out of business, the data might go with him. Thirdly, it’s best to learn if you can look at the internals of any code you’re using.

WordPress has been around forever. It is stable and its editing interface feels intuitive and is easy to grasp for anyone. The technologies it uses, PHP and MySQL, are probably available at every hosting provider, and the amount of support and documentation on the Internet is more than sufficient. And last but not least, the REST API is finally included in the WordPress core, so it works out of the box.

Let’s get started!

Here’s an overview of how we’ll go about setting up a WordPress-based headless CMS:

Get a fresh WP installation and set it up. This part will not be covered but this tutorial explains it perfectly (scroll to “Installing WordPress” section). Use a blank theme that will just redirect to your static site. Fetch the data from WP REST API endpoints! As a bonus, we’ll add Advanced Custom Fields plugin for more, well, custom solutions.

Blank theme with a redirect

A theme in WordPress is the aforementioned third part of a traditional CMS — the part that actually displays the website.

In code, a theme is basically two files in a wp-content/themes/theme-name directory: an index.php file that is the root view, and style.css which — apart from being the stylesheet file — contains comments which inform WP about the theme name, author, etc.

The API will be available under a different URL than that of the main, static, website. I’d suggest placing it on a subdomain, like wp.mysite.com, just for clarity. But what happens when someone decides to visit the subdomain directly? Well, for that we’ll need a blank theme with redirection to the main page.

So, without further ado, here’s the index.php

And style.css :

Put these two files in wp-content/themes/blank directory (or name it however you want), then navigate to WordPress admin and activate this new theme. Now anybody visiting the WP site directly will get redirected to mysite.com . This solution leaves all the parts of WP that we need — like the admin panel, API endpoints, or media files URLs — intact.

Let’s get some data

On the front-end, our site will consume the API via AJAX requests. The simplest way of doing AJAX in JavaScript is XMLHttpRequest, but its usage is so messy that usually developers just go with something like jQuery’s .ajax() or superagent. However, there is also the Fetch API, a new standard for asynchronous data requests. The browser support is unfortunately not there yet, so we’ll use a polyfill — a piece of code that will create the fetch function if it’s not natively in the browser.

So here it goes, a full example:

For the whole documentation to the WP REST API, see the official docs. And keep in mind that the example above is written in ES6, so it may not work in some browsers without transpilation. But that’s a whole different topic.

Bonus — Advanced Custom Fields

Usually, you’ll need more than just title and content on a post object. For example, a client might ask for a location field in an event post. A great solution for creating custom post formats is the Advanced Custom Fields plugin.

The ACF interface in the admin panel is pretty straightforward — just create the fields you need and specify on which posts/pages they should be available.

In order to get the custom fields values in the API response, an additional plugin will be needed. It will just append the acf key to the post object returned from the API.

When not to use it

There are two major drawbacks to this approach. Firstly, the dynamic content might not be indexed by search engines. Secondly, if you ever want a piece of content from a headless CMS displayed on its dedicated page (say, site.com/posts/my-post), then that will probably require attaching the head to the CMS.

But for most cases on unsophisticated static websites, like an events calendar or a small announcements section, this approach will suffice.

If you enjoyed this post, please don’t forget to tap ❤! You can also follow us on Facebook, Twitter and LinkedIn.