January 30, 2019
A while ago I wrote about Decoupled, Headless and traditional CMS architecture. The post is about choosing which one is right for you. I wrote about the different architecture characteristics and the consequences it has. Knowing the differences will help you pick the right one for you. Based on that post you could think that you have to choose between Decoupled or Headless. But maybe there is more to choose from.
Recently we delivered a project with React and Drupal. The project required faceted search along with CMS capabilities. To meet the requirements we integrated Searchkit with Drupal. Searchkit is a suite of React components with an Elasticsearch back-end.
The faceted search is the main component but we ended up using other React components on the front-end.
We discovered that integrating Searchkit was relatively easy and it was actually quite nice to have this rich user experience of Searchkit and React components. Eventually we started to create more React components on the front-end and replicating that rich UI. On the other hand we did not want to lose the benefits of Drupal. We definitely wanted to benefit from Drupal’s front-end theming/rendering of the website structure like the main layout, navigation and user logins etc.
Knowing that we require CMS capabilities and want to benefit from Drupal’s theming we did not wanted an API-first or Headless approach. However we needed at least to decouple some of the things. We used Drupal’s webservices to build a few API’s and integrate with other applications. For the main layout and navigation structure we used Drupal theming and templates. Searchkit was hooked into a Drupal page template which was rendered from a Drupal page controller. The approach we took is actually called “progressively decoupled”. I believe it’s not a real industry standard. Dries wrote about it back in 2015 and I think he sort-off coined the term. There is even a flowchart that helps you decide the best approach in decoupling Drupal. Although Dries said “progressively decoupled” is the future or at least Drupal’s future, I believe it is more like a transition. I think in the current technology landscape with so many different devices the end goal is to have a full-featured pure API-first headless CMS. Today’s headless CMS-es are not as full-featured as CMS-es like Drupal. However Drupal is continually evolving to a decoupled architecture and is therefore an interesting choice.
React + Drupal integration
So how did we integrate React with Drupal? Let’s take a closer look. For this example I assume you have experience with both Drupal and React. If not read about it first or just skip this part.
The Component.js file basically contains the bootstrapping and rendering of a React component. It is what you expect from a common setup. Like the example below.
The next step is to provide data from Drupal in your React components. Assuming you want pass data from entities or configuration. You can use Drupal webservices to build a REST API and have your React component fetch data from that API. Initially we started with a couple of entities that we wanted to pass to React. So we simply encoded the entities in JSON and included that in our Twig template. It looks like this:
You can also use drupalSettings to pass your values. Now it’s just a matter of reading the variable in you React component. Obviously you can improve the bootstrapping a bit and inject the data as props or state into you React component.
Eventually we created React components that were used as FieldWidgets in Drupal’s admin pages. We re-used the components in the Drupal admin to enable configuring the component and show the real-time updated preview.
Progressively decoupled is maybe not the most purest form of architecture and actually adds coupling. It is however a cost effective and pragmatic approach which brings a lot of opportunities. It enables your creativity to create rich UI components integrated in your favorite CMS. On the other hand it is just a pragmatic approach until the Headless CMS-es ecosystem has matured. Nevertheless, it has proven to us to be successful and we will definitely keep using it in future projects.
By sharing this example I hope I have triggered your creativity to improve your projects. If you have any questions or feedback, please contact me!