friendsoftypo3 / visual-editor
TYPO3 CMS Visual Editor - Brings a modern WYSIWYG editing experience to TYPO3 CMS.
Package info
github.com/FriendsOfTYPO3/visual_editor
Type:typo3-cms-extension
pkg:composer/friendsoftypo3/visual-editor
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- typo3/cms-backend: ^13.4.22 || ^14.3.0
- typo3/cms-core: ^13.4.22 || ^14.3.0
- typo3/cms-extbase: ^13.4.22 || ^14.3.0
- typo3/cms-fluid: ^13.4.22 || ^14.3.0
- typo3/cms-frontend: ^13.4.22 || ^14.3.0
- typo3/cms-rte-ckeditor: ^13.4.22 || ^14.3.0
Requires (Dev)
- b13/container: ^3.2.3
- phpunit/phpunit: ^11.5.55
- pluswerk/grumphp-config: ^10.2.7
- saschaegerer/phpstan-typo3: ^2.1.1 || ^3.0.1
- ssch/typo3-rector: ^3.14.1
- typo3/cms-install: ^13.4.28 || ^14.3.2
- typo3/cms-workspaces: ^13.4.28 || ^14.3.2
- typo3/testing-framework: ^9.5.0
- typo3fluid/fluid: ^4.6.1 || ^5.3.1
Suggests
- wapplersystems/multisite-belogin: You should install this extension, if you have multiple domains in your TYPO3 installation.
- dev-main
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.1
- 1.2.0
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.0
- dev-docs/editor-readme-section
- dev-docs/fluid-component-render-text
- dev-bugfix/load-rte-import-modules
- dev-docs/add-known-limitations
- dev-bugfix/disable-cache-in-edit-mode
This package is auto-updated.
Last update: 2026-06-03 10:44:56 UTC
README
Next Generation Frontend Editing for TYPO3 CMS.
This extension provides visual editing features for content elements in TYPO3 CMS.
Features
- โ๏ธ Inline editing it looks perfectly like the frontend output (WYSIWYG)
- ๐งฒ Drag-and-drop repositioning of content elements (โ adding and ๐๏ธ deleting elements)
- โก Real-time preview of changes without page reloads
- ๐ User-friendly interface for non-technical editors
- โฟ Accessibility-aware editing controls for TYPO3 editors
Editing.Made.Visual.mp4
Installation
- ๐ฆ
composer require friendsoftypo3/visual-editor(or install via ๐งฉ Extension Manager) - ๐งฑ Add
f:render.text,f:mark.contentAreato your templates (see below) - ๐งน Clear caches
- ๐ Start editing!
Useful links:
- Try the Demo Try the editor without any setup.
- ddev local demo setup test it locally
- fluid_styled_content addon automatic text editing for fluid_styled_content
- Example Commit How to integrate
f:render.text - Example Commit How to integrate
f:render.contentArea - Slack Channel ask questions
For editors
- ๐ Opening editable links: when editable text is inside a link, left click starts editing the text. To open the link instead, use the middle mouse button or Ctrl/Cmd + click.
- ๐พ Saving changes: use the save button. Autosave is available only when enabled, and the UI says to switch to a workspace if autosave is disabled.
- ๐ฆ Finding editable areas: use Spotlight to highlight editable text, rich text, images, and content elements.
- ๐ป Showing empty fields: use "show empty" when editable but currently empty fields are hard to see.
- โ๏ธ Moving content: drag content elements by their handle. Hold Ctrl while dropping to copy instead of moving.
Template Integration
visual_editor uses ViewHelpers in Fluid templates to mark the areas that should be editable.
In TYPO3 v14, the extension uses existing ViewHelpers in TYPO3 Core to hook into the rendering.
This means that the extension works out-of-the-box for the new theme "Camino" and also for
the default fluid_styled_content templates.
If you want to add visual editing to your own templates, you need to add some ViewHelpers to all locations that should be editable:
Text/RichText Fields
Replace the output of your texts with the f:render.text ViewHelper.
- record is already a Record object:
before: <f:if condition="{record.header}"> <h1>{record.header}</h1> </f:if> after: <f:variable name="header" value="{record -> f:render.text(field: 'header')}" /> <f:if condition="{header}"> <h1>{header}</h1> </f:if>
before: <h1>{record.header}</h1> after: <h1>{record -> f:render.text(field: 'header')}</h1>
If you do not have a Record object yet, you can create one with the record-transformation DataProcessors:
// add record dataProcessor for all content elements lib.contentElement.dataProcessing.1768551979 = record-transformation
Fluid components
When you use Fluid components, render the editable text outside the component and pass the rendered value into the component.
This keeps the component decoupled from records and TCA fields, and lets callers pass either a plain string or the result of f:render.text.
<my:component.card header="{record -> f:render.text(field: 'header')}" />
Inside the component, accept the argument as a string or stringable value:
<f:argument name="header" type="string|Stringable" />
ContentArea
ViewHelper f:render.contentArea (v14)
This newly introduced ViewHelper (v14) is the recommended way to render content areas in the TYPO3 in general.
Short description what you need to change in your templates:
before: <f:cObject typoscriptObjectPath="lib.dynamicContent" data="{colPos: '3'}"/> after: <f:render.contentArea contentArea="{content.main}" />
content.main here is automatically filled if you use PAGEVIEW and a BackendLayout with a column with an Identifier named main.
More information in the Official Documentation.
If you can not use the
f:render.contentAreaViewHelper, you can also use thef:mark.contentAreaViewHelper.
ViewHelper f:mark.contentArea (v13)
Use
f:render.contentAreaif possible!
Add the f:mark.contentArea ViewHelper to the Fluid template that renders your content elements.
search for:
f:cObject(typoscript rendering):before: <f:cObject typoscriptObjectPath="lib.dynamicContent" data="{colPos: '3'}"/> after: <f:mark.contentArea colPos="3"> <f:cObject typoscriptObjectPath="lib.dynamicContent" data="{colPos: '3'}"/> </f:mark.contentArea>
each="{children_(EXT:container):before: <f:for each="{children_201}" as="element"> {element.renderedContent -> f:format.raw()} </f:for> after: <f:mark.contentArea colPos="201" txContainerParent="{record.uid}"> <f:for each="{children_201}" as="element"> {element.renderedContent -> f:format.raw()} </f:for> </f:mark.contentArea>
v:content.render(EXT:vhs):before: <v:content.render column="0"/> after: <f:mark.contentArea colPos="0"> <v:content.render column="0"/> </f:mark.contentArea>
flux:content.render(EXT:flux):before: <flux:content.render area="column0"/> after: <f:mark.contentArea colPos="{data.uid}00"> <flux:content.render area="column0"/> </f:mark.contentArea>
Known limitations
- Wrapped content elements rendered with
f:render.contentAreaandrecordAsare not currently supported for drag-and-drop. In this setup, drag handles may disappear. Move the wrapping markup into the content element rendering instead of wrapping elements at thecontentArealevel. - Headless and non-Fluid setups are not first-class integration targets. Visual Editor relies heavily on Fluid ViewHelpers that wrap output in web components and load the required JavaScript, so robust headless integration would need a public API.
- Cross-domain headless setups are further limited because backend-module frame messaging does not work reliably across domains due to TYPO3 core limitations. General multi-domain setups are effectively excluded for this approach.
Multi Site/Domain Setup
You need to be Logged in to every Domain separately to use the Visual Editor.
OR you can use EXT:multisite_belogin it automatically logs you in to all sites/domains.
Rich Text Styling
Visual Editor uses your regular frontend CSS for the editing view. CSS that is configured only in the TYPO3 RTE configuration (contentsCss) is not applied there.
If your project defines custom rich-text styles, add the relevant rules to your frontend CSS so the page output and the editor share the same styling. Projects with custom lib.parseFunc_RTE setups may also need matching frontend rules.
Accessibility
Visual Editor is designed with WCAG 2.2 AA as a goal, but this is not a full compliance claim for every TYPO3 project.
The editor interface includes accessible labels, keyboard-focusable controls, validation announcements, and semantic roles. It has been tested with axe DevTools and NVDA.
Final accessibility depends on the project templates, CSS, semantic HTML, and editor-authored content. Drag-and-drop workflows are pointer-oriented, so projects should verify alternative workflows for their editor needs. Project-level accessibility should be checked in the integrated TYPO3 site.
License and Authors: License type, contributors, contact information
This extension is licensed under the GPL-2.0-or-later license.
with โฅ๏ธ from 
If something did not work ๐ฎ
or you appreciate this Extension ๐ฅฐ let us know.
We are always looking for great people to join our team!
https://www.andersundsehr.com/karriere/