Skip to main content

Layout Builder Nirvana

Igor Lakic

This is an article about a topic I wanted to write about for at least a year. Like they say, better even than never, right?! ;)

One important note at the beginning: this article is not intended to be one of the articles that are going to talk about Layout Builder vs. Paragraphs vs. [You name some other module]. If you already have a preferred approach with some other Drupal module, please feel free to continue using it. There are a lot of possible solutions and strategies out there and everyone can find and use one that suits the best needs of project, client or team of developers that are working on the particular project.


As you, or most of you, already know, Layout Builder is an amazing tool for content editing. It has endless potential. But like with most things in the world of Drupal, things can get messy quickly, and you can end up with a situation in which clients have too much “creative freedom”. And that can negatively affect the initial design, representation of the content, which then becomes a huge issue for everyone related.

The original idea behind Layout Builder was to have all required components, that are going to be used on a project, available everywhere on that project. Because that would simplify the use of those components and make the life of developers, agencies and clients a lot easier, right?
Well, to answer quickly – nope! :) That’s not the case.

And that’s simply because clients usually just want to add some components on the page they are editing and be done with it. They don’t want to think too much about which component would fit best inside which layout and things like that. And who can blame them?! User experience should be straight-forward and intuitive.


So rather than enabling all components available in almost every Layout Builder layout, I did something different.

I tried another approach which proved to be intuitive for the clients/editors, clean for site builders and developers, and much safer environment which is less prone to user errors. And safer in a way, because you don’t need to fear too much if some Layout Builder block/component is going to be used in a place that is not supposed to be used for that particular purpose.

Especially, developers are going to love this approach - they will have an easier task to maintain projects that utilize this approach because of the cleaner, better-structured codebase.

My idea was to create Layout Builder layouts for any more complex component and then enable needed blocks inside.

When I was creating this new approach, I was inspired by Atomic Design principles and Pattern Lab themes, with which I worked in the past a lot.

Atomic design grouped all components into Atoms, Molecules, Organisms, Templates and Pages. And there was a good reason for that – so that components keep styles for visual representations (Atoms and Molecules) while the layout of components is controlled from the higher level components (usually Organisms and Templates). That way, we get components that are highly re-usable, we don’t have a need for a lot of repetitive work. DRY principle is always more than welcome.

The logical companion of such component-based themes in the Drupal world was Paragraph module. In that way, we had paragraphs which represented components, but we also had paragraphs which were basically wrappers around the components. In that way we had a control over components, and we could configure which components are going to be available in which wrapper paragraph.

That approach was pretty powerful yet safe for the end client.

Introduction of the Layout Builder was a big thing. Simpler and more modern way of adding content inside Drupal. But with a lot of power comes great responsibility. And that’s especially true if you try to enable all possible components in the project everywhere, in all layouts. Or even worse, if you have only 1 or 2 general layouts, like “Full width” and “One Column” layouts.

I have seen projects using this approach, and each of these projects was a nightmare on its own.

End users are not satisfied with the end result, because, they need to be careful when placing components. Code is bloated with a lot of unnecessary CSS etc.

The solution is fairly simple – let's create components which are flexible but limited to be used only on specific layouts. From an Atomic design standpoint, this is like when we are adding Atoms and Molecules into Organisms, where block types/components are Atoms and Molecules and Layout Builder layouts are Organisms. This way, we can still continue using components on multiple different layouts, but we are also safe they are never be used in the “wrong” layouts, or places on the project where they are not supposed to be used in the first place.

So for example, if we have some kind of wall of cards, which consists from a title on the top, cards in the middle, we should create a layout for it first, let's call it "Simple Cards". That layout is going to have, in this case, 2 different regions: Title and Cards regions.

After that, we are going to create all the needed block types. In this case, we need block type for Title and Card. And some of them, like Title block type in this case, we are going to be able to re-use for other components too, so like I already wrote, less repeating and component variations. Because the layout of those components can be controlled from the Layout Builder layout level.

We can also restrict easily with plain CSS how many of these blocks we want in a particular region of the Layout Builder layout.

All these Layout Builder layouts are going to be enabled per content types. There’s no point in enabling them all in all content types that have Layout Builder enabled. And of course, there’s no point in enabling all block types in global/general layouts like “One column layout” and similar ones. Because that was a source of troubles in the first place.

To accomplish everything briefly described above, we are going to use some contributed Drupal modules alongside the Layout Builder module, which is in the Drupal core. The following contributed modules are needed: layout_options, layout_options_ui, layout_builder_restrictions, layout_builder_restrictions_by_region. I usually also use: layout_builder_modal, layout_builder_lock.


But because it’s a lot easier to explain while showing an example, I prepared a short video recording. You will be able to take a look at those files that needs to be customized correctly on a Github repo.

I hope you are going to enjoy this approach.

Until next time. :)