CKEditor 5 provides several ready-to-use editor implementations, each with different UI approaches and integration patterns. All editors share the same core functionality but differ in their user interface and integration methods.
Traditional editor with a toolbar positioned above the editing area. Best for dedicated editing interfaces.
/**
* Classic editor implementation with fixed toolbar above the editing area
*/
class ClassicEditor extends Editor {
/**
* Creates a classic editor instance
* @param sourceElementOrData - DOM element to replace or initial data string
* @param config - Editor configuration
* @returns Promise resolving to ClassicEditor instance
*/
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<ClassicEditor>;
/**
* Destroys the editor instance and restores the original element
*/
destroy(): Promise<unknown>;
}Usage Example:
import { ClassicEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
ClassicEditor
.create(document.querySelector('#editor'), {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic'],
language: 'en'
})
.then(editor => {
console.log('Classic editor ready', editor);
// Get editor data
const data = editor.getData();
// Set editor data
editor.setData('<p>Hello world!</p>');
})
.catch(error => {
console.error('Error creating classic editor:', error);
});Editor that replaces an element in place when focused. Ideal for seamless content editing within existing layouts.
/**
* Inline editor implementation that activates on element focus
*/
class InlineEditor extends Editor {
/**
* Creates an inline editor instance
* @param sourceElementOrData - DOM element to make editable or initial data string
* @param config - Editor configuration
* @returns Promise resolving to InlineEditor instance
*/
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<InlineEditor>;
/**
* Destroys the editor instance
*/
destroy(): Promise<unknown>;
}Usage Example:
import { InlineEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
InlineEditor
.create(document.querySelector('#inline-editor'), {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic']
})
.then(editor => {
console.log('Inline editor ready', editor);
})
.catch(error => {
console.error('Error creating inline editor:', error);
});Editor with a contextual toolbar that appears in a balloon when text is selected. Provides a clean, distraction-free editing experience.
/**
* Balloon editor implementation with contextual floating toolbar
*/
class BalloonEditor extends Editor {
/**
* Creates a balloon editor instance
* @param sourceElementOrData - DOM element to replace or initial data string
* @param config - Editor configuration
* @returns Promise resolving to BalloonEditor instance
*/
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<BalloonEditor>;
/**
* Destroys the editor instance
*/
destroy(): Promise<unknown>;
}Usage Example:
import { BalloonEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
BalloonEditor
.create(document.querySelector('#balloon-editor'), {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic']
})
.then(editor => {
console.log('Balloon editor ready', editor);
})
.catch(error => {
console.error('Error creating balloon editor:', error);
});Editor where the toolbar and editing area are separate, allowing for flexible UI layouts and custom positioning.
/**
* Decoupled editor implementation with separate toolbar and editing area
*/
class DecoupledEditor extends Editor {
/**
* The decoupled editor's toolbar view
*/
readonly ui: DecoupledEditorUI;
/**
* Creates a decoupled editor instance
* @param sourceElementOrData - DOM element to replace or initial data string
* @param config - Editor configuration
* @returns Promise resolving to DecoupledEditor instance
*/
static create(
sourceElementOrData: HTMLElement | string,
config?: EditorConfig
): Promise<DecoupledEditor>;
/**
* Destroys the editor instance
*/
destroy(): Promise<unknown>;
}
interface DecoupledEditorUI extends EditorUI {
/**
* The toolbar view of the decoupled editor
*/
readonly toolbar: ToolbarView;
}Usage Example:
import { DecoupledEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
DecoupledEditor
.create(document.querySelector('#decoupled-editor'), {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic']
})
.then(editor => {
// Add the toolbar to a custom container
const toolbarContainer = document.querySelector('#toolbar-container');
toolbarContainer.appendChild(editor.ui.toolbar.element);
console.log('Decoupled editor ready', editor);
})
.catch(error => {
console.error('Error creating decoupled editor:', error);
});Advanced editor supporting multiple editing roots for complex document structures and collaborative editing scenarios.
/**
* Multi-root editor implementation supporting multiple editing areas
*/
class MultiRootEditor extends Editor {
/**
* Creates a multi-root editor instance
* @param sourceElementsOrData - Object mapping root names to DOM elements or data strings
* @param config - Editor configuration
* @returns Promise resolving to MultiRootEditor instance
*/
static create(
sourceElementsOrData: Record<string, HTMLElement | string>,
config?: EditorConfig
): Promise<MultiRootEditor>;
/**
* Adds a new root to the editor
* @param rootName - Name of the new root
* @param element - DOM element for the new root
*/
addRoot(rootName: string, element?: HTMLElement): void;
/**
* Removes a root from the editor
* @param rootName - Name of the root to remove
*/
detachRoot(rootName: string): void;
/**
* Gets data from specific root
* @param rootName - Name of the root
* @returns Root data as HTML string
*/
getData(options?: { rootName?: string }): string;
/**
* Sets data for specific root
* @param data - HTML data to set
* @param rootName - Name of the root
*/
setData(data: string, rootName?: string): void;
/**
* Destroys the editor instance
*/
destroy(): Promise<unknown>;
}Usage Example:
import { MultiRootEditor, Essentials, Paragraph, Bold, Italic } from 'ckeditor5';
MultiRootEditor
.create({
header: document.querySelector('#header'),
content: document.querySelector('#content'),
footer: document.querySelector('#footer')
}, {
plugins: [Essentials, Paragraph, Bold, Italic],
toolbar: ['bold', 'italic']
})
.then(editor => {
console.log('Multi-root editor ready', editor);
// Get data from specific root
const headerData = editor.getData({ rootName: 'header' });
// Set data for specific root
editor.setData('<p>New content</p>', 'content');
// Add new root dynamically
const sidebar = document.createElement('div');
document.body.appendChild(sidebar);
editor.addRoot('sidebar', sidebar);
})
.catch(error => {
console.error('Error creating multi-root editor:', error);
});All editor implementations extend the base Editor class, providing common functionality:
/**
* Base editor class providing common functionality for all editor implementations
*/
abstract class Editor {
/**
* The data model of the editor
*/
readonly model: Model;
/**
* The editing controller
*/
readonly editing: EditingController;
/**
* The data controller
*/
readonly data: DataController;
/**
* The user interface of the editor
*/
readonly ui: EditorUI;
/**
* The keystroke handler
*/
readonly keystrokes: EditingKeystrokeHandler;
/**
* The commands collection
*/
readonly commands: CommandCollection;
/**
* The plugins collection
*/
readonly plugins: PluginCollection;
/**
* The configuration object
*/
readonly config: Config;
/**
* The locale object
*/
readonly locale: Locale;
/**
* Sets the editor data
* @param data - HTML string to set as editor content
*/
setData(data: string): void;
/**
* Gets the editor data
* @param options - Options for data retrieval
* @returns HTML string representing editor content
*/
getData(options?: {
rootName?: string;
trim?: 'empty' | 'none'
}): string;
/**
* Executes a command
* @param commandName - Name of the command to execute
* @param args - Command arguments
* @returns Command execution result
*/
execute(commandName: string, ...args: any[]): any;
/**
* Focuses the editor
*/
focus(): void;
/**
* Destroys the editor instance
* @returns Promise that resolves when destruction is complete
*/
destroy(): Promise<unknown>;
/**
* Creates an editor instance (implemented by subclasses)
*/
static create(...args: any[]): Promise<Editor>;
}