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

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](vue-default-npm.md).

> **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.

<a id="quick-start">

## Quick start

This guide assumes you already have a Vue project. If you want to create a new one, you can use the [Vite](https://vitejs.dev/guide/) 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](https://www.npmjs.com/package/@ckeditor/ckeditor5-vue) and the [multi-root editor type](../../../setup/editor-types.md#multi-root-editor).

```bash
npm install ckeditor5 @ckeditor/ckeditor5-vue
```

> **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 must either comply with the GPL or
> * Obtain a license for [self-hosting distribution](../../../licensing/license-key-and-activation.md).
>
> You can set up [a free trial](https://portal.ckeditor.com/checkout?plan=free) to test the editor and evaluate the self-hosting.

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

```vue
<!-- 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 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.

```js
import { createApp } from 'vue';
import { CkeditorPlugin } from '@ckeditor/ckeditor5-vue';

import App from './App.vue';

createApp( App )
	.use( CkeditorPlugin )
	.mount( '#app' );
```

<a id="component-properties">

## Component properties

The `CkeditorMultiRoot` component supports the following properties:

* `editor: MultiRootEditor` (required) – The [`MultiRootEditor`](../../../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.md) constructor to use.
* `modelValue: Object` – The initial data for the created editor. Use it with `v-model`. See the [Getting and setting data](../../../setup/getting-and-setting-data.md) 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](../../../setup/configuration.md) guide.
* `disabled: Boolean` – The [`MultiRootEditor`](../../../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.md) is switched to read-only mode if the property is set to `true`.
* `disableWatchdog: Boolean` – If set to `true`, [the watchdog feature](../../../../features/watchdog.md) will be disabled. It is set to `false` by default.
* `watchdogConfig: WatchdogConfig` – [Configuration object](../../../../api/module_watchdog_watchdog-WatchdogConfig.md) for the [watchdog feature](../../../../features/watchdog.md).
* `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`](../../../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.md) 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`](../../../../api/module_engine_model_document-ModelDocument.md#event-change:data) event.
* `blur` – It is called when the editor was blurred. See the [`editor.editing.view.document#blur`](../../../../api/module_engine_view_document-ViewDocument.md#event-blur) event.
* `focus` – It is called when the editor was focused. See the [`editor.editing.view.document#focus`](../../../../api/module_engine_view_document-ViewDocument.md#event-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`](../../../../api/module_utils_eventinfo-EventInfo.md) object or `null`, and a [`MultiRootEditor`](../../../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.md) 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`](../../../../api/module_utils_eventinfo-EventInfo.md) object.
2. An [`MultiRootEditor`](../../../../api/module_editor-multi-root_multirooteditor-MultiRootEditor.md) instance.

<a id="slot-values">

## Slot values

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.

<a id="two-way-data-binding">

## Two-way data binding

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](../../../../features/autosave.md). The second approach involves providing the `change` event listener, which is called on each editor update.

<a id="how-to">

## How to?

<a id="adding-and-removing-roots-dynamically">

### Adding and removing roots dynamically

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).

```vue
<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 id="mixing-standard-and-inline-roots">

### Mixing standard and inline roots

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.

```js
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.

<a id="contributing-and-reporting-issues">

## Contributing and reporting issues

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

<a id="next-steps">

## Next steps

* See how to manipulate the editor’s data in the [Getting and setting data](../../../setup/getting-and-setting-data.md) guide.
* Refer to further guides in the [setup section](../../../setup/configuration.md) to see how to customize your editor further.
* Check the [features category](../../../../features/index.md) to learn more about individual features.

---

Full index of the CKEditor 5 documentation: [llms.txt](../../../../../llms.txt)
