It seems like hopping on Hacker Noon basically guarantees that you’ll leave with some sort of identity crisis or heightened case of imposter syndrome.

WTF? Shadow DOM? I thought I knew about HTML and CSS — if nothing else. What? People are hating on SASS now? When will it stop? Back up. What?

(I’m super excited about the Shadow DOM — but again, not the topic of this specific story. At the same time I also have some shadowy thoughts about the Shadow DOM — but I gotta concentrate. One thing at a time, Jim.)

The web moves fast and we all know that. But one part of the web hasn’t been moving as fast as everything else — the state of content management systems.

WordPress

At TRBL, we’ve got a lot of clients that know and love WordPress. They’re used to the admin interface, and let’s be honest with our jaded selves, if you weren’t a web developer and you just wanted to manage some content, the admin panel is pretty good. Especially when paired with Advanced Custom Fields.

We could try to recommend something else to spare ourselves from the sanity-robbing frontend development process inherent to WordPress, but what else would we even recommend? Craft? Yay, same thing, different syntax. Still no place for the newer build processes or techniques that are commonplace throughout the rest of the internet.

To a developer looking to build something with 2018 practices and benefits, most traditional CMS are all horse shit — just different flavors of horse shit. One horse just ate some hay, and one horse just ate some other horse’s shit. Who knows. Same thing, slightly different taste. Content gets coupled to the code that displays it through whatever templating system is being used and you gotta do things their monolithic, geriatric way.

It’s time to take the content out of the code. Give marketers an admin panel and give developers the freedom to build a site that won’t become unmanageable in 6 months.

Enter the idea of a headless WordPress.

TRBL is a huge proponent of the concept of a headless CMS, but unfortunately we aren’t big on the idea of paying someone else a monthly fee so that we can poll their APIs for our clients’ content. Most (if not all) widely-used and supported headless content management systems as of April 2018 unfortunately fall into this bucket. We want our projects built on open-source foundations and we want to host our own stuff.

Turns out as you probably know, a while back, WordPress integrated a REST API directly into its core. We’ve vetted it at TRBL through multiple production projects paired with a React client side, and although it’s not perfect, it does offer the ability to use WordPress as a headless CMS! Clients still get their familiar interface, and we get to build fast, maintainable web platforms that don’t remind us of Geocities. Props to WP here — hopefully they continue to see the light.

Not so fast, buddy

Firing up create-react-app and making some calls to the WP REST API isn’t really all that difficult in and of itself. It’s actually pretty satisfying to get everything all up and running.

But then — you share a link to your new fancy site in Slack and see no meta data.

Even if Google does render JS before caching results, we still have the problem of other search engines and services that don’t. Facebook itself doesn’t even render React code before caching pages when you go to share a link. Ironic? Kinda.

Outside of proper page scraping by the big birds out there, a few other drawbacks of simply serving a JS bundle to a client come to mind. I’m not going to go too deep into this because it’s been beaten to death elsewhere on the internet, but another potential drawback of simply serving the build folder from your fancy JS framework is the time delay added by first serving barebones HTML, then downloading a potentially large JS file, and then finally evaluating all that JS to get the results of your view.

If we want all sorts of 2018 web dev fanciness in 2018, we need to jump through some hoops. The hoops aren’t that difficult or that involved, but it gets tiring to wire up the same thing over and over again. That’s why we’ve done it for you.

TRBL’s SSR, Code-Split React + Redux + WordPress REST API Boilerplate

Why our own boilerplate?

In our quest for SSR knowledge, we’ve come across some far smarter people than we are doing similar things with server-side rendered React.

Next JS

From what we’ve seen playing with Next, it’s a beautiful concept. Declare all your API requests the Next way and they’ll run synchronously so you can return full HTML from your Node server. Voila, do whatever you want with React, render it and send it straight from the server, and have it pick up where the server left off on the client. Cool!

Postlight in NYC has built a React + WP boilerplate of their own that is absolutely amazing. It’s got some really cool features like using Robo to set up a headless WordPress installation for you with one command. They give you the full bird — a Next JS + headless WordPress setup right out of the box. It’s neat and we really look up to Postlight as a company.

But, there are a few things with Next JS that we aren’t particularly fond of yet at TRBL. Persisting components across routes is quite a bit more difficult than it should be and from what we have been able to tell, persisting kinda goes against the architecture of NextJS in general because the entirety of the top-level component re-renders every time a route changes.

For us, this negates some of the most important benefits of using a library like React. We love the idea of having components like the header persist (not re-render) between pages. We want to build nice page transitions that provide an extra layer of polish to a company’s image (and not fake them by cleverly hiding page reloads). When changing pages, or views, we want to only ask the server for what we need, rather than asking for the full HTML of a different page (which would be about 90% the same as the HTML we already have). Just seems backward.

It looks like Zeit is working on this but as of Apr 2018 an approach seems to still be in flux. Check here for more information.

Create React App + React Router

When we first started experimenting with Next, we were still learning the behind-the-scenes intricacies of React Router. Wait, weren’t we just beginning to get comfortable with how to route in React, the way that most people route in React? Now Next has its own way? Shoooooot. See back to the beginning of this story.

We’ve actually come to like React Router. At first, coming from an Angular background it was a bit bewildering, but now we want it to stick around for a while.

We also really like CRA. It’s got a lot of good stuff bundled in that makes building React apps much more efficient. Yes, we could write up our own Webpack setup and not even rely on CRA, but… been there, done that. We feel CRA is a good place to be OK with taking a shortcut.

The decision was made

Time to do some research and get to work. Over the years, much has been said about server-side rendering React apps, and lots of it can be pretty scary. But another super genius by the name of Andrei Duca wrote up a very helpful Medium story that outlines exactly how to get up and running with SSR and code splitting a React app:

Rather than rewriting his instructions and how they applied to our boilerplate, just check out his posts. It’s very worth the read and provided a lot of the hard work for our boilerplate.

API requests — run them on each render and wait, or cache them?

The super nice part about Redux on the server in our situation is that we can persist API calls within the Redux store, in memory.

We’ve chosen to architect our store with actions and a reducer that handles the loading of data needed per view, including meta needed by react-helmet . This data gets matched to a page, post or custom post type slug from WordPress, and this way, it can be stored and fetched very easily.

The first time a user hits a page — let’s say the home page — there will be nothing stored in Redux for that specific page’s slug. But, when our server-rendered React fires, it’ll make the API calls to WP, fetch the data for the view, and store it in Redux. On this first page load, the client will pull up a server-rendered HTML file, but the API call, being asynchronous, will not have returned by the time the HTML is sent from the server. For this first load, the client will be responsible for pulling the data from the API.

But, that API call made by the server will end up returning at some point, and when it does, it’ll store itself in the server’s memory (Redux store) for all following requests.

For now, we are not caching requests in any way other than in the Redux store because we view the entirety of our SSR efforts as just measures to decrease initial load time and create meta-filled, shareable HTML. If for some reason our Node server restarts, and some lucky winner hits a page for the first time without having been cached to memory prior, boo hoo. This isn’t life or death and the user’s client will still pull content, albeit 150ms slower.

That being said, it wouldn’t be hard to modify our server renderer in an effort to synchronously pull all necessary API requests before responding with the rendered HTML if that sorta thing sounds better to you.

Building routes