I’ll be working on a new project over the next few months: a pro-bono website for a fantastic non-profit called “Cool Cars For Kids” (current site built with Wix) that connects classic car enthusiasts with families of children with birth defects through an annual car show to raise funds for research.
When I first started researching the tech options for this project, I was all gung-ho about the headless CMS approach. In a sentence, a “headless” CMS, a.k.a. “decoupled” CMS, is where your CMS handles data only, and front-end display happens completely separately. The worst part about working with WordPress is probably dealing with it as you develop the front end, so isn’t this the dream? I can hit the WordPress API to grab whatever data I need and build the front end completely PHP-free (which is what Timber allowed me to do!) and, finally, have a project where I can really use React worry-free.
Not so fast. Here’s a tweet of mine that sums up my hestitations:
My concern is that it's too far removed from the WP ecosystem – e.g. template hierarchy, URLs, Yoast, etc. A small site that doesn't directly benefit from being decoupled is just more prone to error and requires more maintenance. Have you run into that at all?
— Lara Schenck (@laras126) December 20, 2017
Brainless instead of Headless
I set out to do further research on how exactly people are building headless WordPress websites powered by the WordPress REST API and frameworks, and the ensuing pitfalls. In Ben Moore’s talk, Headless and Brainless WordPress, he brought up an interesting idea, the “Brainless” approach.
Rather than completely severing the connection between front end and back end, your front-end code still lives within WordPress, and WordPress acts as a wrapper so, in theory, you could still use things like previewing posts, URL routing, the Customizer, and plugin functionality. In page.php, for instance, you’d have something like this:
Awesome! Now I can do all my single page app loveliness and still take advantage of what WordPress gives me out of the box.
Once again…not so fast. I foresee a few major headaches here, first of all: lack of server-side rendering.
From my understanding, server-side rendering needs to happen in a node environment and is not terrible to set up, if you are using a framework like React or Vue. It’s probably possible to figure some way to do all that within WordPress with some custom node work and weird code injection, but I am not up to that task…at all.
Server-side rendering allows search engine bots to crawl rendered pages, and improves perceived page load times. More on that here.
Brainless example: Foxhound
I did some digging into Foxhound, a React-based WordPress theme on the repository built by Kelly Dwan. There’s a nice CSS-Tricks article about it, too. Overall, it’s a zippy and a well-designed experience, and how I wish I was able to write code like Kelly’s…getting there!
However, I have some concerns regarding performance. When auditing Foxhound on a local install with Chrome DevTools, on a “Fast 3G” connection the main page/post content – i.e. what is requested from the API and rendered with React – does not appear until about 8s, which is about 5s after the server-rendered content appears. That’s way too slow.
Besides server-side rendering, I believe the solution for this would be caching the large, and essential, app.js file for offline use with a service worker, or splitting up that file and loading scripts by prioritization. Unfortunately, at the time of this blog post service workers are not yet supported in iOS Safari, Edge or IE11, so that’s not an option quite yet.
Regarding the code splitting, I’m not sure how helpful that would be given how large React itself is, and it would be quite challenging to implement that type of loading in a fashion inline with WordPress standards.
So, I think I’ve ruled out the “brainless” approach, but if service workers were better supported I would definitely do some more digging.
Shoutout to Gatsby.js
Before I wrap this up, I want to give a shoutout to the up and coming Gatsby.js, a relatively new kid on a block. It’s a “bring your own data” approach to a static site generator. It’s server-side React and includes code splitting and service workers and other stuff, so that’s a solved problem. It uses GraphQL to query API requests, and from what I know of GraphQL after a recent meetup here in LA, is that it is really, really awesome and exciting and is the future.
What’s more, Gatsby.js has a ready-made source package for hooking up to the WordPress REST API. Plug and play! The WordPress portion could be hosted on an inexpensive shared server (or even WordPress.com), and the front end for free on Netlify.
If this was my personal site, I’d do it because I don’t care much about previewing posts and smart URL routes. But this is not my personal site, and I have too much to do to be wrangling with the task of building my own smart routing solution when WordPress already has one ready to go.
It comes down to this: I want to use WordPress because I think it is the right content management solution for this project and client. After I build the site, I want them to manage it on their own and I don’t want to be putting out fires or dealing with multiple server setup. It’s too many moving parts. Plus, as a developer, I ultimately care more about gaining experience developing with Gutenberg blocks and the Customizer than I do about learning React – I can do that on another project.
So, the head stays on!
- WordPress as a Headless CMS – Post Status Draft podcast. Excellent overview of the pros and cons from some WordPress experts.
- #204: With Matt Dennewitz and Jeff Eaton – Shoptalk Show podcast.
- Headless WordPress with React – Tutorial.
- Rebuilding My Portfolio Site With WordPress & Gatsby.js – account on the Gatsby.js blog.
- Postlight’s React + WordPress Starter Kit