Contribute to this guide

guideUpdate to CKEditor 5 v35.x

When updating your CKEditor 5 installation, make sure all the packages are the same version to avoid errors.

For custom builds, you may try removing the package-lock.json or yarn.lock files (if applicable) and reinstalling all packages before rebuilding the editor. For best results, make sure you use the most recent package versions.

# Update to CKEditor 5 v35.2.0

Released on October 5, 2022.

For the entire list of changes introduced in version 35.2.0, see the release notes for CKEditor 5 v35.2.0.

Listed below are the most important changes that require your attention when upgrading to CKEditor 5 v35.2.0.

# Introducing external comments

In this release, we are introducing external comments and suggestions. Currently, they are used by the import from Word feature. However, other features may use them in the future as well.

External comments and suggestions display their content, author name, and date as provided by an external source (like a Word document).

Even if you do not plan to use the import from Word feature, we recommend following this migration guide. It will make your integration ready in case you decide to use external comments or suggestions in the future.

# Saving external comments and suggestions data

This information applies only to integrations that use the asynchronous collaboration features.

The external data for external comments and suggestions is kept in the newly added @external attribute. It is an object with two fields: authorName (String) and createdAt (Date).

Other properties and attributes for comments and suggestions are used in the regular way. The authorId property is set to the author who performed the import.

The external data is shown in the UI, but it is not authenticated (as it comes from an external source). Because of that, it is important to introduce some security measures when saving external comments and suggestions:

  • The @external attribute should be read-only and possible to set only when a comment or suggestion is created.
  • Other comment and suggestion properties (like content) should be read-only as well, if the @external attribute is set.

This information applies only to integrations that use custom annotation views or templates.

Since the data in external comments and suggestions is not authenticated, we have added a label that informs users that a given item comes from an external source.

This changes the CommentView template and the SuggestionThreadView template. The label is added at the end of these templates. Check the new templates to see whether this change affects your custom view.

# Comment input editor is now loaded on demand

This information applies only to custom features depending on the comment input editor.

The comment input editor is now initialized on demand (when the comment view is focused for the first time) instead of when it is rendered.

If your custom feature somehow depends on the comment input editor, you may need to update it.

This information applies only to custom features that create their own Annotation instances.

The Annotation instances that target a marker or a DOM element inside the editor editable must now be manually registered. You need to do this using EditorAnnotations#registerAnnotation() to provide correct focus tracking between the annotation and the editor.

// Before:
const annotation = new Annotation( ... );
editor.plugins.get( 'Annotations' ).add( annotation );

// After:
const annotation = new Annotation( ... );
editor.plugins.get( 'EditorAnnotations' ).registerAnnotation( annotation );
editor.plugins.get( 'Annotations' ).add( annotation );

# Icons paths changed

Among other changes, some icons have been moved around the project. Observe these changes if you use custom UI elements that call these icons.

  • The bold icon was moved to the @ckeditor/ckeditor5-core package.
  • The paragraph icon was moved to the @ckeditor/ckeditor5-core package.

The rest of the import path remained unchanged (/theme/icons/).

# Update to CKEditor 5 v35.1.0

Released on August 31, 2022.

For the entire list of changes introduced in version 35.1.0, see the release notes for CKEditor 5 v35.1.0.

Listed below are the most important changes that require your attention when upgrading to CKEditor 5 v35.1.0.

# Changes to API providing accessible navigation between editing roots and toolbars on Alt+F10 and Esc keystrokes

This information applies only to integrators who develop custom editor creators from scratch by using the Editor and EditorUI classes as building blocks.

  • The enableToolbarKeyboardFocus() helper that allowed the navigation was removed. To bring this functionality back, use the addToolbar method instead.
  • Editable elements are now automatically added to the main focus tracker. You should not add them individually.


import { EditorUI } from 'ckeditor5/src/core';

export default class MyEditorUI extends EditorUI {
    // ...

    init() {
        const view = this.view;
        const editableElement = view.editable.element;
        const toolbarViewInstance = this.view.toolbar;

        // ...

        this.setEditableElement( 'editableName', editableElement );

        this.focusTracker.add( editableElement );

        enableToolbarKeyboardFocus( {
            // ...

            toolbar: toolbarViewInstance
        } );

        // ...


import { EditorUI } from 'ckeditor5/src/core';
// Or `import { EditorUI } from 'ckeditor5/src/ui';` if you update to v36.x;

export default class MyEditorUI extends EditorUI {
    // ...

    init() {
        const view = this.view;
        const editableElement = view.editable.element;
        const toolbarViewInstance = this.view.toolbar;

        // ...

        // Note: You should not add the editable element to the focus tracker here.
        // This is handled internally by the EditorUI#setEditableElement() method.
        this.setEditableElement( 'editableName', editableElement );

        // Note: Add the toolbar to enable Alt+F10 navigation.
        // The rest (e.g. the Esc key handling) is handled by the EditorUI#setEditableElement() method.
        this.addToolbar( toolbarViewInstance );

        // ...

# Removal of the TooltipView class and changes to the tooltip system

This change does not affect integrations that configure tooltips of core UI components, for instance tooltip.

Starting with v35.1.0, the TooltipView UI component was removed from the ckeditor5-ui package. Instead, a new tooltip API is available based on the data-cke-tooltip-* DOM element attributes.

Your integration may create instances of TooltipView and inject them into the DOM in a similar way:

// ❌ Old tooltip API.
import { TooltipView } from 'ckeditor5/src/ui';

const tooltip = new TooltipView();

tooltip.text = 'Tooltip text';
tooltip.position = 'sw';

DOMElementThatNeedsTooltip.appendChild( tooltip.element );
/* ❌ Old tooltip API. */
.dom-element-that-needs-tooltip:hover .ck-tooltip {
    visibility: visible;
    opacity: 1;

If this is the case, you should now use the data-cke-tooltip-* attributes and let the editor’s built–in TooltipManager handle the rest:

// ✅ New tooltip API.
DOMElementThatNeedsTooltip.dataset.ckeTooltipText = 'Tooltip text';
DOMElementThatNeedsTooltip.dataset.ckeTooltipPosition = 'sw';

You do not need to worry about showing and hiding your custom tooltips in CSS. The TooltipManager will attach a tooltip whenever the user moves the mouse or brings the focus to a DOM element with the data-cke-tooltip-* attributes. For more information, refer to the TooltipManager API.

# Changes to the color palette in the UI

In this release, we have made several changes to improve the accessibility and contrast of the UI. Since we understand that some integrations may prefer the earlier look of the editor, we prepared a CSS snippet you can use to bring it back.

For the best results, set the custom properties listed below after the main editor style sheets. For more information, check out the theme customization guide.

:root {
    --ck-color-base-border: 						hsl(0, 0%, 77%);
    --ck-color-base-action: 						hsl(104, 44%, 48%);
    --ck-color-base-active: 						hsl(208, 88%, 52%);
    --ck-color-base-active-focus:					hsl(208, 88%, 47%);
    --ck-color-focus-border-coordinates: 			208, 79%, 51%;
    --ck-color-focus-outer-shadow: 					hsl(207, 89%, 86%);

    --ck-color-button-default-hover-background: 	hsl(0, 0%, 90%);
    --ck-color-button-default-active-background: 	hsl(0, 0%, 85%);
    --ck-color-button-default-active-shadow: 		hsl(0, 0%, 75%);

    --ck-color-button-on-background: 				hsl(0, 0%, 87%);
    --ck-color-button-on-hover-background: 			hsl(0, 0%, 77%);
    --ck-color-button-on-active-background: 		hsl(0, 0%, 73%);
    --ck-color-button-on-active-shadow: 			hsl(0, 0%, 63%);
    --ck-color-button-on-disabled-background: 		hsl(0, 0%, 87%);
    --ck-color-button-on-color:						var(--ck-color-text);

    --ck-color-button-action-hover-background: 		hsl(104, 44%, 43%);
    --ck-color-button-action-active-background: 	hsl(104, 44%, 41%);
    --ck-color-button-action-active-shadow: 		hsl(104, 44%, 36%);

    --ck-color-switch-button-off-background:		hsl(0, 0%, 69%);
    --ck-color-switch-button-off-hover-background:	hsl(0, 0%, 64%);
    --ck-color-switch-button-on-hover-background: 	hsl(104, 44%, 43%);

    --ck-color-input-border: 						hsl(0, 0%, 78%);
    --ck-color-input-disabled-border: 				hsl(0, 0%, 78%);

    --ck-color-list-button-on-background: 			var(--ck-color-base-active);
    --ck-color-list-button-on-background-focus: 	var(--ck-color-base-active-focus);

    --ck-color-toolbar-background: 					var(--ck-color-base-foreground);

# Renaming the properties of BalloonPanelView

The static properties of BalloonPanelView were renamed.

The BalloonPanelView.arrowVerticalOffset static property is now arrowHeightOffset and BalloonPanelView.arrowHorizontalOffset is now arrowSideOffset.

# Update to CKEditor 5 v35.0.0

Released on August 3, 2022.

For the entire list of changes introduced in version 35.0.0, see the release notes for CKEditor 5 v35.0.0.

Listed below are the most important changes that require your attention when upgrading to CKEditor 5 v35.0.0.

# The source element is not updated automatically after the editor destruction

The last version of CKEditor 5 changes the default behavior of the source element after the editor is destroyed (when editor.destroy() is called). Before, the source element was updated with the output coming from editor.getData(). Now, the source element becomes empty after the editor is destroyed and it is not updated anymore.

However, this behavior is configurable. You can enable it with the updateSourceElementOnDestroy configuration option:

ClassicEditor.create( sourceElement, {
    // ...
    updateSourceElementOnDestroy: true
} );

Depending on the plugins you use, enabling the updateSourceElementOnDestroy option in your configuration might have some security implications. While the editing view is secured, there might be some unsafe content in the data output, so enable this option only if you know what you are doing. Be extra careful when using the Markdown, General HTML Support, and HTML embed features.

Due to the ongoing accessibility improvements, the default behavior of the dropdown UI component was changed. From now on, by default, after choosing an option from a dropdown (either by mouse or keyboard), the focus will automatically move to the dropdown button.

This default behavior of the dropdown component needs to be overridden in scenarios where the focus should move back to the editing area. An example of such a feature would be the “Heading” dropdown. Choosing one of the options should result in the focus returning to the editing area instead of the button.

You can customize this behavior by using the listener on the dropdown’s execute event, e.g.:

// Option 1.
// If the `execute` event is delegated to the dropdown, one listener can handle both:
// executing the command (assuming the dropdown executes it) and focusing the editor editing view.
dropdownView.on( 'execute', () => {
    editor.execute( 'myCommand' );
} );

// Option 2.
// Otherwise, a dedicated listener may need to be added.
buttonInsideADropdown.on( 'execute', () => {
    editor.execute( 'myCommand' );
} );

dropdownView.on( 'execute', () => {
} );

# There is now TypeScript code on GitHub (and how it affects your build)

Starting from v35.0.0, the first CKEditor 5 package (namely: @ckeditor/ckeditor5-utils) is developed in TypeScript. This is the first step of the migration to TypeScript.

# Whom does it affect

It affects you only if you use the source code directly from the Git repository (GitHub). If you use it via any other channel (npm, CDN, ZIP, etc.), this change is transparent for you as we publish only JavaScript code there.

# How does it affect you

For instance, if you happen to have a custom CKEditor 5 build that installs its dependencies from the Git repository, you will need to update your webpack configuration to support the TypeScript code.

You can find the inspiration on how to change your configuration in this commit (this one makes the discussed change in our builds).