Drupal: Layout Builder
|
This content was generated with the assistance of AI and should be verified against the official Drupal documentation before being relied on in production. This sub-section’s Drupal bibliography lists the reference material consulted while preparing these pages. |
Layout Builder is the core module that lets a site builder or editor arrange fields and blocks visually, either once for every item of a content type or separately for one item. This page explains the two storage modes (layout defaults and per-entity overrides), the model of sections, layouts, regions and components, inline blocks, the Layout Discovery module that supplies the layouts, the permissions, a custom layout for the museum, the trade-offs with revisions, translations and storage, and its status next to Drupal Canvas.
It was written against Drupal 11.4.x, with Drush 13 or 14 and PHP 8.3 or later, and checked against the official
documentation on 2026-10-30. The running example is the Meridian Museum: an exhibition content type whose full
display gets a hero, a gallery and a sidebar with opening hours, and a single exhibition that needs a one-off
"Closing weekend" banner. Drupal 12.0.0 is scheduled for the week of 2026-12-07 and the end of life of Drupal 10 for
2026-12-09, so both are described as upcoming.
What Layout Builder is and who uses it
Layout Builder replaces, for the displays where it is enabled, the "Manage display" field list with a drag-and-drop canvas. The official overview describes it as a tool for two jobs: building a template for every item of a content type (the defaults), and customising that template for one item (an override). It is not turned on by default.
-
Editors use the Layout tab of an item to rearrange one page.
-
Site builders enable it per display and design the defaults.
-
Administrators decide who may configure layouts (see the permissions section).
-
Themers style the layouts and the regions.
-
Developers write custom layouts, restrict the blocks and layouts offered, and react to the events.
Layout Builder works on any fieldable entity type, not only nodes: user profiles, taxonomy terms (see
Taxonomy) and the custom collection_object entity of meridian_collection can all use
it. It builds on view modes, so read Display modes and image styles
and Content types and fields first.
The model: sections, layouts, regions and components
-
A section is one row of the page. It has a layout, optional layout settings and a list of components.
-
A layout is a plugin (for example
layout_onecol,layout_twocol_section) that defines named regions and a template. Core ships one-, two-, three- and four-column layouts through the Layout Discovery module. -
A component (
Drupal\layout_builder\SectionComponent) is one placed block in one region, with a weight and its own configuration. Fields are placed as field blocks, for examplefield_block:node:exhibition:field_gallery, so a layout can show a field, a block plugin (see Blocks and block layout), an extra field such as Links, or an inline block. -
The list of sections is a
Drupal\layout_builder\Sectionobject list handled throughSectionListInterface.
The sections are rendered by the entity view builder, so Layout Builder output goes through the normal render pipeline and its cache metadata (see Render API and cache metadata).
Layout defaults per bundle
Defaults live in the entity view display configuration entity, so they are exported with the code and deployed through configuration management (see Configuration management).
-
Enable the module (it depends on
layout_discovery,contextualandblock). -
Open Structure > Content types > Exhibition > Manage display, pick the view mode (here Default), tick Use Layout Builder and optionally Allow each content item to have its layout customized.
-
Save, then press Manage layout. The same screen offers Add section, Add block and the contextual links on each component to configure or remove it.
-
Press Save layout. Editing a default layout does not change items that already have an override.
ddev drush pm:install layout_builder
ddev drush config:get core.entity_view_display.node.exhibition.default third_party_settings.layout_builder
Each view mode of each bundle chooses on its own. The Layout Builder settings and the section list are stored under
third_party_settings.layout_builder of the display, as in this abridged export:
# config/sync/core.entity_view_display.node.exhibition.default.yml (abridged)
langcode: en
status: true
dependencies:
module:
- layout_builder
- layout_discovery
third_party_settings:
layout_builder:
enabled: true
allow_custom: true
sections:
-
layout_id: layout_onecol
layout_settings:
label: Hero
components:
0a1b2c3d-0000-4000-8000-000000000001:
uuid: 0a1b2c3d-0000-4000-8000-000000000001
region: content
configuration:
id: 'field_block:node:exhibition:title'
label_display: '0'
formatter:
type: string
weight: 0
additional: { }
third_party_settings: { }
id: node.exhibition.default
targetEntityType: node
bundle: exhibition
mode: default
The keys enabled and allow_custom are the two checkboxes above. Because the sections are inside the display, a
default layout is a normal configuration change: review it in a pull request, import it on staging and do not edit it
on production.
Per-entity overrides
When Allow each content item to have its layout customized is on, every item of the bundle gets a Layout tab. Saving
there stores a copy of the sections in the layout_builder__layout field of that item (field type layout_section).
Two buttons manage the override: Discard changes drops unsaved edits, and Revert to defaults deletes the override so
the item follows the bundle default again. An overridden item is not affected by later changes to the default layout;
reverting returns it to whatever the default is at that time.
Internally the work is done by two section storage plugins, selected from the route by the section storage manager:
-
defaults(DefaultsSectionStorage) edits the sections inside the view display configuration; -
overrides(OverridesSectionStorage) edits the field value of one entity. The attribute has anallow_inline_blocksflag, so a storage type can hide the inline block creation link.
Both implement SectionStorageInterface, and the override variant also implements OverridesSectionStorageInterface.
Developers can read the layout of an entity without the UI:
<?php
use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
if ($node->hasField(OverridesSectionStorage::FIELD_NAME) && !$node->get(OverridesSectionStorage::FIELD_NAME)->isEmpty()) {
/** @var \Drupal\layout_builder\Section[] $sections */
$sections = array_map(
static fn ($item) => $item->section,
iterator_to_array($node->get(OverridesSectionStorage::FIELD_NAME)),
);
}
Source: Namespace Drupal\layout_builder
The \Drupal:: call is acceptable in a snippet or a procedural script; in a class, inject entity_type.manager (see
Services and dependency injection).
Inline blocks
An inline block is a one-off block created inside the layout instead of being placed from the block library. Core
stores it as a block_content entity that is not reusable, and the inline_block_usage table (service
InlineBlockUsage) records which layout entity owns it. Inline blocks use the block types of the Block Content module
(see Blocks and block layout): the "Closing weekend" banner can be a
basic block type with a body field, created from Add block > Create content block.
Points that matter in practice:
-
Inline blocks are revisioned together with the layout entity, so an editor going back to an older revision of the exhibition sees the banner text of that revision. The usage record and the
InlineBlockEntityOperationsservice remove the blocks that are no longer referenced. -
The permission Create and edit custom blocks is needed to create them (before it was split off, Configure any layout gave this access).
-
Inline block content is data in the database, not configuration. A banner created in a default layout is part of the exported display and is cloned into each use; a banner created in an override stays on that item and is not deployed with the configuration.
-
Content imported with a default-content tool may not populate
inline_block_usage, which makes inline blocks look orphaned; check the tool before migrating layouts. -
Searching and the Search API only see what the entity’s search display renders, so decide whether the layout display should be indexed (see Search and Search API).
Layout Discovery and custom layouts
Layout Discovery (layout_discovery) is a separate, stable core module that provides the Layout API: the plugin type
plugin.manager.core.layout, the base class Drupal\Core\Layout\LayoutDefault and the Twig layout theme hook. Layout
Builder is one consumer; other modules, such as Panels, use the same plugins. The module’s own layouts are
layout_onecol, layout_twocol, layout_twocol_section, layout_threecol_section and layout_fourcol_section.
A module or theme registers layouts in <name>.layouts.yml. For the museum, meridian_collection offers a "Gallery
with sidebar" layout:
# meridian_collection/meridian_collection.layouts.yml
meridian_gallery_sidebar:
label: 'Gallery with sidebar'
category: 'Meridian'
path: layouts/gallery_sidebar
template: layout--gallery-sidebar
library: meridian_collection/layout_gallery_sidebar
default_region: main
icon_map:
- [main, main, sidebar]
regions:
main:
label: Main
sidebar:
label: Sidebar
The template lives at layouts/gallery_sidebar/layout--gallery-sidebar.html.twig. Each region is available as
content.<region> and the attributes of a region as region_attributes.<region>:
{% if content %}
<div{{ attributes.addClass('layout', 'layout--gallery-sidebar') }}>
{% if content.main %}
<div{{ region_attributes.main.addClass('layout__region', 'layout__region--main') }}>
{{ content.main }}
</div>
{% endif %}
{% if content.sidebar %}
<aside{{ region_attributes.sidebar.addClass('layout__region', 'layout__region--sidebar') }}>
{{ content.sidebar }}
</aside>
{% endif %}
</div>
{% endif %}
Source: Layout API
The library is declared in the usual meridian_collection.libraries.yml and is attached automatically when the layout is
rendered:
layout_gallery_sidebar:
css:
theme:
layouts/gallery_sidebar/gallery-sidebar.css: {}
When a layout needs a setting (for example a column ratio), set class to your own subclass of LayoutDefault
and implement defaultConfiguration(), buildConfigurationForm() and submitConfigurationForm(). Layouts can also be
defined with the Drupal\Core\Layout\Attribute\Layout PHP attribute (see
Plugin API and attributes); the attribute is available in Drupal 10 and
later, and a layout without a label or a deriver triggers a deprecation notice that becomes mandatory in
Drupal 12.0.0.
Layout Builder adds its own CSS on top of the front-end theme, and the editing UI is rendered in the admin theme or the
default theme depending on the layout_builder settings, so check both when a layout looks wrong. Layouts
declared in a theme must be reachable by the theme’s library definitions, and a Single Directory Component can be
rendered inside the template (see Single Directory Components).
Restricting what editors can place
By default every block plugin and every layout can be added. The plugin filter hooks narrow the lists. With OOP hooks (see Hooks and OOP hooks):
<?php
declare(strict_types=1);
namespace Drupal\meridian_collection\Hook;
use Drupal\Core\Hook\Attribute\Hook;
/**
* Limits what editors can place in Layout Builder.
*/
final class LayoutBuilderHooks {
/**
* Offers only the museum layouts and a short list of blocks.
*/
#[Hook('plugin_filter_layout__layout_builder_alter')]
public function filterLayouts(array &$definitions, array $extra): void {
$allowed = ['layout_onecol', 'layout_twocol_section', 'meridian_gallery_sidebar'];
$definitions = array_intersect_key($definitions, array_flip($allowed));
}
/**
* Removes the administrative blocks from the block list.
*/
#[Hook('plugin_filter_block__layout_builder_alter')]
public function filterBlocks(array &$definitions, array $extra): void {
foreach (array_keys($definitions) as $plugin_id) {
if (str_starts_with($plugin_id, 'system_menu_block:admin')) {
unset($definitions[$plugin_id]);
}
}
}
}
Source: layout_builder.api.php
The hook class goes in src/Hook, as for any OOP hook from Drupal 11.1. Core also dispatches events from
LayoutBuilderEvents, for example to alter the render array of a component or to prepare a layout, which a subscriber
can use to add cache contexts or attributes (see Events and subscribers).
Permissions and security
Layout Builder concentrates a lot of power in one tab, so the permissions deserve care (see Users, roles and permissions):
-
Layout defaults need Configure any layout (Layout Builder) and Administer display for the entity type (Field UI). Give them to site builders only, because defaults can show any field and any block to anonymous visitors.
-
Layout overrides use per-bundle permissions: configure all layout overrides of a bundle, or configure the overrides of content items the user can edit. The second one keeps an author to their own items.
-
Inline blocks need Create and edit custom blocks.
-
Editing is impractical without the Contextual Links module and the permission Use contextual links.
-
Contrib modules such as Layout Builder Permissions and Layout Builder Advanced Permissions refine the core set. The official permissions page is marked as needing review, so verify names on your own site (People > Permissions).
Security implications:
-
Layout Builder can place any field of the entity, including fields hidden from the default display, and can place blocks whose own access checks decide visibility. A user who may configure overrides should be trusted with that content.
-
A formatted-text inline block is filtered by its text format like any other field, so give layout editors a restricted format (see Text formats and CKEditor 5).
-
Block access and cache contexts still apply per component, but a mistake such as caching a personalised block without the
usercontext is easier to make in a layout. See Performance and caching.
Trade-offs: revisions, translations and storage
-
Revisions. An override is a field value, so it is stored with the entity revision, and inline blocks are revisioned together with it. This works well with Content Moderation (see Content moderation, workflows and revisions): a draft layout can be reviewed before publishing. The official permissions example notes that a layout editor needs an existing published revision to reach the Layout tab on moderated content, so test the workflow with each role. Default layouts are configuration and have no revisions beyond version control.
-
Translations. The layout field is not translatable, so one override applies to every translation. The documentation states that translation-specific layouts are not supported. Translate the content of the placed fields and blocks instead, and make the layout field non-translatable on each bundle with overrides enabled (see Multilingual). Inline blocks themselves are shared too, so a banner in the override has one text for English and Spanish unless it is built from translatable fields of the node.
-
Storage and size. Each override copies the whole section list into the database, so a later change to the default does not reach overridden items, and a large site can accumulate hundreds of divergent pages. Prefer defaults and use overrides sparingly; use a field-based design (Paragraphs or a plain content type) when pages must stay uniform.
-
Performance. Every component is rendered separately and carries its own cache metadata; many blocks and views per page raise the cost. The render and caching pages cover tags, contexts and BigPipe.
-
Editing experience. The UI is powerful but easy to misuse. Layouts are not validated for accessibility; heading order and landmark roles depend on what editors place (see Accessibility and performance in themes).
-
Workspaces. Check the interaction with the Workspaces module before combining it with heavy use of inline blocks (see Workspaces).
Common errors and pitfalls
-
Enabling Use Layout Builder on a display that already has editors' changes in Manage display resets the field list; the fields become components and the old region settings are lost.
-
Turning on Allow each content item to have its layout customized after items exist does not change those items; they keep following the default until someone saves an override.
-
Disabling Layout Builder on a display with overrides is blocked until the overrides are removed, because deleting the field would delete the layouts.
-
A new field added to the content type later is not shown on pages that follow a default layout until it is placed in the layout, and never appears on overridden items unless each override is edited.
-
Overrides in a default-content or migration import need their inline blocks and the usage table, not only the node.
-
Editing layouts on production creates configuration drift; export the display after each change to the defaults.
-
Using Layout Builder as the whole site layout (header, footer, sidebars) mixes concerns with Block layout. Keep site-wide regions in the theme and use Layout Builder for the content area.
Layout Builder, Canvas and what changed in recent versions
Drupal Canvas (formerly Experience Builder) is a contrib page builder that is the default editor of Drupal CMS 2 (see Canvas visual page building and Drupal CMS and site templates). The status as of 2026-10-30:
-
Layout Builder remains in Drupal core in 11.4 and is fully supported on core sites. Drupal CMS 2.0 had no automatic migration from Layout Builder or Paragraphs to Canvas. The Canvas Migration Initiative presents migration approaches at conferences, but no official one-click path is documented on drupal.org; re-check before planning a move.
-
A core discussion covers the overlap between Block layout, Layout Builder and Canvas, including proposals to move parts of Layout Builder to contrib. It is not an approved removal, so do not remove Layout Builder from a working site on that basis.
-
Field Layout is removed from core in Drupal 12 (moved to contrib, as are Ban, Contact, History, Search, Settings Tray, Shortcut, Telephone and Toolbar). Layout Builder does not depend on it, but a display that uses Field Layout needs the contrib
field_layoutproject, or a conversion to Layout Builder, before upgrading. See Preparing for Drupal 12 and Removed core modules and replacements. -
The Layout API class
Drupal\Core\Layout\Attribute\Layoutrequires alabelor a deriver from Drupal 12.0.0. -
Third-party Layout Builder extensions (for example Layout Builder Additions) release Drupal 12-compatible versions on their own schedule; check each one before upgrading.
Choosing between the tools (see Comparison and decision guide):
| Need | Layout Builder fits when | Prefer something else when |
|---|---|---|
Uniform templates for a content type |
The layout is a template shared by all items and designers work in configuration. |
Plain "Manage display" and a theme template are enough. |
One-off landing pages |
Editors need drag-and-drop on a few pages and accept untranslated layouts. |
Pages must be translated per language or reused across sites; consider Canvas or Paragraphs. |
Structured, reusable content |
Almost never; layouts mix presentation with content. |
Paragraphs, referenced content or Views keep content reusable. |
New Drupal CMS 2 site |
Existing Layout Builder knowledge or contrib modules are required. |
Canvas is the default editor and has component-level tooling. |
Older books such as Drupal 10 Development Cookbook (2023) present Layout Builder as the standard way to build flexible pages and teach it with Drupal 10 screens, and Drupal 10 Masterclass (2023) treats it as the only visual builder. Both predate Canvas and Drupal CMS 2, where Canvas is the default; Layout Builder is still in core, but it is no longer the only choice. Tutorials may also show Field Layout as a core module; it is removed in Drupal 12.
Version notes
-
Layout Builder was experimental in Drupal 8.5 and stable in 8.7.
-
The translation behaviour above was set in 8.7.0; configurations from earlier experimental installs may need the non-translatable setting applied manually.
-
The Layout API attribute replaces annotations for new code from Drupal 10; annotations still work but are on a deprecation path.
-
The permission to create inline blocks was split from Configure any layout into Create and edit custom blocks.
-
Drupal 11.4 does not create the Article and Page content types in the Standard install, so create the
exhibitiontype first and then enable Layout Builder for it.