Contribute to this guide

guideReact rich text editor component

npm version

React lets you build user interfaces out of individual pieces called components. CKEditor 5 can be used as one of such components.

Starting from version 6.0.0 of this package, you can use native type definitions provided by CKEditor 5. Check the details about TypeScript support.

# Quick start

# Using CKEditor 5 Builder

The easiest way to use CKEditor 5 in your React application is by configuring it with CKEditor 5 Builder and integrating it with your application. Builder offers an easy-to-use user interface to help you configure, preview, and download the editor suited to your needs. You can easily select:

  • the features you need,
  • the preferred framework (React, Angular, Vue or Vanilla JS),
  • the preferred distribution method.

You get ready-to-use code tailored to your needs!

# Setting up the project

This guide assumes you have a React project. You can create a basic React project using Vite. Refer to the React documentation to learn how to set up a project in the framework.

# Installing from npm

First, install the CKEditor 5 packages:

  • ckeditor5 – package with open-source plugins and features.
  • ckeditor5-premium-features – package with premium plugins and features.

Depending on your configuration and chosen plugins, you may need to install the first or both packages.

npm install ckeditor5 ckeditor5-premium-features

Then, install the CKEditor 5 WYSIWYG editor component for React:

npm install @ckeditor/ckeditor5-react

Use the <CKEditor> component inside your project. The below example shows how to use the component with open-source and premium plugins.

import { CKEditor } from '@ckeditor/ckeditor5-react';
import { ClassicEditor, Bold, Essentials, Italic, Mention, Paragraph, Undo } from 'ckeditor5';
import { SlashCommand } from 'ckeditor5-premium-features';

import 'ckeditor5/ckeditor5.css';
import 'ckeditor5-premium-features/ckeditor5-premium-features.css';

function App() {
    return (
        <CKEditor
            editor={ ClassicEditor }
            config={ {
                toolbar: {
                    items: [ 'undo', 'redo', '|', 'bold', 'italic' ],
                },
                plugins: [
                    Bold, Essentials, Italic, Mention, Paragraph, SlashCommand, Undo
                ],
                licenseKey: '<YOUR_LICENSE_KEY>',
                mention: { 
                    // Mention configuration
                },
                initialData: '<p>Hello from CKEditor 5 in React!</p>',
            } }
        />
    );
}

export default App;

Remember to import the necessary style sheets. The ckeditor5 package contains the styles for open-source features, while the ckeditor5-premium-features package contains the premium features styles.

# Component properties

The <CKEditor> component supports the following properties:

  • editor (required) – The Editor constructor to use.
  • data – The initial data for the created editor. See the Getting and setting data guide.
  • config – The editor configuration. See the Configuration guide.
  • id – The editor ID. When this property changes, the component restarts the editor with new data instead of setting it on an initialized editor.
  • disabled – A Boolean value. The editor is being switched to read-only mode if the property is set to true.
  • disableWatchdog – A Boolean value. If set to true, the watchdog feature will be disabled. It is set to false by default.
  • watchdogConfigConfiguration object for the watchdog feature.
  • onReady – A function called when the editor is ready with an editor instance. This callback is also called after the reinitialization of the component if an error occurred.
  • onAfterDestroy – A function called after the successful destruction of an editor instance rendered by the component. This callback is also triggered after the editor has been reinitialized after an error. The component is not guaranteed to be mounted when this function is called.
  • onChange – A function called when the editor data has changed. See the editor.model.document#change:data event.
  • onBlur – A function called when the editor was blurred. See the editor.editing.view.document#blur event.
  • onFocus – A function called when the editor was focused. See the editor.editing.view.document#focus event.
  • onError – A function called when the editor has crashed during the initialization or during the runtime. It receives two arguments: the error instance and the error details. Error details is an object that contains two properties:
    • {String} phase: 'initialization'|'runtime' – Informs when the error has occurred (during the editor or context initialization, or after the initialization).
    • {Boolean} willEditorRestart – When true, it means that the editor component will restart itself.

The editor event callbacks (onChange, onBlur, onFocus) receive two arguments:

  1. An EventInfo object.
  2. An Editor instance.

# Context feature

The @ckeditor/ckeditor5-react package provides a ready-to-use component for the context feature that is useful when used together with some CKEditor 5 collaboration features.

import { ClassicEditor, Context, Bold, Essentials, Italic, Paragraph, ContextWatchdog } from 'ckeditor5';
import { CKEditor, CKEditorContext } from '@ckeditor/ckeditor5-react';

import 'ckeditor5/ckeditor5.css';

function App() {
  return (
    <CKEditorContext context={ Context } contextWatchdog={ ContextWatchdog }>
      <CKEditor
        editor={ ClassicEditor }
        config={ {
          plugins: [ Essentials, Bold, Italic, Paragraph ],
          toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ],
        } }
        data='<p>Hello from the first editor working with the context!</p>'
        onReady={ ( editor ) => {
          // You can store the "editor" and use when it is needed.
          console.log( 'Editor 1 is ready to use!', editor );
        } }
      />

      <CKEditor
        editor={ ClassicEditor }
        config={ {
          plugins: [ Essentials, Bold, Italic, Paragraph ],
          toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ],
        } }
        data='<p>Hello from the second editor working with the context!</p>'
        onReady={ ( editor ) => {
          // You can store the "editor" and use when it is needed.
          console.log( 'Editor 2 is ready to use!', editor );
        } }
      />
    </CKEditorContext>
  );
}

export default App;

The CKEditorContext component supports the following properties:

  • context (required) – The CKEditor 5 context class.
  • contextWatchdog (required) – The Watchdog context class.
  • config – The CKEditor 5 context configuration.
  • isLayoutReady – A property that delays the context creation when set to false. It creates the context and the editor children once it is true or unset. Useful when the CKEditor 5 annotations or a presence list are used.
  • id – The context ID. When this property changes, the component restarts the context with its editor and reinitializes it based on the current configuration.
  • onReady – A function called when the context is ready and all editors inside were initialized with the context instance. This callback is also called after the reinitialization of the component if an error has occurred.
  • onError – A function called when the context has crashed during the initialization or during the runtime. It receives two arguments: the error instance and the error details. Error details is an object that contains two properties:
    • {String} phase: 'initialization'|'runtime' – Informs when the error has occurred (during the editor or context initialization, or after the initialization).
    • {Boolean} willContextRestart – When true, it means that the context component will restart itself.

An example build that exposes both context and classic editor can be found in the CKEditor 5 collaboration sample.

# How to?

# Using the document editor type

If you use the document (decoupled) editor, you need to add the toolbar to the DOM manually:

import { useEffect, useRef, useState } from 'react';
import { DecoupledEditor, Bold, Essentials, Italic, Paragraph } from 'ckeditor5';
import { CKEditor } from '@ckeditor/ckeditor5-react';

import 'ckeditor5/ckeditor5.css';

function App() {
    const editorToolbarRef = useRef( null );
    const [ isMounted, setMounted ] = useState( false );
    
    useEffect( () => {
        setMounted( true );

        return () => {
            setMounted( false );
        };
    }, [] );

    return (
        <div>
            <div ref={ editorToolbarRef }></div>
            <div>
                { isMounted && (
                    <CKEditor
                        editor={ DecoupledEditor }
                        data='<p>Hello from CKEditor 5 decoupled editor!</p>'
                        config={ {
                            plugins: [ Bold, Italic, Paragraph, Essentials ],
                            toolbar: [ 'undo', 'redo', '|', 'bold', 'italic' ]
                        } }
                        onReady={ ( editor ) => {
                            if ( editorToolbarRef.current ) { 
                                editorToolbarRef.current.appendChild( editor.ui.view.toolbar.element );
                            }
                        }}
                        onAfterDestroy={ ( editor ) => {
                            if ( editorToolbarRef.current ) {
                                Array.from( editorToolbarRef.current.children ).forEach( child => child.remove() );
                            }
                        }}
                    />
                ) }
            </div>
        </div>
    );
}

export default App;

# Using the editor with collaboration plugins

We provide a few ready-to-use integrations featuring collaborative editing in React applications:

It is not mandatory to build applications on top of the above samples, however, they should help you get started.

# Localization

CKEditor 5 supports multiple UI languages, and so does the official React component. Follow the instructions below to translate CKEditor 5 in your React application.

Similarly to CSS style sheets, both packages have separate translations. Import them as shown in the example below. Then, pass them to the translations array inside the config prop in the CKEditor 5 component.

import { ClassicEditor } from 'ckeditor5';
import { CKEditor } from '@ckeditor/ckeditor5-react';
// More imports...

import coreTranslations from 'ckeditor5/translations/es.js';
import premiumFeaturesTranslations from 'ckeditor5-premium-features/translations/es.js';

// Style sheets imports...

function App() {
    return (
        <CKEditor
            editor={ ClassicEditor }
            config={ {
                translations: [ coreTranslations, premiumFeaturesTranslations ],
                initialData: '<p>Hola desde CKEditor 5 en React!</p>',
            } }
        />
    );
}

export default App;

For more information, please refer to the Setting the UI language guide.

# Contributing and reporting issues

The source code of rich text editor component for React is available on GitHub in https://github.com/ckeditor/ckeditor5-react.