CKEditor 5 changelog
This is the CKEditor 5 changelog guide. Here you will find information about the most important changes introduced in the release, new features, and bug fixes.
Information about both major and minor breaking changes is available, too, if the release introduces them. You can read more about breaking changes in CKEditor 5 in the Versioning policy guide.
You can find more information about each release in the blog posts linked at the start of each entry.
This guide covers the three latest releases of CKEditor 5. For older releases, see the Previous releases section.
We are happy to announce the release of CKEditor 5 v49.1.0.
We are releasing Editing Toolkit, a new set of APIs for developers who build their own editing experiences.
Editing Toolkit grew out of our work on CKEditor AI, our plug-and-play AI offering. Turn it on, and you have an editor with AI that keeps humans in the loop.
But some teams want to build their own AI integration rather than use a ready-made one. Editing Toolkit gives them the building blocks to work with content in the editor. It consists of two parts:
- Compare: an editor API that lets you compare two versions of HTML content, then apply or suggest individual changes. You can also preview the changes before they land in the content.
- Coauthor: think of it as MCP for CKEditor. It lets server-side agents draft content, suggest edits, or leave comments in the editor: through ChatGPT or Claude, or as background jobs. Coauthor is currently in early access, and if you would like to test it, let us know.
Editing Toolkit is not limited to AI. You can also use it in strictly deterministic scenarios like manipulating content with code or comparing it with externally generated HTML, for example, HTML converted from an updated Word file.
CKEditor AI can now work with the content of your plugins, such as a custom widget or a new HTML element. Upload a custom skill that describes the markup and rules of your feature, then register the plugin with AIEditorConfig#add(). The AI agent then writes and keeps your custom content in the shape your editor accepts, and its proposed changes follow your feature’s rules.
See Registering custom features for details.
On-premises deployments of CKEditor AI can call a service you host before the agent answers an AI Chat message. With hooks, your service can check each message against your policies, answer from your systems, or pass context and instructions to the CKEditor AI agent. Use them when you already have an AI platform with access to your data and want it to take part in the chat.
- New theme improvements and fixes: v49.0.0 introduced a refreshed default theme built on three layers of design tokens (foundation scales, semantic roles, and per-component tokens), with legacy variable names kept as aliases. Some aliases were silently ignored even though the migration guide said they worked. They work again, so overrides of focus borders and the shadows of dropdowns, balloons, menus, and comment and suggestion cards apply with no changes on your side. Additionally, more of the UI moved from hard-coded values to tokens (#20255, #20257, #20259): button colors in the resting, hover, and active states, toolbar button borders and radius, form and dialog headers, the insert table grid, and find and replace results. Every new token defaults to the value used today, so the default theme looks the same. See the full token list in the theme customization guide.
- Shadow DOM support for more features: the CKBox file manager and image editor, the “Edit source” dialog of enhanced source editing, and footnotes work correctly when the editor renders in a shadow root. Plugin authors get two helpers for events that do not cross a shadow boundary, such as
scroll:listenToEventRoots()listens on the document and on every shadow root the editor lives in, andDomTargetsListenerlistens on a set of targets you can refresh, like a balloon’s positioning target. See the Shadow DOM deep dive. - More reliable balloons and toolbars: tooltips, the link balloon, and the mention list appear in the right place again on scrolled pages when
<body>or the overlay container is positioned (a v49.0.0 regression, #20251). - Content loading: some browsers started parsing
<?target data?>markup as processing instruction nodes instead of comments, which made the editor throw while loading or pasting such content. The editor ignores these nodes the same way it ignores comments, and data processors have a newskipProcessingInstructionsflag for integrations that need to keep them. - Email export fixes: Email export converts
hsl()andhsla()colors torgb()andrgba()through the newtransformEmailStylesColors()transformation, since many email clients, including Outlook, do not support HSL. The default font and table palettes also no longer trigger warnings in the email configuration logger.
-
collaboration-core, comments: Focused comments and suggestions are now marked with a focus ring instead of a background color. The
--ck-comment-focus-background-colorand--ck-suggestion-box-focus-background-colorCSS variables have been removed. To style the focus ring, use the new--ck-comment-focus-border-color,--ck-comment-focus-shadow,--ck-suggestion-box-focus-border-color, and--ck-suggestion-box-focus-shadowCSS variables. -
ai: The
AIEditorConfigtype describing the editor configuration snapshot has been renamed toAIEditorConfigSnapshot. TheAIEditorConfigname now refers to the new plugin that produces the snapshot and registers custom features. If you used theAIEditorConfigtype (for example, to typeDocumentCompareSnapshot#editorConfigorAIEditingDocumentData#editorConfig), replace it withAIEditorConfigSnapshot. -
comments: The default
CommentThreadViewno longer renders the comment thread header, and theBaseCommentThreadView#commentThreadHeaderViewproperty is deprecated. Customizations of the header, such as buttons added to it or styles for the.ck-thread__headerand.ck-contextCSS classes, no longer apply. The reopen button is now available in the first comment asCommentThreadView#reopenButton. If you need the header, addcommentThreadHeaderViewto the template of your custom comment thread view. -
comments: The
--ck-comment-input-paddingCSS variable now sets only the padding of the comment field container, not the padding inside the comment field. If you used it to change the padding inside the comment field, use the new--ck-comment-input-field-paddingCSS variable instead. -
revision-history: Some Revision History CSS variables now style different parts of the refreshed sidebar:
--ck-revision-history-sidebar-revision-vertical-spacingsets only the spacing between revisions. Use the new--ck-revision-history-sidebar-time-period-vertical-spacingfor the spacing between the time period groups.--ck-revision-history-revision-border-colorsets the whole card border.--ck-revision-history-revision-selected-border-colorand--ck-revision-history-revision-highlighted-border-colorset the vertical line that marks the selected and the compared revisions.- The time period labels no longer use the inverse text color. If you changed their background with
--ck-revision-history-sidebar-period-background-color, set their text color with the new--ck-revision-history-sidebar-period-text-color. --ck-revision-history-revision-highlighted-hover-background-colorno longer has an effect, because the actions button of a compared revision uses the default button hover background.
-
utils: The DOM event passed to the
listenToShadowRoots()callback is now typed after theeventoption, the same way as inDomEmitter#listenTo(), instead ofany. A TypeScript callback that declares a narrower DOM event type than the one of the event it listens to no longer compiles. Declare the matching DOM event type, or narrow it inside the callback.
-
document-outline, footnotes, merge-fields, pagination, real-time-collaboration, revision-history, slash-command, source-editing-enhanced, template, uploadcare: The document outline, table of contents, footnotes, revision history, merge fields, Uploadcare, pagination, presence list, templates, and slash command features expose new CSS custom properties for their colors, sizes, and spacing, and several of their defaults now follow the semantic theme roles. Every new property defaults to the current value, so the default theme renders unchanged.
- Document outline: the active item follows the semantic accent text color (
--ck-color-text-accent), and the hover text color has a new name (--ck-document-outline-item-hover-text-color). The legacy--ck-document-outline-item-hover-state-colorkeeps working. - Table of contents and footnotes: the widget label text color (
--ck-table-of-contents-label-text-color,--ck-footnotes-widget-label-text-color). The label backgrounds follow the semantic secondary text color, and the table of contents background follows the subtle surface (--ck-color-surface-subtle). - Revision history: the selected revision border follows the semantic accent border color (
--ck-color-border-accent), and the actions button of the selected revision has its own text color at rest and on hover (--ck-revision-history-revision-selected-actions-text-color,--ck-revision-history-revision-selected-actions-hover-text-color). - Merge fields: component-first names for the colors (
--ck-merge-fields-outline-color,--ck-merge-fields-value-outline-color,--ck-merge-fields-with-warning-outline-color,--ck-merge-fields-block-outline-color,--ck-merge-fields-affix-text-color,--ck-merge-fields-form-error-background-color), the label and preview badge backgrounds (--ck-merge-fields-label-background-color,--ck-merge-fields-preview-badge-background-color), and the affix font (--ck-merge-fields-affix-font-family). The legacy--ck-color-merge-fields-*names keep working. - Uploadcare: the widget font size, font family, radius, padding, text and border colors (
--ck-uploadcare-font-size,--ck-uploadcare-font-family,--ck-uploadcare-border-radius,--ck-uploadcare-padding,--ck-uploadcare-text-color,--ck-uploadcare-secondary-text-color,--ck-uploadcare-muted-text-color,--ck-uploadcare-border-color), and suffix-convention names for the form colors (--ck-uploadcare-form-image-background-color,--ck-uploadcare-form-error-icon-color,--ck-uploadcare-form-skeleton-background-color). The legacy--ck-uploadcare-color-*names keep working. The widget font now follows the editor UI font (--ck-font-family), so overriding the editor font also changes the Uploadcare widget. - Pagination: the page number label text color (
--ck-pagination-label-text-color). - Presence list: the avatar border and users counter colors (
--ck-presence-list-avatar-border-color,--ck-presence-list-counter-border-color,--ck-presence-list-counter-background-color,--ck-presence-list-counter-text-color) can now be set on:root(or:hostin a shadow root). The avatar border follows the subtle surface. These properties are now override points only: because the counter colors depend on the avatar color of each user, their defaults are applied where they are used, so reading them withvar()in your own CSS returns nothing unless you set them. - Templates: the description text color (
--ck-template-description-text-color). The template title and description now follow the button text color. - Slash command: the icon chip text color, background, and radius (
--ck-slash-command-icon-text-color,--ck-slash-command-icon-background-color,--ck-slash-command-icon-border-radius).
- Document outline: the active item follows the semantic accent text color (
-
basic-styles, block-quote, code-block, horizontal-line, image, list, mention, page-break, table: The block quote border, code block, inline code, horizontal line, page break, table borders and header, and to-do list checkmarks in the content expose
--ck-content-*CSS custom properties, so the content rendered inside.ck-contentcan be restyled on:root(or:hostin a shadow root) without overriding element rules. Every new property defaults to the current value, so the default theme renders unchanged. The table caption, image caption, and mention color properties were renamed to follow the current naming convention (for example--ck-content-table-caption-background-color), and the former--ck-content-color-*names keep working as fallbacks on:root(or:hostin a shadow root) and in scoped selectors. Closes #20253. -
ckbox, fullscreen, html-embed, html-support, media-embed, style, ui, widget: New semantic color roles cover design intents that had no shared token, so they can be restyled once on
:root(or:hostin a shadow root) instead of per component. The components that read the new roles keep their current colors, so the default theme renders unchanged. Closes #20259.--ck-color-surface-subtle: a muted panel or placeholder surface. The fullscreen layout, HTML embed, HTML object embed, media embed placeholder, and the disabled style in the style grid now read it instead of the foundation--ck-color-base-foreground.--ck-color-border-subtle: a light border. The blurred widget outline now reads it.--ck-color-surface-overlay: the scrim behind modal dialogs, read by--ck-dialog-overlay-background-color.--ck-color-surface-skeletonand--ck-color-surface-skeleton-highlight: the loading shimmer, read by the CKBox image processing placeholder.--ck-color-interactive-disabled-surface: the background of a disabled input.--ck-color-text-placeholder: the editing area placeholder text, read through--ck-color-engine-placeholder-text.--ck-color-feedback-error-surface,--ck-color-feedback-success-surface, and--ck-color-feedback-warning-surface: light, translucent backgrounds for messages and fields in a feedback state, available for custom components (no built-in component reads them yet).
The focus border color (
--ck-focus-border-color) now derives from--ck-color-base-focus, so changing the foundation focus color also moves the focus border. The labeled field and labeled input error text now read--ck-color-text-error. Both resolve to the same values as before. -
code-block, find-and-replace, heading, style, table, ui: Toolbars, form and dialog headers, dropdowns, split buttons, lists, tab buttons, the insert table grid, the heading dropdown, find and replace, code blocks, and the style grid expose new CSS custom properties that can be restyled on
:root(or:hostin a shadow root). Every new property defaults to the current value, so the default theme renders unchanged. Closes #20257.- Toolbar: the border and radius of the toolbar’s own buttons in every toolbar (
--ck-toolbar-button-border,--ck-toolbar-button-border-radius), including compact toolbars, toolbars in dropdown panels, and open dropdown and split buttons in toolbars, and the separator width (--ck-toolbar-separator-width). The button tokens do not reach lists in dropdown panels. - Form header and dialog header: the background and the text color of the label, the header icon, and the header buttons, such as the dialog close button (
--ck-form-header-background,--ck-form-header-text-color,--ck-dialog-header-background). - Dropdown: the gap between the label and the arrow (
--ck-dropdown-arrow-gap). The open dropdown button radius (--ck-dropdown-panel-uniform-button-border-radius) now defaults to--ck-button-border-radius. - Split button and list: the separator width and height (
--ck-split-button-separator-width,--ck-list-separator-height). - List item button: the text color and hover background of a toggleable item in the “on” state (
--ck-list-item-button-on-text-color,--ck-list-item-button-on-hover-background). - Tab button: the focus border color and the label color of the active tab (
--ck-tab-button-focus-border-color,--ck-tab-button-active-text-color). - Insert table grid: the cell border, and the background and border of selected cells and of the cell under the pointer (
--ck-insert-table-dropdown-box-border-color,--ck-insert-table-dropdown-box-on-background,--ck-insert-table-dropdown-box-on-border-color,--ck-insert-table-dropdown-box-hover-background,--ck-insert-table-dropdown-box-hover-border-color). - Heading dropdown: the label width and the list item minimum width (
--ck-heading-dropdown-label-width,--ck-heading-dropdown-list-item-min-width). - Find and replace: the result and selected result background and text color (
--ck-find-result-background,--ck-find-result-text-color,--ck-find-result-selected-background,--ck-find-result-selected-text-color). The legacy--ck-color-find-result-selectedkeeps working. - Code block: the language label background and text color (
--ck-code-block-label-background,--ck-code-block-label-text-color). The legacy--ck-color-code-block-label-backgroundkeeps working. - Style grid: the border of the selected style and of the selected style under the pointer (
--ck-style-panel-button-on-border-color,--ck-style-panel-button-on-hover-border-color).
- Toolbar: the border and radius of the toolbar’s own buttons in every toolbar (
-
ai, collaboration-core, comments, real-time-collaboration: The user marker tooltip text color and the background around the comment reply field are now themable through
--ck-user-marker-tooltip-text-colorand--ck-comment-input-container-background-color, and the border of format suggestions in the sidebar follows the semantic--ck-color-border-accentrole. The AI tabs overlay follows the dialog layer (--ck-layer-dialog), so it stays right below dialogs when that layer changes. -
collaboration-core, comments, revision-history: The suggestion and comment markers, the annotation type bar, pills, user avatars, and the confirmation view expose new CSS custom properties for their line width and style, colors, and sizes. Every new property defaults to the current value, so the default theme renders unchanged.
- Suggestion markers: the line width (
--ck-suggestion-marker-border-width, also used by the added and removed roots in the revision viewer), the line style per change type (--ck-suggestion-marker-insertion-border-style,--ck-suggestion-marker-deletion-border-style,--ck-suggestion-marker-format-border-style), the deletion strikethrough thickness (--ck-suggestion-marker-deletion-stroke-thickness), and the gap color next to the block format bar (--ck-suggestion-marker-format-gap-color,--ck-suggestion-marker-format-code-gap-color). - Comment markers: the line width and style (
--ck-comment-marker-border-width,--ck-comment-marker-border-style), and the border color of text and widget markers and of the active marker (--ck-comment-marker-border-color,--ck-comment-marker-active-border-color). The active border color falls back to the resting one on text markers. - Annotation type bar: the line style (
--ck-annotation-type-border-style). - Color swatch in suggestion descriptions: the size and ring color (
--ck-suggestion-color-swatch-size,--ck-suggestion-color-swatch-border-color). - Pill: the text color (
--ck-pill-text-color). The legacy--ck-pill-colorkeeps working. The resting pill background now reads the base hover color directly, so overriding the semantic--ck-color-interactive-hover-surfaceno longer recolors pills. To restyle them, use--ck-pill-background. - User avatar: the background behind avatar images (
--ck-user-avatar-image-background-color). - Confirmation view: the background (
--ck-confirm-view-background-color). The legacy--ck-color-light-redkeeps working.
- Suggestion markers: the line width (
-
style, table, ui: Two new semantic color roles cover accent-colored parts drawn on the canvas:
--ck-color-text-accentfor text and icons, and--ck-color-border-accentfor borders and thin lines. They are separate from--ck-color-interactive-primary-surface, which is a fill. A dark theme can now give these parts a lighter accent that reads well on a dark canvas, while the filled action buttons keep the primary surface color. Both roles default to--ck-color-base-active, so the default theme renders unchanged. Closes #20261.The outline button label and border (
--ck-button-outline-color) and the active tab icon and indicator bar (--ck-tab-button-active-icon-color) now read--ck-color-text-accent. The border of a toggled-on surface button (--ck-button-surface-border-color), the border of the selected style in the style panel, and the hovered table column resizer read--ck-color-border-accent.--ck-color-interactive-selected-textnow follows--ck-color-text-accentby default. -
ui, utils: Introduced helpers for listening to DOM events on both the document and the shadow roots a node lives in. Events that are not composed, such as
scroll, never cross a shadow boundary, so a listener ondocumentalone misses them.- The new
listenToEventRoots()helper listens to the document and to every shadow root tracked by aShadowRootRegistry, and follows the registry as these roots come and go. - The new
DomTargetsListenerclass listens to a set of DOM event targets that can be updated with itsrefresh()method. Together with the newgetEventRoots()helper, it covers particular elements, such as the positioning target of a balloon. ShadowRootRegistrynow also reports the documents of its registered nodes throughgetEventRoots()and fires thechangeEventRootsevent when they change.
The balloon panel, sticky panel, tooltip manager, and block toolbar now use these helpers instead of their own listener syncing code.
- The new
-
collaboration-core, comments: The comments and annotations UI now follows the shared theme tokens, and its buttons, avatars, cards, focus shadows, commented excerpt, and narrow sidebar counter expose new CSS custom properties. Every new property defaults to the current value, so the default theme renders unchanged, with one exception: while its menu is open, the comment options button now shows the regular “on” button colors, like other toggled buttons in the editor.
- Buttons in annotations and below the comment field now follow the shared button tokens, for example
--ck-button-default-text-colorand its hover state, and--ck-button-action-text-colorfor the Reply button. The legacy--ck-annotation-icon-colorkeeps setting the default color of the buttons in annotations (not the buttons below the comment field or in the comment menu), and it wins over--ck-button-default-text-colorthere. - Annotation avatars: the size (
--ck-annotation-user-avatar-size). - Annotation card: the border (
--ck-annotation-wrapper-border), and the border and shadow of the active card (--ck-annotation-wrapper-active-border,--ck-annotation-wrapper-active-shadow). The active card border falls back to the resting one. The card background now defaults to the semantic container surface. - Comment threads and suggestions: the focus shadow (
--ck-thread-focus-shadow,--ck-suggestion-wrapper-focus-shadow). - Commented excerpt: the text color (
--ck-comment-context-text-color). - Narrow sidebar counter: the badge text color (
--ck-annotation-counter-badge-text-color). - The documented
--ck-comment-count-colorCSS custom property now takes effect.
- Buttons in annotations and below the comment field now follow the shared button tokens, for example
-
editor-classic, ui: The background of the editing area can be themed on
:root(or:hostin a shadow root) with the new--ck-editor-editable-backgroundCSS custom property. It reaches the main editing roots of every editor type, not nested editables or secondary editors, and is read through thebackgroundshorthand, so it also accepts gradients and images. -
table, ui: The resting shadow of the classic editor toolbar area, the shadow of the selected insert table grid cell under the pointer, and the inner start border width of the split button arrow can be themed on
:root(or:hostin a shadow root) with the new--ck-sticky-panel-content-shadow,--ck-insert-table-dropdown-box-hover-shadow, and--ck-split-button-arrow-border-inline-start-widthCSS custom properties. Every new property defaults to the current look. -
ai: Custom editor plugins can now be registered with the AI agent using the new
AIEditorConfigplugin (AIEditorConfig#add()method), so that the agent can produce and preserve their content. -
ai: Introduced the Editing Toolkit: APIs and standalone UI components to compare two versions of a document, present them through an interactive UI, and apply the differences to the editor directly or as Track Changes suggestions.
-
ai: AI Chat now scrolls the feed to the next pending change after a proposed change is accepted, suggested, or rejected.
-
ai: The editor configuration that AI features send to the AI service now reports whether the restricted editing mode is enabled, along with the commands allowed in it.
-
ai: After deciding on a change in AI Chat, the preview balloon automatically shows the next pending one or closes if all changes have already been decided on.
-
ai: The AI features now follow the semantic theme roles, so a theme that restyles the editor through
:roottokens (for example the primary, selected, and feedback colors, the text and border roles, and the subtle surface) also restyles the AI UI. The AI toggle and the Quick Actions toolbar buttons also follow the shared button state tokens (--ck-button-on-background-color,--ck-button-on-hover-background-color,--ck-button-on-active-background-color,--ck-button-on-disabled-background-color,--ck-button-on-text-color,--ck-button-default-hover-background-color). The default theme renders unchanged.The AI tabs panel background (
--ck-tabs-panels-container-background) now accepts gradients. New override points: the capability icon background in the AI chat feed (--ck-ai-chat-feed-interaction-header-capabilities-icon-background-color), the AI chat disclaimer divider color (--ck-ai-chat-disclaimer-divider-color), and the inset of the add context button (--ck-ai-chat-context-controls-add-context-button-inset-block-end). The active AI tab background (--ck-ai-tab-active-surface-color) now takes effect. The AI borders and dividers follow the border width roles (--ck-border-width-surface,--ck-border-width-divider), and the dimmed content of resolved suggestions has its own opacity (--ck-ai-suggestion-resolved-opacity). -
ai: AI Review now shows a summary of the accepted and dismissed changes once the last change is decided, and scrolls the list back to the top to show it.
-
ai: The AI features have their own theme tokens for more interactive states. The default look stays the same. New tokens:
- Chat history items:
--ck-ai-chat-history-item-hover-background-color,--ck-ai-chat-history-item-active-background-color,--ck-ai-chat-history-item-edit-background-color. - AI Review check tiles:
--ck-ai-review-check-list-item-hover-shadow,--ck-ai-review-check-list-item-selected-shadow,--ck-ai-review-check-list-item-selected-icon-color. - AI Translate results:
--ck-ai-translate-check-run-result-hover-shadow,--ck-ai-translate-check-run-result-active-border-color,--ck-ai-translate-check-run-result-active-shadow. - Web source chips:
--ck-ai-chat-web-source-hover-background-color,--ck-ai-chat-web-source-focus-shadow. - Chat shortcuts:
--ck-ai-chat-shortcuts-shortcut-icon-hover-color,--ck-ai-chat-shortcuts-shortcut-active-background-color. - Maximized AI tabs resize button:
--ck-ai-tabs-resize-button-on-background-color.
The AI Review tile shadow now follows
--ck-shadow-surface-raised, and the chat prompt highlight ends on the input focus style. - Chat history items:
-
ai: After making a decision about a proposed change in AI Chat and the Editing Toolkit, or about a change in AI Review, the decided change now shows the “Accepted” or “Rejected” label for a moment before the view moves on to the next one. You can change how long this pause lasts, or turn it off with
0, with theconfig.ai.review.autoAdvanceDelayandconfig.ai.chat.autoAdvanceDelayconfiguration options and theautoAdvanceDelayoption of the Editing ToolkitcreateController()method. -
ckbox: The CKBox file manager and image editor dialogs now work when the editor is rendered in a Shadow DOM.
-
comments: You can now set the text color of annotation content, for example suggestion descriptions, using the new
--ck-annotation-content-font-colorCSS custom property. By default, it follows the--ck-comment-content-font-colorvalue. -
email: Introduced the
transformEmailStylesColors()transformation that convertshsl()andhsla()colors torgb()andrgba()in the exported email content, as many email clients (for example, Outlook) do not support the HSL notation.Since
hsl()colors are now safe to use in emails, the email configuration logger no longer reports theemail-configuration-unsupported-color-valueandemail-configuration-unsupported-color-formatwarnings forhsl()colors and thehslcolor picker format, including the default font and table color palettes. These warnings are still reported forhsla()colors. -
emoji: Introduced the
config.emoji.definitionsoption that allows passing the emoji database directly to the editor instead of downloading it from a URL. See ckeditor/ckeditor5#18116.Use it to bundle the database with your application, for example, when the Content Security Policy of the page does not allow downloading it. When the option is set, the
config.emoji.definitionsUrlandconfig.emoji.versionoptions are ignored. TheEmojiCdnResourcetype was renamed toEmojiDefinition. The old name is still available but deprecated. -
ui: Dialogs can now use the new
--ck-width-dialog-xs,--ck-width-dialog-sm, and--ck-width-dialog-xlCSS variables, which set their width to thexs,sm, and2xlsteps of the width scale and cap it at90vw. -
ui: The spread of the focus shadow can now be changed with the new
--ck-focus-shadow-spreadCSS variable, which--ck-focus-shadow-geometryis built from. -
ui: The input field now has a small variant that you can enable with the
ck-input_smallCSS class. You can customize its size with the new--ck-input-min-height-smalland--ck-input-padding-smallCSS variables. -
ui: Buttons, list item buttons, split buttons, tab buttons, and the menu bar expose their interactive states (hover, active, open, and toggled on) as CSS custom properties that can be restyled on
:root(or:hostin a shadow root) without class-level overrides. Every new property defaults to the current value, so the default theme renders unchanged. Closes #20255.- Button: the resting, hover, and active label and icon color (
--ck-button-default-text-color,--ck-button-default-hover-text-color,--ck-button-default-active-text-color; hover and active fall back to the resting color), and the border split into--ck-button-border-width,--ck-button-border-style, and--ck-button-border-color. - Surface and outline button variants: the
--ck-button-surface-*and--ck-button-outline-*tokens are declared on:rootinstead of on the variant button, plus the new--ck-button-outline-border-color. - List item button: the resting and hover label color (
--ck-list-item-button-text-color,--ck-list-item-button-hover-text-color) and the background of an open item, for example an open menu (--ck-list-item-button-open-background). - Split button: the hover background and border color, the focus border color, and the arrow border width (
--ck-split-button-hover-background,--ck-split-button-hover-border-color,--ck-split-button-focus-border-color,--ck-split-button-arrow-border-block-width). - Tab button: the hover background of an inactive tab (
--ck-tab-button-hover-background). - Menu bar: the background (
--ck-menu-bar-background).
- Button: the resting, hover, and active label and icon color (
-
ui: A new
--ck-shadow-surface-raisedsemantic role covers the shadow of in-flow surfaces that lift on hover, such as cards. It defaults to--ck-shadow-lg, so the default theme renders unchanged. -
ui: Open list item buttons, for example open menus in the menu bar and in dropdown menus, can be fully themed from
:rootwith the new--ck-list-item-button-open-hover-backgroundand--ck-list-item-button-open-text-colorCSS custom properties, next to--ck-list-item-button-open-background. The open hover background falls back to the open background, so two properties style the open state with and without the pointer.
-
editor-classic, fullscreen, link, special-characters, style, table, ui: Theme token overrides now reach a few UI parts that ignored them:
- The classic editor editing area border and the fullscreen page follow
--ck-editor-frame-border-colorand--ck-editor-editable-background. A theme that sets--ck-color-border-containeror--ck-color-surface-canvasto a custom value also changes them. - The style grid buttons follow
--ck-color-surface-canvason hover and press, and their backgrounds can be set with--ck-style-panel-button-hover-background,--ck-style-panel-button-active-background, and--ck-style-panel-button-disabled-background. - The table properties error balloon follows the error and inverse text roles:
--ck-table-properties-error-backgroundand--ck-table-properties-error-text-color. - Declared tokens with the current defaults for colors that had only a raw fallback: the color grid check icon (
--ck-color-grid-check-icon-color), the blurred editing area selection (--ck-editor-editable-blurred-selection-background), the accessibility help dialog (--ck-accessibility-help-dialog-code-background-color,--ck-accessibility-help-dialog-kbd-shadow-color, and--ck-accessibility-help-dialog-border-color, which falls back to--ck-color-divider), and the linked image badge (--ck-link-image-indicator-background-color).
- The classic editor editing area border and the fullscreen page follow
-
engine, html-support, paste-from-office, utils: Processing instructions in the input data no longer cause an error during conversion.
Browsers have started parsing
<?target data?>markup in HTML into processing instruction nodes rather than comments. Such nodes are now ignored by default, consistently with how comments have always been handled. Data processors expose a newskipProcessingInstructionsflag for integrations that need to preserve them. -
ckbox, emoji, mention, ui: Dialogs, and the mention list, the emoji picker, and CKBox shown above them, now follow the
--ck-layer-dialogCSS custom property instead of reading the legacy--ck-z-dialogdirectly, so raising the dialog layer moves them together. Set--ck-z-dialogor--ck-layer-dialogon:root(or:hostin a shadow root), or override--ck-layer-dialogon a narrower selector: a scoped override of the legacy--ck-z-dialogno longer applies. The selected item in lists now reads the--ck-color-interactive-primary-surfacefill role instead of a text role. It looks the same in the default theme, but now follows the primary color (--ck-color-base-action) rather than the accent text color, so lightening--ck-color-text-accentfor contrast no longer lightens its background. -
revision-history, source-editing-enhanced, uploadcare: The revision history sidebar header lines up with the editor toolbar again, and the Uploadcare buttons have the same height as the other editor buttons. They, and the enhanced source editing dialog, now read the editor control height (
--ck-size-control-min-height) instead of a legacy size that no longer matched it. -
bookmark, html-support, ui: The
--ck-font-weight-ui-defaultCSS custom property now sets the font weight of regular UI text. The UI reset, the bookmark toolbar preview, and the General HTML Support object widget label read it instead of a hardcodednormalweight. -
ai, comments: Restored support for the legacy
--ck-color-annotation-wrapper-drop-shadowCSS variable. Comment and suggestion cards use it for their shadow again. Focused inline comment threads use--ck-drop-shadowfor their shadow again.The
--ck-tabs-border-radiusCSS variable of the AI tabs now also works when set on a parent element. -
source-editing, ui: Restored support for the legacy
--ck-color-focus-borderand--ck-drop-shadowCSS variables. Buttons, inputs, the editing area, and menu bar items use--ck-color-focus-borderfor their focus border again. Dropdowns, balloons, and menus use--ck-drop-shadowfor their shadow again.Overriding
--ck-interactive-focus-ringnow also changes the focus border of the source editing area. The pulse around the buttons that insert a paragraph next to a widget now matches the refreshed focus color. -
collaboration-core, track-changes: The “AI-generated” pill in the suggestion annotations now has more space above it.
-
ai, revision-history: The AI review check list item descriptions and the revision change author follow the
--ck-font-weight-ui-defaultCSS custom property instead of a hardcoded regular weight. -
ai: The AI Review navigation panel is now hidden when the change it shows becomes outdated, for example, after another user removes the content the change was suggested for.
-
ai: The review results navigation bar’s width is now aligned with the width of the text inside the editor.
-
ai: The AI Translate languages list now leaves space below the last language, matching the AI Review list.
-
ai: Fixed several styling issues in the AI UI:
- The AI Quick Actions search field no longer overflows its panel with a larger control font size.
- The AI error notification dismiss button and the AI Review info button have the intended small size again.
- The add context button in the AI chat prompt is aligned with the input at any control height.
- The toolbar buttons of an AI suggestion show their pressed state, and disabled toolbar buttons no longer get the hover color.
- The error message in the AI balloon follows the theme radius instead of a fixed 4px.
-
ai: Items in the AI Quick Actions dropdown and its sub-menus now show the focus ring when focused with the keyboard.
-
ai: The icons of the AI header buttons follow
--ck-form-header-text-colorwhen it is set on:root, so they match the header label.--ck-ai-header-icon-colorstill overrides them. -
ai: The buttons at the bottom of the AI Chat and AI Quick Actions balloons no longer stick out of the balloon when the editor is narrow. When the buttons do not fit, you can scroll them horizontally instead.
-
bookmark: The URL preview in the bookmark toolbar is no longer oversized. It now uses the regular UI control font size instead of inheriting the larger page font size.
-
clipboard: Links copied using the “Copy” option in the iOS Safari share sheet can now be pasted into the editor. When the clipboard provides neither HTML nor plain text, the editor now uses the
text/uri-listdata and inserts the links as plain text. Closes #2074.Thanks to @dtdesign.
-
collaboration-core: When the annotation type bar is turned on (
--ck-annotation-type-border-width), the thread header (in thread views that render it) now shows the insertion, deletion, or format color of a suggestion, like the rest of the thread, instead of the comment color. The bar of a block format suggestion now shows when the collaboration content styles are loaded without the editor UI styles. -
comments: The commented text quoted in the first comment of a comment thread now fills the available width of the annotations sidebar and stays on a single line in narrow sidebars.
-
comments: The initials in the default avatars of comments, suggestions, and the comment reply field now fit inside the avatar, including wide initials such as “WW”.
-
comments: Replies and the reply field in suggestions displayed inline or in the narrow sidebar now look the same as in comment threads.
-
emoji: Selecting an emoji category that does not contain any emoji in the emoji picker no longer throws an error. The picker now displays a message that the category is empty.
-
export-inline-styles: Exporting content with inline styles no longer loses parts of the
bordershorthand defined with CSS variables, for example, the border style of table cells from the default content styles. CSS variables are now resolved before shorthand properties are processed. -
find-and-replace: The results counter in the find and replace form no longer covers the end of the search text, and it uses the search field font size instead of the larger base UI font size. The counter font size can be themed on
:root(or:hostin a shadow root) with the new--ck-find-and-replace-form-results-counter-font-sizeCSS custom property. -
footnotes: Footnote content no longer wraps below the backlink when the editor is rendered inside a shadow root or on a page without a global
box-sizing: border-boxreset. -
link: Choosing a link from a links provider list in the link form (for example, a bookmark) or going back from that list no longer displays the balloon toolbar on top of the link form. The link form with the chosen link filled in is now displayed as expected.
-
real-time-collaboration: Fixed handling of revision updates made by other users while the revision history is loading.
Such updates could previously throw an error, be dropped, duplicate a revision, or leave it without its authors. They are now applied once the initial revisions and the users they reference are loaded.
-
real-time-collaboration: Comment changes made by other users while comments are loading are no longer lost.
New comment threads, replies, and other comment changes received while the initial comments were loading (also after a reconnection) could previously be dropped or throw an error. They are now applied once the initial comments and the users they reference are loaded.
-
real-time-collaboration: Suggestion attribute changes made by other users while suggestions are loading are no longer lost. They are now applied once the initial suggestions are loaded.
-
revision-history: The Revision History sidebar now follows the direction of the editor UI language, including right-to-left languages.
-
source-editing-enhanced: The code editor in the “Edit source” dialog now receives its styles when the editor UI is rendered inside a shadow root (for example, when
config.ui.overlayContainerpoints to a shadow root). Previously, the code editor styles were added to the main document instead, which left the code editor unstyled. -
template: Template list buttons keep their rounded corners when
--ck-border-radius-uniformis set toinitial, and no longer follow a custom uniform radius. Their radius is controlled by the new--ck-template-list-item-border-radiusCSS custom property, which defaults to--ck-border-radius-surface. -
ui: Fixed menu bar items sticking out of their menu panels on narrow viewports, such as most mobile phones. The larger default font size of the refreshed theme made the minimum width of the items exceed the maximum width of the panel.
The
--ck-menu-bar-menu-item-min-widthCSS variable now sets the minimum width of the whole menu panel and is capped by its maximum width. You can customize the maximum width with the new--ck-menu-bar-panel-max-widthCSS variable (75vwby default). -
ui: The page no longer scrolls back when slowly scrolling the classic editor out of the viewport while a contextual balloon, such as the link or bookmark balloon, is open. The sticky toolbar now returns to its regular position before notifying about the change of its sticky state.
-
ui: Pressing Esc while a tooltip of the focused toolbar button is visible now moves the focus back to the editing area with a single key press. Previously, the first press only hid the tooltip. Tooltips displayed on mouse hover can still be dismissed with Esc without triggering other actions. Closes #18333.
Thanks to @minwookshin.
-
ui: UI buttons and inputs now use the editor UI font (
--ck-font-family) everywhere. Before, controls rendered outside the reset styles, for example inside regions excluded from the UI reset, fell back to the browser’s default font, so a theme could not change their font through tokens. Closes #20258. -
ui: Border colors of inputs, dropdown panels, balloon panels, toolbars, and autocomplete results set on a narrower selector than
:rootnow apply again, under both the legacy and the new token names. Their border shorthand tokens can still be overridden, but they no longer hold a value you can read. To use these borders in your own CSS, read their border color tokens instead. -
ui: Dropdown panels, dropdown menu panels, autocomplete results, the color selector, and list dropdown items now follow
--ck-border-radius-surfaceset on:root(or:host), because--ck-border-radius-uniformderives from it. Override--ck-border-radius-uniformto set them apart. -
utils: Balloons, such as tooltips, the link balloon, or the mention list, are no longer displaced by the page scroll when the
<body>element or the overlay container is positioned. TheRect#toAbsoluteRect()method no longer counts the page scroll twice when the element has a positioned ancestor. Closes #20251. -
utils: The
collectStylesheets()helper no longer fails when collecting the editor content styles with theEDITOR_STYLEStoken in Safari after a modal dialog has been opened in the editor.Safari lists style sheets created by scripts, such as the one that blocks page scrolling while a modal dialog is open, in
document.styleSheets. These style sheets are not attached to any element and caused an error. They are now skipped. -
widget: The buttons for inserting a paragraph next to a widget now use a dedicated theme token for their icon color in the blurred-editor state, so customizing the widget outline color no longer unintentionally recolors them.
-
ai, comments: The comment field, comment editing field, and chat renaming field in AI Chat History now have visible borders and display a focus ring when focused. The buttons below the comment field are smaller.
-
comments: Comment threads in the comments archive now match the refreshed look of comment annotations, with the commented content quoted in the first comment instead of a thread header.
-
real-time-collaboration: Real-time collaboration editors now start faster.
The initial comments, suggestions and revisions are now fetched in parallel during the editor initialization, followed by a single request for the users they reference, instead of one feature after another.
-
revision-history: Revision History sidebar cards now match the refreshed editor UI. Revision names are edited in a bordered field with “Save” and “Cancel” buttons instead of saving on focus loss, and “Name this revision” is now the first revision action and no longer changes the revision displayed in the viewer.
-
typing: The
deleteevent fired when pressing Backspace at the beginning of an editing root or a nested editable now has the view document as its source instead of the global DOM document. -
uploadcare: The loading shimmer of an image being processed in Uploadcare image editing now reads the semantic
--ck-color-surface-skeletonand--ck-color-surface-skeleton-highlightcolors, which resolve to the same values as before. Restyling the skeleton surface once on:root(or:hostin a shadow root) now also reaches it. See ckeditor/ckeditor5#20259. -
The development environment for CKEditor 5 now requires Node v26.10.
CKEditor 5 v49.0.1 is now available.
This release addresses three cross-site scripting (XSS) vulnerabilities, two in the Track Changes plugin and one in CKEditor AI. Under specific conditions, described below, each of them could lead to unauthorized JavaScript code execution.
The first vulnerability (GHSA-2x29-fwvw-5g7x) can be triggered by inserting a specially crafted suggestion into the editor. It affects only installations where Track Changes is enabled together with a feature that allows assigning a color or background color to an element, such as the Font Color or Font Background Color plugins.
The second vulnerability (GHSA-xh7q-269v-94j2) affects the “Preview final content” feature of Track Changes and can be triggered when the final content preview is displayed. It applies only to installations that use a plugin allowing unsafe markup in the editor data output, such as General HTML Support with a non-default configuration or HTML Embed.
The third vulnerability (GHSA-vjh8-qw64-q282) can be triggered by inserting a specially crafted message into the CKEditor AI chat. It affects only installations where CKEditor AI is enabled, and exploitation requires tricking the model into returning specific output, for example through prompt injection.
You can read more details in the relevant security advisories and contact us if you have more questions.
We would like to thank Won Yong Jeon for reporting these vulnerabilities.
- track-changes: The final content preview now renders the content using the editing pipeline instead of the data pipeline, so the preview looks and behaves like the content in the read-only editor.
We are happy to announce the release of CKEditor 5 v49.0.0.
CKEditor 5 v49.0.0 is a major release. It adds shadow DOM support, a refreshed default theme built on design tokens, Trusted Types support, and a redesigned AI Review. It also removes the Watchdog. Before you upgrade, read the v49.0.0 update guide, which also covers the move to ES2023 and native CSS nesting in the distributed stylesheets.
CKEditor 5 can now run inside an open shadow root. Selection, focus, scrolling, drag and drop, and the floating UI (balloons, tooltips, dialogs, and menus) all work there. So do the premium features, including Comments, Track Changes, Real-time Collaboration, and CKEditor AI. Web components, micro-frontends, and design systems built on shadow DOM can now embed the editor without workarounds. Closed shadow roots are not supported.
A shadow root is a separate styling boundary, so load the editor stylesheets into it and override CSS variables on :host instead of :root. The new config.ui.overlayContainer option sets where the floating UI renders. It also helps outside shadow DOM, for example when the editor sits in a container with overflow: hidden. The shadow-aware DOM helpers that the editor uses internally are now public API, so feature and plugin authors can make their own code work in shadow roots. See the Shadow DOM integration guide and, for feature authors, the Shadow DOM deep dive.
The editor ships with a new default theme (#20235). The refresh covers the whole UI, from the toolbar, dropdowns, balloons, dialogs, and forms to the premium features and CKEditor AI. Because it is built on design tokens, matching the editor to your product means overriding a few tokens, and those overrides keep working across editor updates.
The refresh also changes content styles, so published documents look slightly different. Block quotes, code blocks, and horizontal lines use lighter colors, and comment and suggestion markers use new ones.
The new look applies automatically when you upgrade. To keep the previous look, load the legacy theme preset after the editor styles and use the content styles rollback snippets for published content.
The theme now uses three layers of design tokens instead of a flat set of CSS variables (#19910): foundation scales (spacing, radius, color, typography), semantic roles shared across components, and per-component tokens. Override a few foundation tokens to align the editor with your design system, one semantic token to restyle a whole class of controls, or a component token such as --ck-button-border-radius to change one component without side effects.
Overrides of legacy variable names keep working. CSS that reads legacy names, such as var(--ck-spacing-small), needs the opt-in aliases. Scoped overrides of foundation tokens no longer reach components, so override the component token for per-element changes. See the theme token naming guide, the theme customization guide, and the refreshed theme and design tokens section of the update guide.
AI Review has a new design and a Suggest action, which adds an AI change as a Track Changes suggestion instead of applying it directly. While you work through the changes, a balloon in the content follows the current one and a progress bar shows how many are left. AI Review, AI Quick Actions, and Proposed Changes in AI Chat now share the same cards and controls, so actions sit in similar places in all three.
The whole AI interface, including AI Chat, AI Review, Quick Actions, and AI Translate, now uses the refreshed theme and responds to the same token overrides as the rest of the editor. If you customized the AI interface, update your overrides, because legacy AI token names have no fallback. See the AI package section of the theme migration guide for the name mappings.
CKEditor 5 now works in applications that enforce Trusted Types with the require-trusted-types-for 'script' Content Security Policy directive (#10845). Before, the browser blocked the HTML strings the editor inserts into the page, so the editor could not run at all. Every place where the editor inserts HTML, including in premium features, now goes through a Trusted Types policy named ckeditor5.
The policy does not sanitize content, so validating the data you load into the editor remains your responsibility. See the Trusted Types section of the CSP guide and the API docs for trustedHtml().
The Watchdog has been removed (along with the @ckeditor/ckeditor5-watchdog package), so CKEditor 5 no longer restarts the editor after an unhandled error. The editor keeps running with its content and undo history, but its state may be inconsistent, so your application decides what to do next: reload the editor, notify the user, or report the error. Register a callback with the new onEditorError() function to learn about errors and which editor or context caused them.
See the Error handling guide and the Migrating from the Watchdog guide for integration and migration instructions.
-
ckeditor5, core, utils: Removed the
@ckeditor/ckeditor5-watchdogpackage and automatic editor restarts after a crash. The editor now retains its content and undo history instead of being recreated from previously saved data.- Removed the
EditorWatchdog,ContextWatchdog, andWatchdogclasses and theWatchdogConfigtype, including their exports fromckeditor5. - Removed the
Editor.EditorWatchdogandEditor.ContextWatchdogstatic fields from every editor class. - Moved
ActionsRecorderto@ckeditor/ckeditor5-corewithout changing its behavior.
Use
onEditorError()to observe errors and identify the editor or context that caused them. It returns a function that unregisters the callback and is also available asEditor.onEditorError()andContext.onEditorError()for framework integrations.
Copy codeimport { onEditorError } from 'ckeditor5'; const off = onEditorError( ( { error, source } ) => { console.error( 'An error escaped', source, error ); } );If you used
ContextWatchdogto share a context between editors, create theContext, pass it in the editor configuration, and destroy it when it is no longer needed.
Copy codeconst context = await Context.create( contextConfig ); const editor = await ClassicEditor.create( { context, /* ... */ } );Integrations that relied on automatic restarts must now handle errors, for example by reloading the editor, notifying the user, or reporting the error to a tracking service.
- Removed the
-
Introduced three layers of CSS custom properties for theme customization, replacing the previous flat set of variables. Closes #19910.
The layers are:
- Foundation primitives, such as the spacing, radius, and color scales.
- Semantic design roles shared across components, such as control padding and surface radius.
- Per-component override points, such as the button or dialog tokens.
Overrides of legacy variables remain supported, except for removed variables, but reading legacy names in custom CSS, such as
var(--ck-spacing-small), requires the opt-in aliases from the migration guide. Scoped overrides of new foundation or semantic tokens do not affect component tokens, so use component tokens for per-element customization. See the theme token naming guide for the layers and recommended override points. -
Introduced a refreshed default theme based on the new design tokens. The new appearance applies to all integrations using the default theme. Closes #20235.
To retain the previous appearance, copy the legacy theme preset from the migration guide into a stylesheet and load it after the editor styles.
The refreshed
.ck-contentstyles also affect published documents, including comment and suggestion markers, block quotes, code blocks, and horizontal lines. Use the rollback snippets to restore the previous content colors.Custom themes can continue to override legacy token names, but CSS that reads those names requires opt-in aliases. See the migration guide for details and exceptions.
-
core: Moved
ActionsRecorderfrom the removed@ckeditor/ckeditor5-watchdogpackage to@ckeditor/ckeditor5-core.Imports from
ckeditor5are unchanged, but direct imports from@ckeditor/ckeditor5-watchdogmust be updated:
Copy code// Before. import { ActionsRecorder } from '@ckeditor/ckeditor5-watchdog'; // After. import { ActionsRecorder } from '@ckeditor/ckeditor5-core';The
ActionsRecorderConfig,ActionsRecorderEntry,ActionsRecorderEntryEditorSnapshot,ActionsRecorderErrorCallback,ActionsRecorderFilterCallback, andActionsRecorderMaxEntriesCallbacktypes also moved, andconfig.actionsRecorderretains its typing. -
ui: Replaced
new TooltipManager( editor )withTooltipManager.for( locale )and made the constructor private. Callrelease()instead ofdestroy( editor )when each caller no longer needs the shared instance. All editors still share one instance per page througheditor.ui.tooltipManager, using theLocaleof the first caller. See #3891. -
ui: Renamed
BodyCollection#detachFromDom()toBodyCollection#destroy(), which still destroys the collection’s views and removes their container from the DOM. ReplacedetachFromDom()calls withdestroy(), or use the newBodyCollection#unmountFromDom()method to detach the collection without destroying it. See #3891. -
Changed the target for all packages and CDN builds from ES2022 to ES2023.
-
Introduced native CSS nesting in distributed stylesheets in place of flattened selectors. Tools that post-process CKEditor 5 CSS must support nesting or use a nesting transform.
-
font, table, ui: Introduced a shared default palette of 120 Material colors for the font and table color features without changing existing document colors. Configure the color options explicitly to retain the previous palettes.
The default color grid now has 12 columns instead of 5, also changing the default value of
fontColor.documentColors, and the newcolorGridColumnsoption controls the grid width in the table and table cell properties balloons. -
block-quote, code-block: Changed the border and background colors of block quotes and code blocks to lighter shades, including in published content. To restore the previous colors, see the content styles rollback snippets in the migration guide. See #19910.
-
export-pdf, export-word: Changed
converterOptions.extra_http_headersto accept an array of{ domain, headers }entries instead of an object keyed by domain.
Copy code// Before. converterOptions: { extra_http_headers: { 'https://medias.example.org/': { authorization: 'Bearer xxx' } } } // After. converterOptions: { extra_http_headers: [ { domain: 'https://medias.example.org/', headers: { authorization: 'Bearer xxx' } } ] }This affects only integrations that pass converter options directly to the
exportPdforexportWordcommand, as the object form did not work in the editor configuration. -
comments, track-changes: Changed the default colors of comment highlights and suggestion insertion and deletion markers to match the refreshed theme, including in published
.ck-content. To restore the previous appearance, override the--ck-comment-marker-*and--ck-suggestion-marker-*custom properties as shown in the content styles rollback snippets. -
fullscreen, ui: Added CSS variable declarations on
:hostalongside:rootin editor stylesheets, so overrides on:rootdo not affect editors inside shadow roots. Override variables on the shadow host and declare custom stylesheet variables on both selectors, as described in the “Overriding CSS variables” section of the shadow DOM guide. See #3891.Styles that affect the light DOM, such as
ck-fullscreen-scroll-lockedfor locking page scrolling, are now applied at runtime instead of through theme stylesheets, so custom overrides may require higher specificity. -
ai: Changed
AITabs#containerfrom a plainHTMLElement | nullproperty to an observableHTMLElement | ShadowRoot | nullproperty to support shadow roots.See the documentation for details on running CKEditor AI features inside shadow roots.
-
ai: Removed the
config.ai.assistant.useThemeoption. The AI Assistant now always uses theck-ai-assistant-ui_themeCSS class, which follows the editor theme instead of applying a violet tint. To restore the tint or apply custom colors, see the “Using custom colors for the UI” section of the AI Assistant integration guide. -
ai: Removed the unused
--ck-ai-review-suggestion-active-colorCSS custom property (formerly--ck-color-ai-review-suggestion-active) without a replacement. Remove or replace references to it in custom styles. -
ai: Removed the third
editorparameter fromAIGateway#mergeChangesIntoContent(). -
engine: Removed
ViewRenderer#domDocumentswithout a public replacement, as editing roots can now be inside shadow roots. See #3891. -
fullscreen: Changed the default fullscreen container from
<body>toconfig.ui.overlayContainer, the editor’s shadow root, or<body>, in that order of precedence. An explicitconfig.fullscreen.containervalue still takes precedence. See #3891.When the option is not set,
editor.config.get( 'fullscreen.container' )now returnsundefinedinstead of the<body>element.The fullscreen wrapper now uses the
ck-fullscreen__main-wrapper_custom-containerclass when it fills an integrator-provided container, which may require updating custom CSS. -
horizontal-line: Changed the background color of horizontal lines to a lighter shade, including in published content. To restore the previous color, see the content styles rollback snippets in the migration guide. See #19910.
-
mention: Updated the mention suggestion list to match toolbar dropdown lists, with list item buttons and a focus ring instead of a background highlight for the item selected with the keyboard.
Update custom styles to use
ck-mentions__item_focusedon the list item instead ofck-onfor the selected item. Every item, including custom-rendered items, now also uses theck-list-item-buttonclass. -
merge-fields: Updated the merge field suggestion list markup to match the refreshed theme. Custom styles targeting the previous markup may need to be updated. See ckeditor/ckeditor5#20235.
-
ui: Changed the editor’s body collection (balloons, dialogs, and tooltips) to attach to the DOM only after the editing root is connected to the document. Each mount target now has its own
.ck-body-wrapper, including shadow roots and configuredconfig.ui.overlayContainercontainers, instead of sharing one wrapper across the page. See #3891.For editors created on detached elements,
.ck-body-wrapperis no longer in the DOM immediately afterEditor.create()resolves. Useeditor.ui.view.body.bodyCollectionContainerinstead ofdocument.querySelector( '.ck-body-wrapper' )to access the container before it is attached. -
ui: Removed the
listenerOptionsoption fromclickOutsideHandler(), so listener priority and capture mode can no longer be configured. Remove this option from calls to the function. See #3891. -
uploadcare: Changed the Uploadcare
uc-configanduc-upload-ctx-providerweb components to render in the editor’s floating UI container instead ofdocument.body, enabling shadow DOM support. Continue to access them throughUploadcareEditing#configElementandUploadcareEditing#ctxElement. -
utils: Removed the
getCommonAncestor()DOM utility fromckeditor5-utils, as it did not support traversal across shadow boundaries. To find the lowest common ancestor of two DOM nodes, traverse their ancestors withgetParentNode()and compare the chains, or use the model and viewgetCommonAncestor()methods when working with the editor tree. See #3891. -
utils: Changed
getPositionedAncestor()to returnnullfor elements not connected to a document. Previously, it only required the element to have a parent. See #3891.It also handles these cases differently:
- It now returns
<body>when styles such asposition: relativeortransformmake it the containing block. Previously, it always returnednullfor the main document’s<body>. - It now returns
nullinstead of a statically positioned<body>for elements inside an iframe, matching its behavior in the main document. - It now searches the shadow tree for the positioned ancestor of an element assigned to a
<slot>.
- It now returns
-
core, fullscreen, ui: Introduced
config.ui.overlayContainerto specify an element or shadow root for the editor’s floating UI, including balloons, dialogs, and tooltips. Load the editor stylesheets into the target container as described in the “Where the floating user interface mounts” section of the shadow DOM guide. See #3891, #5319.The
config.fullscreen.containeroption now also accepts a shadow root. -
ui, utils: Introduced public APIs for shadow DOM integrations:
ShadowRootRegistry,OverlayHost,ShadowSelection,getSelection(),EditorUI#shadowRootRegistry, and theBodyCollectionmounting API. ThegetSelection()utility returns aShadowSelectioninstance, andBodyCollection#attachToDom()now accepts an element or a shadow root. See #3891.Shadow-aware DOM helpers include
getParentNode(),containsNode(),getActiveElement(), andgetElementFromPoint(), with the full list available in theckeditor5-utilsAPI documentation. -
comments, real-time-collaboration: Introduced
config.sidebar.overlayContainerandconfig.presenceList.overlayContainerto specify an element or shadow root for the narrow sidebar annotation balloon and presence list dropdown, respectively. Use these options when a feature runs inside a shadow root or its container clips the floating UI. Otherwise, the features useconfig.ui.overlayContainerwhen configured. -
ckeditor5: Added support for creating editors inside open shadow roots, including selection, focus, positioning, scrolling, drag and drop, floating UI, and premium features. Closed shadow roots are not supported. Closes #3891.
Load editor stylesheets into each shadow root containing editor UI and override CSS variables on the shadow host instead of
:root, as described in the shadow DOM guide. -
ai: Adjusted the content width in AI Quick Actions and AI Chat dialogs to match the text width of the editing area. The dialog width and height can now be customized with CSS custom properties.
-
ai: Added a progress bar to the AI Review panel header showing how many suggestions have been reviewed out of the total.
-
ai: Grouped AI Review sidebar checks into those that run immediately on click and those that open a collapsible options panel before running.
-
ai: Added a confirmation prompt when leaving AI Review or AI Translate with unresolved suggestions to prevent accidental loss of the session.
-
ai: Added support for inserting AI Review changes as Track Changes suggestions instead of applying them directly.
When the
TrackChangesplugin is loaded in every editor in the context, the change balloon and results list include a “Suggest” button that creates suggestions marked as AI-generated and replaces “Accept” if Track Changes mode is enabled in any editor. “Accept all” and “Reject all” remain available in the “Complete” dropdown, with “Accept all” creating suggestions in editors with Track Changes mode enabled and applying changes directly in the others. -
ai: Added a loading skeleton to AI Chat and AI Review during initialization, replacing the empty panel.
-
ai: Added information for the AI agent about the document root’s host element, whether the root accepts only inline content, and whether the editor supports soft breaks (Shift+Enter).
-
ai: Replaced the separate “Accept all” and “Exit review” buttons in AI Review with a single “Complete” dropdown, which also introduces a new “Reject all” bulk action. The dropdown is available both in the sidebar header and directly from the suggestion balloon shown in the editor content.
-
ai: Introduced
config.ai.overlayContainerto specify an element or shadow root for AI balloons, dialogs, and dropdowns, as well as the AI interface when using the'overlay'container type.Set this option when the AI interface runs inside a shadow root or its container clips or repositions floating elements. If it is not set,
config.ui.overlayContaineris used when configured. -
ai: Added a full comparison of inserted and removed text for the selected AI Review change, even when “Show changes” is disabled.
Inserted text appears next to struck-through removed text, while other changes remain highlighted.
-
core: Introduced
onEditorError()to observe unhandled editor errors and identify their source editor or context, replacing the removed Watchdog. It returns a function that unregisters the callback. It does not restart editors, save or restore data, or prevent errors from reaching the console. -
ui: Added
TooltipManager#registerBodyCollection( bodyCollection, options )andTooltipManager#unregisterBodyCollection( bodyCollection )to choose the body collection for the shared tooltip balloon. Components outside the editor can now display tooltips in their own DOM tree, including shadow roots, even without an editor on the page. See #3891. -
ui: Introduced reusable UI components for building tabbed interfaces. See #20235.
-
ui: Added the
DropdownView#panelPositionLimiterproperty to constrain automatic dropdown positioning to the visible bounds of a specified element. -
utils: Introduced the
isOfflineutility to check whether the browser is in offline mode. -
Added support for applications that enforce Trusted Types with the
require-trusted-types-for 'script'Content Security Policy directive. Closes #10845.
- ai: Fixed an issue where AI Chat shortcuts remained in the chat feed after a shortcut was used or a message was sent.
- ai: Fixed inconsistent change numbers between the AI Chat suggestion preview and the chat feed.
- ai: Fixed an issue where AI Translate and AI Review failed when a block element ended with a soft break.
- ai: Fixed the AI model selector to show only recommended models when
ai.models.displayedModelscontains only empty values, such as[ '' ]. Previously, this configuration displayed all available models. - ai: Fixed failures to merge or apply changes through
AIReviewGateway#runReview(),AIReviewGateway#runCustomReview(), andAITranslateGateway#runTranslate()when content contained nested block structures, such as tables or images with captions. - ckbox: Fixed misleading file category or server error messages shown when the internet connection was lost. Users now receive a connection error message.
- comments: Fixed annotation activation when clicking content covered by both a comment and a suggestion. The annotation higher in the sidebar now becomes active, keeping the other annotations in view.
- export-inline-styles: Fixed handling of nested CSS rules in the
stylesheetsandinlineCssconfiguration. Declarations after a nested rule now apply to the parent selector instead of being dropped, and&resolves against each selector in the parent list. Previously, parent selector lists could cause styles to apply to the wrong elements. - image: Fixed the positioning of the text alternative and custom resize balloons to anchor them to the nearest image edge when a centered balloon does not fit. Previously, balloons for left- or right-aligned images could move toward the middle of the editing area instead of staying next to the image.
- pagination: Fixed misalignment between the page break line and its label when scrolling in fullscreen mode.
- track-changes: Fixed an error in the track changes preview and
TrackChangesDatain the classic editor when the element passed toconfig.attachToor as the first argument ofClassicEditor.create()contained suggestions in its HTML. - utils: Fixed an editor crash when passing an empty
translationsconfiguration entry. Closes #20226. - widget: Fixed an issue where clicking beside a block widget that was the only child of a block quote did not change the selection. The click now selects the widget.
-
ai, comments, uploadcare: Removed header icons from the AI Assistant, comments archive, and Uploadcare dialogs to match the refreshed theme.
-
ai: Added the editor version to the configuration sent to the AI backend to support compatibility with older editor versions.
-
ai: Changed AI balloons, dialogs, and dropdowns to render in the AI interface’s DOM tree instead of
document.bodyto support shadow roots.When
config.ai.container.typeis'custom', setAITabs#containerto the AI interface’s host element or useconfig.ai.overlayContainer, which takes precedence. Otherwise, the floating UI falls back todocument.bodyand may appear unstyled inside shadow roots. The'sidebar'and'overlay'container types are unaffected.See the documentation for details on running CKEditor AI features inside shadow roots.
-
ai: Removed normalization of AI-generated content through the editor data pipeline before the AI Review and AI Translate programmatic gateways merge it.
-
emoji: Shortened the emoji search input label from “Find an emoji (min. 2 characters)” to “Find an emoji”. A message shown while typing still indicates the minimum character requirement. See #19910.
-
emoji: Updated emoji category buttons to match the tabs in the refreshed theme. See #20235.
-
footnotes: Updated the focus highlight of footnote editing fields and aligned footnote text with its number. See ckeditor/ckeditor5#20235.
-
source-editing-enhanced: Updated the source code editing area’s focus highlight and rounded corners to match other text fields. See ckeditor/ckeditor5#20235.
-
table: Aligned controls in equal-width columns in the table and table cell properties forms to match the refreshed theme. See #20235.
-
ui: Removed the header icon from the accessibility help dialog. See #19910.
-
ui: Changed editor UI scrollbar colors to match the theme instead of using browser defaults. See #20235.
-
utils: Added support for resolving points inside shadow roots with
getRangeFromMouseEvent()in Chrome and Edge 128 and later, Firefox 150 and later, and Safari 26.2 and later. Older browsers still return a range beside the shadow host because they do not support theshadowRootsoption ofDocument#caretPositionFromPoint(). See #3891. -
widget: Removed the glossy highlight from buttons for inserting a paragraph next to a widget to match the refreshed theme. See #20235.
The changelog above covers the three latest releases only. To learn about older releases:
- Read the release notes on GitHub. Every CKEditor 5 release has its own entry with the full list of changes.
- Browse the
CHANGELOG.mdfile in the CKEditor 5 repository. It collects the changelog entries of all releases in a single file, so you can search across them. - Check the update guides in the Update guides section of the sidebar. They describe breaking changes and migration steps for each major version. For versions older than v42, see the Updating from older versions guide.
- Read the release announcements on the CKEditor Ecosystem Blog.
The CKEditor 5 LTS Edition is maintained in its own release line, currently v47.x. Its releases are not listed in this guide. For their changelog, see the LTS Edition changelog in the dedicated LTS documentation. To learn more about the LTS Edition, see the CKEditor 5 LTS Edition guide.