Official React component for CKEditor 5 – the best browser-based rich text editor.
npx @tessl/cli install tessl/npm-ckeditor--ckeditor5-react@11.0.0CKEditor 5 React integration provides official React components and hooks for seamlessly integrating CKEditor 5 rich text editor into React applications. It offers comprehensive lifecycle management, error handling with watchdog functionality, multi-root editing capabilities, and cloud-based editor loading.
npm install @ckeditor/ckeditor5-reactimport {
CKEditor,
CKEditorContext,
useMultiRootEditor,
type MultiRootHookProps,
type MultiRootHookReturns
} from "@ckeditor/ckeditor5-react";For CommonJS:
const { CKEditor, CKEditorContext, useMultiRootEditor } = require("@ckeditor/ckeditor5-react");Cloud integration imports:
import {
useCKEditorCloud,
withCKEditorCloud,
loadCKEditorCloud,
type WithCKEditorCloudHocProps,
type CKEditorCloudResult,
type CKEditorCloudConfig
} from "@ckeditor/ckeditor5-react";Note: The loadCKEditorCloud, CKEditorCloudResult, and CKEditorCloudConfig types are re-exported from @ckeditor/ckeditor5-integrations-common.
import React, { useState } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import { ClassicEditor } from 'ckeditor5';
function MyEditor() {
const [data, setData] = useState('<p>Hello CKEditor 5!</p>');
return (
<CKEditor
editor={ClassicEditor}
data={data}
onReady={(editor) => {
console.log('Editor is ready to use!', editor);
}}
onChange={(event, editor) => {
const data = editor.getData();
setData(data);
console.log({ event, editor, data });
}}
onBlur={(event, editor) => {
console.log('Blur.', editor);
}}
onFocus={(event, editor) => {
console.log('Focus.', editor);
}}
/>
);
}CKEditor 5 React integration is built around several key components:
CKEditor class component and CKEditorContext provider for single and shared editor instancesuseMultiRootEditor hook for advanced multi-area editing scenariosCore React component for integrating CKEditor 5 in standard single-editor scenarios with comprehensive lifecycle management and error handling.
class CKEditor<TEditor extends Editor> extends React.Component<Props<TEditor>> {
get watchdog(): EditorWatchdog<TEditor> | EditorWatchdogAdapter<TEditor> | null;
get editor(): Editor | null;
}
interface Props<TEditor extends Editor> {
editor: {
create(...args: any): Promise<TEditor>;
EditorWatchdog: typeof EditorWatchdog;
ContextWatchdog: typeof ContextWatchdog;
};
config?: EditorConfig;
data?: string;
disabled?: boolean;
watchdogConfig?: WatchdogConfig;
disableWatchdog?: boolean;
onReady?: (editor: TEditor) => void;
onAfterDestroy?: (editor: TEditor) => void;
onError?: (error: Error, details: ErrorDetails) => void;
onChange?: (event: EventInfo, editor: TEditor) => void;
onFocus?: (event: EventInfo, editor: TEditor) => void;
onBlur?: (event: EventInfo, editor: TEditor) => void;
contextItemMetadata?: CKEditorConfigContextMetadata;
id?: any;
}Context provider for sharing CKEditor 5 context and resources between multiple editor instances, enabling efficient resource utilization and collaborative editing scenarios.
function CKEditorContext<TContext extends Context = Context>(
props: Props<TContext>
): ReactElement | null;
interface Props<TContext extends Context> {
id?: string;
isLayoutReady?: boolean;
context?: { create(...args: any): Promise<TContext> };
contextWatchdog: typeof ContextWatchdog<TContext>;
watchdogConfig?: WatchdogConfig;
config?: ContextConfig;
onReady?: (context: TContext, watchdog: ContextWatchdog<TContext>) => void;
onError?: (error: Error, details: ErrorDetails) => void;
onChangeInitializedEditors?: (editorsMap: Map<string, Editor>) => void;
}Advanced hook for managing multi-root editor instances where content is split across multiple editable areas with independent data management.
function useMultiRootEditor(props: MultiRootHookProps): MultiRootHookReturns;
interface MultiRootHookProps {
id?: any;
semaphoreElement?: HTMLElement;
isLayoutReady?: boolean;
disabled?: boolean;
data: Record<string, string>;
rootsAttributes?: Record<string, Record<string, unknown>>;
editor: typeof MultiRootEditor;
config?: Record<string, unknown>;
watchdogConfig?: WatchdogConfig;
disableWatchdog?: boolean;
disableTwoWayDataBinding?: boolean;
onReady?: (editor: MultiRootEditor) => void;
onAfterDestroy?: (editor: MultiRootEditor) => void;
onError?: (error: Error, details: ErrorDetails) => void;
onChange?: (event: EventInfo, editor: MultiRootEditor) => void;
onFocus?: (event: EventInfo, editor: MultiRootEditor) => void;
onBlur?: (event: EventInfo, editor: MultiRootEditor) => void;
}
interface MultiRootHookReturns {
editor: MultiRootEditor | null;
editableElements: Array<JSX.Element>;
toolbarElement: JSX.Element;
data: Record<string, string>;
setData: Dispatch<SetStateAction<Record<string, string>>>;
attributes: Record<string, Record<string, unknown>>;
setAttributes: Dispatch<SetStateAction<Record<string, Record<string, unknown>>>>;
}Dynamic loading and integration of CKEditor 5 builds from cloud services, enabling CDN-based distribution and reduced bundle sizes.
function useCKEditorCloud<Config extends CKEditorCloudConfig>(
config: Config
): CKEditorCloudHookResult<Config>;
function withCKEditorCloud<Config extends CKEditorCloudConfig>(
config: CKEditorCloudHocConfig<Config>
): <P extends object>(
WrappedComponent: ComponentType<WithCKEditorCloudHocProps<Config> & P>
) => ComponentType<Omit<P, keyof WithCKEditorCloudHocProps<Config>>>;
function loadCKEditorCloud<Config extends CKEditorCloudConfig>(
config: Config
): Promise<CKEditorCloudResult<Config>>;interface ErrorDetails {
phase: 'initialization' | 'runtime';
willEditorRestart?: boolean;
}
interface ContextWatchdogValue<TContext extends Context = Context> {
status: 'initializing' | 'initialized' | 'error';
watchdog?: ContextWatchdog<TContext>;
error?: any;
}
interface CKEditorConfigContextMetadata {
[key: string]: any;
}
interface EditorSemaphoreMountResult<TEditor extends Editor> {
instance: TEditor;
watchdog: EditorWatchdog<TEditor> | EditorWatchdogAdapter<TEditor> | null;
}