This project is not covered by Drupal’s security advisory policy.
Write content as a stream of Drupal Canvas components, right in the regular edit form. Editors add text, images, quotes, fact boxes, live feeds and any other component your theme provides, nest them, reorder them and preview them in your site's design, without leaving the node form. The content is stored as a Canvas component tree, so Canvas renders it, JSON:API serves it as structured data, and it stays compatible with Canvas's own editor.

Features
Blocks that are easy to scan and move
Each block shows an open/close arrow, its icon, its type and, when collapsed, a one-line summary of what's in it. Move up, Move down, drag, Duplicate and Remove (with Undo) sit right in the block's header, and every button names itself on hover and keyboard focus. The editor's header counts blocks and words, shows the read time, and stays at the top of the window on long stories. Blocks can start open or collapsed, and on very long content a collapsed block's fields can load the first time it's opened.
A searchable chooser
The + between blocks opens a compact chooser: a search box over every component, grouped by Canvas folder, with Canvas Patterns at the end. The highlighted component's description shows at the bottom. Type to filter, use the arrow keys, press Enter to add. Typing / in an empty text block opens it in place, and a slot that takes only one kind of component adds it straight away.


Nested blocks on a dashed line
Components with slots (a live feed and its updates, a fact box and its rows, a hero and its buttons) hold their blocks on a dashed line. Only top-level blocks are drawn as cards, and the blocks inside them hang off the line, so even deep nesting stays narrow and easy to follow. The block you're working in gets dark lines, so you always know where you are. What a slot accepts, and how many, comes from core's SDC slot metadata (expected, minItems, maxItems).

Preview in your theme
Switch between Fields and Visual. Visual renders the content through Canvas in your site's default theme; click a block to edit it in place or in a side panel.

In Fields view, the live preview updates as you type. In Gin and Claro it's a Preview tab in the node form's sidebar, next to Settings, so the form keeps its full width. Buttons above it switch between mobile and desktop width and open the preview in its own window, and a line above it shows the moderation state the content will be saved in. Clicking a block in the preview opens it in the form. Without a sidebar, the preview appears beside the form.


Icons for every component
Each component shows an icon. A theme sets one in its component's .component.yml, from any core Icon API pack or as an SVG in the component's folder. The module ships a pack of line icons for common components. For themes you can't edit, pick icons under Configuration › Content authoring › Canvas Content Editor.
thirdPartySettings:
canvas_content_editor:
icon: 'canvas_content_editor:text'![]()
Starting values per content type
New blocks start with the content type's Starting values (for example a quote style or a text color made for the section your template puts the content on), and otherwise with the component's defaults for its required choices. Text, links and media start empty, so example copy never gets published by accident.

And on the page
The content renders through Canvas, in your theme, like any Canvas content.

How it compares
This module is for writing the story: a stack of components in the regular edit form, stored in one field. It doesn't lay out pages or displays, so it works alongside the tools that do.
- Paragraphs: editors see something similar, but every paragraph is its own entity with its own tables and revisions. Here, each block is one row in the node's field table. In our benchmark of the same 19-block story, saving was about 12 times faster, viewing about 3 times faster, and it used 2 tables instead of 24. Much of what Paragraphs adds through extra modules comes from Canvas here: Canvas Patterns are reusable groups of blocks, and settings like a quote's style are just component props, so there's nothing like Paragraphs behaviors to set up. What we don't have yet is a migration from Paragraphs or shared blocks that update everywhere they're used.
- Layout Paragraphs and Mercury Editor: both store content as paragraphs and are built for page layouts with sections and columns. Here, anything that needs columns is a component with slots.
- Gutenberg: stores the story as HTML with the block structure in comments, and its blocks are written in React. Here, every block is data (its component and its prop values), and the blocks are the same components the rest of your site uses: your theme's SDCs and any code components you've made in Canvas.
- Canvas's own editor: this module is built on Canvas, not instead of it. Canvas's editor is a full-screen page builder for landing pages. This module is for content types like articles, where writers stay in the normal edit form with the other fields, revisions and moderation. Both use the same components and store content the same way, so they work side by side on one site.
- Layout Builder and Display Builder: both lay out displays (and, with Display Builder, pages and Views), each in its own builder. This module edits a field you place in that layout.
- CKEditor 5 with embeds: the least setup, but quotes and fact boxes end up as markup in one big field. Here, CKEditor 5 is still used for the text, inside each Text block, and everything else is a real component.
Requirements
- Drupal 11.3 or later
- Drupal Canvas 1.12. Each new Canvas minor is tested before the module allows it.
- Media Library (core)
Getting started
- Install the module:
composer require 'drupal/canvas_content_editor:^1.0@alpha', then enable it. - Edit a content type and open Canvas Content Editor in the vertical tabs. Turn on Build content from components. Optionally keep only Body's summary, limit the allowed components, and set starting values.
- Print the field in your template (
{{ content.field_canvas_components }}) or leave it in the view display. If a Canvas Content Template displays the content type, as in Drupal CMS site templates, place the Content components block in the template instead.
Editor settings
Under Manage form display, the widget's settings choose, per form mode:
| Setting | Options |
|---|---|
| Opens in | Fields view, Visual view |
| Block style | Cards (each block of the content is a card), Lines (no cards; blocks hang off dashed lines) |
| In Visual view, edit a block | In place, In a side panel |
| Blocks start | Open, Collapsed |
| Load a collapsed block's fields | With the page (blocks open instantly), When it's first opened (a lighter edit form for very long content) |
| Live preview | Shown when the editor asks for it, Shown when the form opens, Off |
| Live preview appears | In a Preview tab in the sidebar, Beside the form |
| "/" opens the chooser | On, Off |
| Word count and read time | On, Off |
| Classes around the preview | The CSS classes of the area your content sits in, so previews get its background and spacing |
Accessibility
The editor is built and tested for WCAG 2.2 AA in Gin and Claro: everything works from the keyboard, the chooser is a combobox with a listbox, focus returns to the + that opened it, icon buttons name themselves on hover and focus (Esc hides the tooltip), and moving a block from the keyboard keeps focus on its controls.
Good to know
- Editors need the
use text format canvas_html_blockpermission for rich text props. - Canvas props can't be arrays of objects: use a slot with a child component (Fact box → Fact row) for repeating rows. Canvas's
canvas_html_blockformat has no headings, so model subheads as their own component. - While Canvas has unpublished changes for the same entity, the editor is locked, because publishing them would overwrite edits made here.
- The module uses some Canvas APIs marked
@internal, all in one class, so it allows only the Canvas minor versions it has been tested with. - Updates are safe to install: they never change saved content or how an existing site behaves until a site builder changes a setting. New defaults apply to new installs only, and release notes list anything to do.
- Automated tests (unit, kernel and browser tests) run in GitLab CI on every change.
- The full documentation is in the module's README.
| Attachment | Size |
|---|---|
| cce-2-chooser.png | 96.65 KB |
| cce-3-nested.png | 68.8 KB |
| cce-4-preview-side-panel.png | 321.33 KB |
| cce-5-live-preview.png | 133.73 KB |
| cce-5b-live-preview-desktop.png | 400.51 KB |
| cce-6-icons.png | 83.02 KB |
| cce-7-settings.png | 53.6 KB |
| cce-8-published.jpg | 536.32 KB |
Project information
- Project categories: Administration tools, Content editing experience
- Ecosystem: Drupal Canvas
- Created by jasonfelix on , updated
This project is not covered by the security advisory policy.
Use at your own risk! It may have publicly disclosed vulnerabilities.
Releases
First alpha: build content from Canvas components in the regular edit form.
Development version: 1.0.x-dev updated 7 Nov 2026 at 23:56 UTC


