RootConfig
Configuration for an editor root. It is used in EditorConfig#root and EditorConfig#roots.<rootName>.
For a typical single-root editor (Classic, Inline, Balloon, Decoupled), use config.root to set the root configuration. For the multi-root editor, use config.roots to define configuration for each root.
// Classic editor – the source element is set via `config.attachTo`.
ClassicEditor.create( {
attachTo: document.querySelector( '#editor' ),
root: {
initialData: '<p>Hello world!</p>',
placeholder: 'Type some text...',
label: 'Article main content'
}
} );
// Inline editor – the source element is set via `root.element`.
InlineEditor.create( {
root: {
element: document.querySelector( '#editor' ),
initialData: '<p>Hello world!</p>',
placeholder: 'Type some text...',
label: 'Article main content'
}
} );
// Multi-root editor – each root is configured separately via `config.roots`.
MultiRootEditor.create( {
roots: {
header: {
element: document.querySelector( '#header' ),
placeholder: 'Type header...',
label: 'Article header'
},
content: {
element: document.querySelector( '#content' ),
placeholder: 'Type content...',
label: 'Article main content'
}
}
} );
Properties
element : HTMLElement | undefinedmodule:core/editor/editorconfig~RootConfig#elementThe DOM element that will be the source for the created editor root (on which the editor root will be initialized).
If a DOM element is passed, its content will be automatically loaded to the editor upon initialization (but only when
initialDatais not set).The editor data will be set back to the original element once the editor is destroyed only if the updateSourceElementOnDestroy option is set to
true.If this config property is not set, a detached editor will be created. In this case you need to insert it into the DOM manually.
initialData : string | undefinedmodule:core/editor/editorconfig~RootConfig#initialDataThe initial editor data to be used instead of the HTML content of the source element.
ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), root: { initialData: '<h2>Initial data</h2><p>Foo bar.</p>' } } ) .then( ... ) .catch( ... );Copy codeBy default, the editor is initialized with the content of the source element on which this editor root is initialized. This configuration option lets you override this behavior and pass different initial data. It is especially useful if it is difficult for your integration to put the data inside the HTML element.
If your editor implementation uses multiple roots, you should provide config for roots individually:
MultiRootEditor.create( { roots: { header: { element: document.querySelector( '#header' ), initialData: '<p>Content for header part.</p>' }, content: { element: document.querySelector( '#content' ), initialData: '<p>Content for main part.</p>' }, leftSide: { element: document.querySelector( '#left-side' ), initialData: '<p>Content for left-side box.</p>' }, rightSide: { element: document.querySelector( '#right-side' ), initialData: '<p>Content for right-side box.</p>' } } } ) .then( ... ) .catch( ... );Copy codeSee also Editor.create() documentation for the editor implementation which you use.
label : string | undefinedmodule:core/editor/editorconfig~RootConfig#labelLabel which briefly describes this editing area.
It is used for the
aria-labelattribute set on the editor editing area, helping assistive technologies to tell apart multiple editor instances (editing areas) on the page. If not set, a default "Rich Text Editor. Editing area [name of the area]" is used instead.It can also be used by other features when referring to this editing area (e.g. AI features).
ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), root: { label: 'Article main content' } } ) .then( ... ) .catch( ... );Copy codeIf your editor implementation uses multiple roots, you should provide config for roots individually:
MultiRootEditor.create( { roots: { header: { element: document.querySelector( '#header' ), label: 'Article header' }, content: { element: document.querySelector( '#content' ), label: 'Article main content' }, sideQuote: { element: document.querySelector( '#side-quote' ), label: 'Side-quote' }, relatedLinks: { element: document.querySelector( '#related-links' ), label: 'Related links' } } } ) .then( ... ) .catch( ... );Copy codelazyLoad : boolean | undefineddeprecatedmodule:core/editor/editorconfig~RootConfig#lazyLoadFlag for the root that exist in the document but is not initially loaded by the editor.
This property has been deprecated and will be removed in the future versions of CKEditor.
Note: This configuration option is supported only by the multi-root editor type.
Important! Lazy roots loading is an experimental feature. Be advised of the following known limitations:
- Real-time collaboration integrations that use uploaded editor bundles are not supported. Using lazy roots will lead to unexpected behavior and data loss.
- Revision history feature will read and process the whole document on editor initialization, possibly defeating the purpose of using the lazy roots loading. Additionally, when the document is loaded for the first time, all roots need to be loaded, to make sure that the initial revision data includes all roots. Otherwise, you may experience data loss.
- Multiple features, that require full document data to be loaded, will produce incorrect or confusing results if not all roots are loaded. These include: bookmarks, find and replace, word count, pagination, document exports, document outline, and table of contents.
These roots can be loaded at any time after the editor has been initialized, using
MultiRootEditor#lazyRoot().This is useful for handling big documents that contain hundreds of roots, or contain very large roots, which may have impact editor performance if loaded all at once.
modelAttributes : RootAttributes | undefinedmodule:core/editor/editorconfig~RootConfig#modelAttributesInitial root attributes for a root.
Note: This configuration option is supported only by the multi-root editor type.
Note: You must provide full set of attributes for each root. If an attribute is not set on a root, set the value to
null. Only provided attribute keys will be returned bygetRootsAttributes.Roots attributes hold additional data related to the document roots, in addition to the regular document data (which usually is HTML). In roots attributes, for each root, you can store arbitrary key-value pairs with attributes connected with that root. Use it to store any custom data that is specific to your integration or custom features.
Currently, any official plugins do not use root attributes. This is a mechanism that is prepared for custom features and non-standard integrations. If you do not provide any custom feature that would use root attributes, you do not need to handle (save and load) this property.
MultiRootEditor.create( // Roots for the editor: { uid1: document.querySelector( '#uid1' ), uid2: document.querySelector( '#uid2' ), uid3: document.querySelector( '#uid3' ), uid4: document.querySelector( '#uid4' ) }, // Config: { roots: { uid1: { modelAttributes: { order: 20, isLocked: false } // Third, unlocked. }, uid2: { modelAttributes: { order: 10, isLocked: true } // Second, locked. }, uid3: { modelAttributes: { order: 30, isLocked: true } // Fourth, locked. }, uid4: { modelAttributes: { order: 0, isLocked: false } // First, unlocked. } } } ) .then( ... ) .catch( ... );Copy codeNote, that the above code snippet is only an example. You need to implement your own features that will use these attributes.
Roots attributes can be changed the same way as attributes set on other model nodes:
editor.model.change( writer => { const root = editor.model.getRoot( 'uid3' ); writer.setAttribute( 'order', 40, root ); } );Copy codeYou can react to root attributes changes by listening to document
change:dataevent:editor.model.document.on( 'change:data', () => { const changedRoots = editor.model.document.differ.getChangedRoots(); for ( const change of changedRoots ) { if ( change.attributes ) { const root = editor.model.getRoot( change.name ); // ... } } } );Copy codeplaceholder : string | undefinedmodule:core/editor/editorconfig~RootConfig#placeholderSpecifies the text displayed in the editor when there is no content (editor is empty). It is intended to help users locate the editor in the application (form) and prompt them to input the content. Works similarly to the native DOM
placeholderattribute used by inputs.ClassicEditor .create( { attachTo: document.querySelector( '#editor' ), root: { placeholder: 'Type some text...' } } ) .then( ... ) .catch( ... );Copy codeIf your editor implementation uses multiple roots, you should provide config for roots individually:
MultiRootEditor.create( { roots: { header: { element: document.querySelector( '#header' ), placeholder: 'Type header...' }, content: { element: document.querySelector( '#content' ), placeholder: 'Type content...' }, leftSide: { element: document.querySelector( '#left-side' ), placeholder: 'Type left-side...' }, rightSide: { element: document.querySelector( '#right-side' ), placeholder: 'Type right-side...' } } } ) .then( ... ) .catch( ... );Copy codeThe placeholder text is displayed as a pseudo–element of an empty paragraph in the editor content. The paragraph has the
.ck-placeholderCSS class and thedata-placeholderattribute.<p data-placeholder="Type some text..." class="ck-placeholder"> ::before </p>Copy codeNote: Placeholder text can also be set using the
placeholderattribute if a<textarea>is passed to thecreate()method, e.g.ClassicEditor.create().Note: This configuration has precedence over the value of the
placeholderattribute of a<textarea>element passed to thecreate()method.See the "Editor placeholder" guide for more information and live examples.