Part 1 | Part 2 | Part 3 | Part 4 | Part 5 |

The question of where Drupal's front end is headed has led to much handwringing in the community, with a variety of ongoing discussions about whether decoupled Drupal (the subject of a recently released book and a yearly conference in New York City) is the future for Drupal's presentation layer. Out of all the debates in the community, few have engendered as much consternation and spilled ink as how, when, and whether to replace or augment Twig's functionality as the default theme engine for Drupal. The discussion raises many passions, because so many front-end developers have committed themselves to maintaining Twig themes and to monolithic Drupal architectures.

At DrupalCon Amsterdam, Fabian Franz (Senior Technical Architect and Performance Lead at Tag1 Consulting) presented a fascinating and futuristic session about the potential directions that Drupal's front end could take. In Fabian's conception of a prospective presentation layer for Drupal, gone are the critiques of Drupal as a woefully outdated solution for real-time and offline-enabled user experiences.

In this multi-part blog series, we inspect some of the ideas behind a future for the Drupal front end that revolves around Web Components, a solution with widening reach that could shake up the very foundations of how rendering occurs in Drupal. In this first installment, we consider some of the challenges we face today and the motivations for moving to a front end driven by Web Components.

Drupal's many challenges today

In kicking off his presentation, Fabian pinpoints a variety of significant challenges that Drupal faces today that could spell disaster for the continued promise of Drupal for years to come as a front-end solution. Among these are the inherent incompatibility of Node.js-driven server-side rendering with Drupal's own server-side rendering, the accelerating loss of Drupal's market share in the front-end development community, and the complexities introduced by decoupled Drupal architectures.

Drupal's incompatibility with Node.js server-side rendering

Fabian argues first and foremost that a solution that depends on Node.js server-side rendering is not the answer to Drupal's front-end issues, despite the fact that decoupled Drupal architectures are optimal for a variety of scenarios and use cases.

Indeed, compelling solutions for server-side rendering exist in the React and Vue ecosystems, but there is a significant issue for Drupal developers considering adopting one of these JavaScript technologies: Why mix two intrinsically incompatible languages, PHP and Node.js, rather than simply using a headless CMS solution or even a Node.js-based CMS? This is a question that many of us in the community are hearing with increasing frequency.

Drupal is losing market share and mindshare

Moreover, Fabian stresses that Drupal is beginning to lose critical market share as architects the world over begin to consider the positive implications of adopting decoupled CMS architectures rather than monolithic ones. For instance, Fabian works frequently with React developers who are newer to the web development landscape and who consider Drupal a relic "from the past" as opposed to a modern technology.

Much of this comes from misconceptions about Drupal. React developers are rightfully concerned about the security implications of storing HTML in the database, but they also are unaware that Drupal has solved issues like input and output sanitization since before React's very existence.

Decoupled Drupal isn't always the answer

Finally, one of the learnings that many decoupled Drupal practitioners now understand is that a decoupled Drupal architecture is not the correct approach for all scenarios, as I also note in my book Decoupled Drupal in Practice. After all, there are still significant benefits in building Drupal sites traditionally utilizing Drupal's page request model.

In the end, no Node.js or separate server-side rendering is even necessary when building traditional Drupal sites. Even with a majority of one's codebase written in PHP and a smattering of JavaScript sprinkled on top, we can build relatively interactive applications with relative ease in the Drupal community. As a matter of fact, many new experiments surrounding the use of JavaScript in Drupal's native front end have emerged in recent years.

Motivating Web Components in Drupal

After many years of halting and inadequate support, Web Components have finally gained steam in the wider web development community as an optimal solution for resolving the dual issues of componentization and encapsulation in the front-end landscape. For instance, at the most recent DrupalCon in Amsterdam, there was a proliferation of content about the subject, with a training, several conference sessions, and multiple birds-of-a-feather (BoF) all featuring the concept.

Nevertheless, Fabian argues that Web Components need to be in core in order for Drupal to realize the need to bridge the widening gap between the front end and back end. And one thing that Fabian, a seasoned core contributor to Drupal, contends is that only by targeting core can large-scale changes be made in the Drupal project. To illustrate this, Fabian cites the example of Twig; as a contributed module, it would likely never have seen the adoption it currently enjoys today.

Finally, Fabian also refers to his regret for the loss of momentum that the Theme Component Library initiative has suffered in recent years. After many discussions surrounding ideas for such a feature as a part of core, the initiative fizzled out as many contributors came to recognize that there was no inherent benefit to incorporating such a library in core. After all, Twig works perfectly well for the vast majority of Drupal theming use cases, and these experimental approaches would not be substantially distinct from the approaches we leverage today.

What are Web Components?

In short, Web Components are comprised of custom HTML elements. In other words, this means that developers can define custom HTML tags outside of the current range of available elements such as <menu-item> or <date-picker>. These HTML tags are defined using JavaScript, which allows for the document object model (DOM) in browsers to be extended. Web Components consist of three major parts: a template in HTML, scoped styles in CSS, and scoped JavaScript.

Web Components are configured using props and object attributes. For instance, the HTML element <menu-item ref="section-1"> is familiar to all web developers who work with HTML on a regular basis, simply with a custom element name and custom attributes. If we want to insert a new prop containing data into the component, we can simply extend the JavaScript object using code like the following:

menuItem.menuObject = {
  'title': 'foo',
  'color': 'red'
}

This approach allows us to insert additional data into the component, but it comes with certain disadvantages, as in Fabian's view, these should be represented within a data tree as opposed to as something akin to configuration.

Implementing "poor man's components"

With Drupal today, we can implement what Fabian calls a poor man's component by employing a Twig template and the Drupal behaviors system in Drupal 8. In Drupal, behaviors allow developers to define certain custom interface elements such as photo slideshows and to leverage certain best practices such as a generic configuration. As an example, an instance configuration for a photo slideshow might define the number of columns in the slideshow as three.

Thus, with this approach, we can house our HTML within a Twig template, utilize Drupal's native JavaScript behaviors (which are scoped and employ Drupal settings), adhering to the following pseudocode:

instanceConfiguration = general configuration, .once(), context

and CSS that is scoped using normal CSS inheritance by prepending the class of the desired componentized element (e.g. .menu-item) to the selector in question, though this is not ideal from the standpoint of true CSS scoping.

What is not a component?

Fabian stresses, however, that something like the following, which Drupal outputs currently as part of its rendering process, is not what we would today consider a properly encapsulated and scoped component:

<div class="page">
   <ul class="menu">
      <li class="menu-item">
        <a href="#section-1">
      </li>
   </ul>
   <div id="section-1">
     <h2>Section name</h2>
     <div class="content">
       Section content
     </div>
     </div>
   </div>
</div>

Instead, component trees are intended to be easy to read and legible even to developers who are less familiar with HTML elements:

<page>
  <menu>
    <menu-item ref="section-1" />
  </menu>
  <section ref="section-1" title="Section 1">
    <content>Section content</content>
  </section>
</page>

Many Drupal developers may question this markup by asking whether we cannot already realize this optimal markup already, thanks to Drupal's existing Render API and render tree. Though this is true, it is still distant from how many newer front-end frameworks handle render trees: namely, a virtual DOM.

Conclusion

As you can see, one of the most formidable challenges facing Drupal today is the lack of properly scoped and encapsulated components that allow for an exciting front-end future for Drupal to take shape with a real-time and offline-enabled presentation layer and true reactivity out of the box. This is in part due to the substantial obstacles facing Drupal today; a shrinking market share, an intrinsic incompatibility with Node.js-driven server-side rendering, and lessons learned from decoupled Drupal architectures.

In the next installment of this multi-part blog series, we devote our attention to how Drupal's history is in many ways just like the virtual DOM we see in many modern JavaScript frameworks, what could happen in future versions of Drupal, and a deep dive into how React and Vue achieve highly performant rendering and reactivity in one fell swoop.

Special thanks to Fabian Franz and Michael Meyers for their feedback during the writing process.

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 |


Photo by Anastasia Dulgier on Unsplash