Sign up (with export icon)

Integrating CKEditor 5 with Vue.js 3+ rich text multi-root editor component from npm

Contribute to this guideShow the table of contents

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.

Experimental

The Vue multi-root editor integration is experimental. Its API is not stable and may change in any release without a major version bump.

Note

The multi-root editors in Vue are supported since version 8.2.0 of this package.

Quick start

Copy link

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.

Install the CKEditor 5 WYSIWYG editor package for Vue and the multi-root editor type.

npm install ckeditor5 @ckeditor/ckeditor5-vue
Copy code
Note

Starting from version 44.0.0, the licenseKey property is required to use the editor. If you use a self-hosted editor from npm:

You can set up a free trial to test the editor and evaluate the self-hosting.

Use the CkeditorMultiRoot, CkeditorElement, and CkeditorMultiRootEditable components inside your project:

<!-- App.vue -->

<template>
    <CkeditorMultiRoot
        v-model="editorData"
        v-model:roots-attributes="editorRootsAttributes"
        :editor="MultiRootEditor"
        :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 } from '@ckeditor/ckeditor5-vue';
import { MultiRootEditor, Bold, Essentials, Italic, Paragraph } from 'ckeditor5';

import 'ckeditor5/ckeditor5.css';

const config = computed( () => {
    return {
        licenseKey: '<YOUR_LICENSE_KEY>', // Or 'GPL'.
        plugins: [ Essentials, Bold, Italic, Paragraph ],
        toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ]
    };
} );

const editorData = ref( {
    intro: '<h1>Vue multi-root editor</h1>',
    content: '<p>Hello from CKEditor&nbsp;5 multi-root!</p>'
} );

const editorRootsAttributes = ref( {
    intro: { order: 10 },
    content: { order: 20 }
} );
</script>
Copy code

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' );
Copy code

Component properties

Copy link

The CkeditorMultiRoot component supports the following properties:

  • editor: MultiRootEditor (required) – The MultiRootEditor constructor to use.
  • modelValue: Object – The initial data for the created editor. Use it with v-model. See the Getting and setting data guide.
  • rootsAttributes: Object – The initial roots attributes for the created editor. Use it with v-model:roots-attributes.
  • config: Object – The editor configuration. See the Configuration guide.
  • disabled: Boolean – The MultiRootEditor is switched to read-only mode if the property is set to true.
  • disableWatchdog: Boolean – If set to true, the watchdog feature will be disabled. It is set to false by default.
  • watchdogConfig: WatchdogConfigConfiguration object for the watchdog feature.
  • disableTwoWayDataBinding: Boolean – Allows disabling the two-way data binding mechanism between the editor state and modelValue object to improve editor efficiency. The default value is false.

The component emits the following events:

  • ready – It is called when the editor is ready with a MultiRootEditor instance. 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 the editor.model.document#change:data event.
  • blur – It is called when the editor was blurred. See the editor.editing.view.document#blur event.
  • focus – It is called when the editor was focused. See the editor.editing.view.document#focus event.
  • 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, an EventInfo object or null, and a MultiRootEditor instance.
  • update:modelValue – It is emitted when the editor data changes and updates v-model.
  • update:rootsAttributes – It is emitted when the roots attributes change and updates v-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 to true, the watchdog will attempt to restart the editor.

The editor event callbacks (change, blur, focus) receive two arguments:

  1. An EventInfo object.
  2. An MultiRootEditor instance.

Slot values

Copy link

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 the disableTwoWayDataBinding property.
  • 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 the disableTwoWayDataBinding property.
  • rootsAttributes – An alias for attributes.
  • addRoot – A function that adds a new root to the editor at runtime. It accepts a single options object with name, data, attributes, modelElement (for example, '$inlineRoot'), and editableOptions (per-root element, placeholder, and label). 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.

Two-way data binding

Copy link

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.

Note

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.

How to?

Copy link

Adding and removing roots dynamically

Copy link

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>
Copy code

The editableOptions.element field accepts a tag name string ('section', 'article') or a descriptor object with name, classes, styles, and attributes.

Mixing standard and inline roots

Copy link

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...'
    }
} );
Copy code

Without modelElement: '$inlineRoot', only the host tag changes – the schema still permits blocks inside the root.

Using the editor with collaboration plugins

Copy link

We provide several ready-to-use integrations featuring collaborative editing with multi-root in Vue applications:

It is not necessary to build applications on top of the above samples, however, they should help you get started.

Contributing and reporting issues

Copy link

The source code of rich text editor component for Vue is available on GitHub in https://github.com/ckeditor/ckeditor5-vue.

Next steps

Copy link