Integrating CKEditor 5 with Vue.js 3+ multi-root editor component from CDN
This page focuses on describing the usage of the multi-root editor in Vue applications. For other editor types, see the default Vue.js 3+ integration.
The Vue multi-root editor integration is experimental. Its API is not stable and may change in any release without a major version bump.
The multi-root editors in Vue are supported since version 8.2.0 of this package.
This guide assumes you already have a Vue project. If you want to create a new one, you can use the Vite CLI. It allows you to create and customize your project with templates. For example, you can set up your project with TypeScript support.
To use our Cloud CDN services, create a free account. Learn more about license key activation.
Install the CKEditor 5 WYSIWYG editor package for Vue.
npm install @ckeditor/ckeditor5-vue
Use the useCKEditorCloud composable together with the CkeditorMultiRoot, CkeditorElement, and CkeditorMultiRootEditable components inside your project:
<!-- App.vue -->
<template>
<p v-if="cloud.loading.value">
Loading CKEditor 5 from CDN...
</p>
<p v-else-if="cloud.error.value">
CKEditor 5 could not be loaded from CDN.
</p>
<CkeditorMultiRoot
v-else-if="editor && config"
v-model="editorData"
v-model:roots-attributes="editorRootsAttributes"
:editor="editor"
:config="config"
>
<template #default="{ editor, roots }">
<CkeditorElement
:editor="editor"
element="menuBar"
/>
<CkeditorElement :editor="editor" />
<CkeditorMultiRootEditable
v-for="rootName in roots"
:id="rootName"
:key="rootName"
:root-name="rootName"
:editor="editor"
/>
</template>
</CkeditorMultiRoot>
</template>
<script setup>
import { computed, ref } from 'vue';
import {
CkeditorElement,
CkeditorMultiRoot,
CkeditorMultiRootEditable,
useCKEditorCloud
} from '@ckeditor/ckeditor5-vue';
const cloud = useCKEditorCloud( {
version: '48.3.1',
languages: [ 'en' ],
premium: true
} );
const editor = computed( () => {
if ( !cloud.data.value ) {
return null;
}
return cloud.data.value.CKEditor.MultiRootEditor;
} );
const config = computed( () => {
if ( !cloud.data.value ) {
return null;
}
const { Essentials, Paragraph, Bold, Italic } = cloud.data.value.CKEditor;
const { FormatPainter } = cloud.data.value.CKEditorPremiumFeatures;
return {
licenseKey: '<YOUR_LICENSE_KEY>',
plugins: [
Essentials,
Paragraph,
Bold,
Italic,
FormatPainter
],
toolbar: [ 'undo', 'redo', '|', 'bold', 'italic', '|', 'formatPainter' ]
};
} );
const editorData = ref( {
intro: '<h1>Vue multi-root editor</h1>',
content: '<p>Hello from CKEditor 5 multi-root!</p>'
} );
const editorRootsAttributes = ref( {
intro: { order: 10 },
content: { order: 20 }
} );
</script>
You can also register all CKEditor 5 Vue components globally by installing CkeditorPlugin in your Vue application.
import { createApp } from 'vue';
import { CkeditorPlugin } from '@ckeditor/ckeditor5-vue';
import App from './App.vue';
createApp( App )
.use( CkeditorPlugin )
.mount( '#app' );
The CkeditorMultiRoot component supports the following properties:
editor: MultiRootEditor(required) – TheMultiRootEditorconstructor to use.modelValue: Object– The initial data for the created editor. Use it withv-model. See the Getting and setting data guide.rootsAttributes: Object– The initial roots attributes for the created editor. Use it withv-model:roots-attributes.config: Object– The editor configuration. See the Configuration guide.disabled: Boolean– TheMultiRootEditoris switched to read-only mode if the property is set totrue.disableWatchdog: Boolean– If set totrue, the watchdog feature will be disabled. It is set tofalseby default.watchdogConfig: WatchdogConfig– Configuration object for the watchdog feature.disableTwoWayDataBinding: Boolean– Allows disabling the two-way data binding mechanism between the editor state andmodelValueobject to improve editor efficiency. The default value isfalse.
The component emits the following events:
ready– It is called when the editor is ready with aMultiRootEditorinstance. This event is also emitted after the reinitialization of the component if an error occurred.destroy– It is called when the editor instance is destroyed.change– It is called when the editor data has changed. See theeditor.model.document#change:dataevent.blur– It is called when the editor was blurred. See theeditor.editing.view.document#blurevent.focus– It is called when the editor was focused. See theeditor.editing.view.document#focusevent.error– It is called when the editor has crashed during the initialization or during the runtime. It receives two arguments: the error instance and the error details.input– It is emitted when the editor data changes. It receives three arguments: the current data, anEventInfoobject ornull, and aMultiRootEditorinstance.update:modelValue– It is emitted when the editor data changes and updatesv-model.update:rootsAttributes– It is emitted when the roots attributes change and updatesv-model:roots-attributes.
Error details is an object that contains two properties:
phase: 'initialization'|'runtime'– Informs when an error has occurred (during the editor or context initialization, or after the initialization).causesRestart: Boolean– If set totrue, the watchdog will attempt to restart the editor.
The editor event callbacks (change, blur, focus) receive two arguments:
- An
EventInfoobject. - An
MultiRootEditorinstance.
The default slot of the CkeditorMultiRoot component exposes the following values:
editor– The instance of created editor.roots– An array of editor root names. This array is updated after detaching an existing root or adding a new root.data– The current state of the editor’s data. It is updated after each editor update. Note that you should not use it if you disabled two-way binding by passing thedisableTwoWayDataBindingproperty.attributes– The current state of the editor’s root attributes. It is updated after each editor attributes update. Note that you should not use it if you disabled two-way binding by passing thedisableTwoWayDataBindingproperty.rootsAttributes– An alias forattributes.addRoot– A function that adds a new root to the editor at runtime. It accepts a single options object withname,data,attributes,modelElement(for example,'$inlineRoot'), andeditableOptions(per-rootelement,placeholder, andlabel). The returned promise resolves once the root has been added.removeRoot– A function that detaches a root from the editor by name. The returned promise resolves once the root has been removed.
The CkeditorElement component renders editor UI elements outside of the editable root. It accepts the editor property and an optional element property set to 'toolbar' or 'menuBar'.
The CkeditorMultiRootEditable component renders a single editable root. It accepts the editor, rootName, optional id, and optional editableOptions properties.
By default, the two-way data binding is enabled. It means that every change done in the editor is automatically applied in the object bound with v-model. It works the same way in case of attributes – bind them with v-model:roots-attributes to keep your application state up-to-date.
Two-way data binding may lead to performance issues with large editor content. In such cases, it is recommended to disable it by setting the disableTwoWayDataBinding property to true when using the CkeditorMultiRoot component. When this is disabled, you will need to handle data synchronization manually if it is needed.
The recommended approach for achieving this is based on utilizing the autosave plugin. The second approach involves providing the change event listener, which is called on each editor update.
The default slot exposes addRoot and removeRoot helpers so you can manage roots from event handlers. The addRoot helper accepts the new root’s name, initial data, optional attributes, an optional modelElement for the schema, and editableOptions describing the editable element (its host tag, placeholder text, and accessible label).
<template>
<CkeditorMultiRoot
v-model="editorData"
:editor="MultiRootEditor"
>
<template #default="{ editor, roots, addRoot, removeRoot }">
<button @click="addSidebar( addRoot )">
Add sidebar
</button>
<button @click="removeRoot( 'sidebar' )">
Remove sidebar
</button>
<CkeditorElement :editor="editor" />
<CkeditorMultiRootEditable
v-for="rootName in roots"
:key="rootName"
:root-name="rootName"
:editor="editor"
/>
</template>
</CkeditorMultiRoot>
</template>
<script setup>
async function addSidebar( addRoot ) {
await addRoot( {
name: 'sidebar',
data: '<p>Sidebar content</p>',
attributes: { order: 30 },
editableOptions: {
element: 'section',
placeholder: 'Type the sidebar content...',
label: 'Sidebar'
}
} );
}
</script>
The editableOptions.element field accepts a tag name string ('section', 'article') or a descriptor object with name, classes, styles, and attributes.
A multi-root editor can host both standard and inline roots in the same document. Set modelElement to '$inlineRoot' for any root that should accept only inline content (text, bold, italic, links) instead of blocks. This is useful for titles, captions, or single-line fields combined with a block-based body.
await addRoot( {
name: 'title',
data: 'Document title',
modelElement: '$inlineRoot',
editableOptions: {
element: 'h1',
placeholder: 'Enter title...'
}
} );
Without modelElement: '$inlineRoot', only the host tag changes – the schema still permits blocks inside the root.
The source code of rich text editor component for Vue is available on GitHub in https://github.com/ckeditor/ckeditor5-vue.
- See how to manipulate the editor’s data in the Getting and setting data guide.
- Refer to further guides in the setup section to see how to customize your editor further.
- Check the features category to learn more about individual features.