How to build a rich text editor for your React app with CKEditor 5
Tags: javascript, react
Published: 2024-02-20 08:00:00

*This article was originally written by [Muhammed Ali](https://www.honeybadger.io/blog/authors/muhammedali/) on the [Honeybadger Developer Blog](https://www.honeybadger.io/blog/build-rich-text-editor-for-your-react-app/).*

Creating a dynamic, user-friendly interface for your React application can be a challenging task. One of the most important aspects of any application is the ability of users to easily create and edit content. That's where a WYSIWYG (What You See Is What You Get) editor comes in. A WYSIWYG editor provides a rich text-editing experience for users, allowing them to easily format text, add images and links, and more.

In this article, you will learn how to build a WYSIWYG editor for your React application. With this, you can go as far as creating something like Google Docs for your application. If you are trying to build a blog, you will not need to touch the code when you want to publish an article. Here, we will build a note application that stores its data on the local storage and then displays the created notes.

You can find the complete code on [GitHub](https://github.com/khabdrick/react-ckeditor5).

## Introduction to CKEditor 5

CKEditor 5 is a JavaScript-based rich text editor that provides a user-friendly interface for creating and editing content. It is designed to be easily integrated into web applications and can be customized to suit the specific needs of a project. CKEditor 5 offers a wide range of features, such as text formatting, media embedding, undo/redo, and more. It also supports a variety of languages and can be used on both desktop and mobile devices. It's an open-source project that can be easily integrated into your web application and customized according to your needs.

### Features of CKEditor 5

CKEditor 5 has a variety of features that make it a powerful and versatile text editor. Here are some of the main features:

- Advanced text formatting: CKEditor 5 allows users to apply a wide range of text formatting options, including bold, italic, underline, and more.
- Media embedding: Users can easily insert images, videos, and other media into their content and align, resize, and caption them.
- Undo/Redo: Users can easily undo and redo any changes they make to their content.
- Customizable interface: CKEditor 5 has a customizable interface that can be tailored to the specific needs of a project.
- Collaboration: CKEditor 5 has a built-in collaboration feature, allowing multiple users to work on the same document in real time.
- Plugins and add-ons: CKEditor 5 has a wide range of available plugins and add-ons, which can be used to extend its functionality.
- Multilanguage support: CKEditor 5 supports a variety of languages, making it easy to use for users around the world.
- Mobile support: CKEditor 5 is fully responsive and can be used on both desktop and mobile devices.

## Developing the editor for the React app

This code is a React component called "App" that creates a simple note-taking application. The component uses the CKEditor library to provide a rich text editor for users to create and edit notes, and it stores the notes in the browser's local storage so that they persist even if the user closes the application or refreshes the page.

Start by creating a new project using **`create-react-app`**:

```bash
npx create-react-app app
cd app
```

Now install the necessary dependencies for CKeditor 5:

```bash
npm install --save @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic
```

Remove what you have in the *App.js* file. Then your component will begin by importing the necessary libraries and modules, including React, the CKEditor library, and a specific version of the CKEditor called `ClassicEditor`. It also imports a CSS file called *App.css*, which is used to style the component.

```js
import React, { Component } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import './App.css';
```

The component's constructor method initializes the component's state with an empty array called `notes` to store the notes and an empty string called `currentNote` to store the note currently being edited.

```js
class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            notes: [],
            currentNote: ""
    }

}

```

The component's `componentDidMount()` method is called when the component is first rendered, and it retrieves any notes that were previously saved in local storage and sets the component's "notes" state accordingly.

```js
componentDidMount() {
    // Retrieve notes from local storage
    let storedNotes = localStorage.getItem("notes");
    if (storedNotes) {
        this.setState({ notes: JSON.parse(storedNotes) });
    }
}

```

The `handleEditorChange` method updates the component's `currentNote` state with the latest data from the CKEditor whenever the user makes changes to the note being edited.

```js
handleEditorChange = (event, editor) => {
    this.setState({ currentNote: editor.getData() });
}

```

The `handleSaveNote` method is called when the user clicks the "Save Note" button. It adds the current note to the component's `notes` state and saves the updated notes to local storage. Then, it clears the `currentNote` state so that the user can start writing a new note.

```js
handleSaveNote = () => {
    // Add the current note to the notes array
    let newNotes = [...this.state.notes, this.state.currentNote];
    this.setState({ notes: newNotes });

    // Save the notes array to local storage
    localStorage.setItem("notes", JSON.stringify(newNotes));

    // Clear the current note
    this.setState({ currentNote: "" });
}

```

The next step is to render the notes array in the UI. This is done in the `render()` method of the `App` component. Inside the `render()` method, we have a `div` element with the class of `notes-container`. Inside this `div`, we use the `map()` function to iterate through the `notes` array and create a new `div` element for each note. The `key` prop is set to the index of the note in the array to ensure that React can keep track of the elements.

```js
render() {
    return (
      <div className="App">
          <h2>Note Application</h2>
          <CKEditor
              editor={ ClassicEditor }
              data={this.state.currentNote}
              onChange={ this.handleEditorChange }
        
          />
          <button onClick={this.handleSaveNote}>Save Note</button>
          <h3>Saved Notes:</h3>
          <div className="notes-container">
              {this.state.notes.map((note, index) => {
                  return <div key={index} className="note" dangerouslySetInnerHTML={{__html: note}} />
              })}
          </div>
      </div>
  );
}
```

The `dangerouslySetInnerHTML` prop is used to render the HTML content of the note inside the `div`. This is a React feature that should be used with caution, as it can introduce security vulnerabilities if not used properly.

Finally, at the bottom of the code, the `App` component is exported so that it can be used in other parts of the application.

```jsx
export default App;
```

Now, paste the following code in *App.css*. This is just basic styling for the note application.

```css
.notes-container {
  margin: 20px 0;
  padding: 20px;
  border: 1px solid rgb(88, 80, 80);
  border-radius: 5px;
}

.note {
  margin: 10px 0;
  padding: 10px;
  border-radius: 5px;
  background-color: #a7a5a5;
}

.App {
  border: 5px solid gray;
  padding: 50px;
  border-radius: 5px;
}
```

Now, you can run your application with the following command:

```css
npm start
```

![complete application](https://www.honeybadger.io/images/blog/posts/build-rich-text-editor-for-your-react-app/app.png)

## Conclusion

This code creates a simple note-taking application that allows the user to create and save notes using the CKEditor5 rich text editor. The notes are stored in the browser's local storage so that they persist even when the user closes the browser or refreshes the page. The notes are displayed in a list in the UI and can be rendered with their original formatting.

You can learn more about CKEditor 5 by reading the [official documentation](https://ckeditor.com/docs/ckeditor5/latest/index.html) and see everything it provides and its limitations.