---
title: How to build a React rich text editor with CKEditor 5
published: "2023-06-05"
updated: "2024-12-18"
publisher: Honeybadger
author: Muhammed Ali
category: JavaScript articles
tags:
  - JavaScript
  - React
  - Front End
description: "A WYSIWYG editor allows users to easily format text, add images, and more. In this article, you'll learn how to build a rich text editor in React using CKEditor 5."
url: "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 many modern web applications is the ability for users to easily create and edit text content. That's where a WYSIWYG (What You See Is What You Get) editor comes in. A WYSIWYG text editor provides a rich text-editing experience for users, allowing them to easily format text, add images and links with embedded media, and more. Rich text editors are important for any blog post that wants to display more than plain text.

In this article, you will learn how to build a React WYSIWYG editor for your application. We'll build a React rich text editor so that users can edit content in a friendly and approachable way. 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) if you want to compare your work building this simple rich text editor.

## Introduction to CKEditor 5

For our example, we'll be using CKEditor 5 to speed up the process of making a WYSIWYG editor. 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, embedded media, 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. It's the perfect starting point for making a rich text editor.

## Features of CKEditor 5

CKEditor 5 has a number of incredible features that make it a powerful and versatile rich text editor. Let's take a quick look at some of the most helpful features for users and developers.

### Advanced text formatting

A rich text editor built with CKEditor 5 allows users to apply a wide range of text formatting options, including bold, italic, underline, and more. It can also be configured to support font family and font size. If you're a developer (and if you're reading this article, you probably are!), you're probably comfortable using markdown to make text appear how you intend. Sure, some popular applications _support_ markdown, but most good web applications allow users to point and click on text options to format their text. A good React rich text editor supports this kind of text formatting, and CKEditor 5 will help us build it!

### Embedded media

Media embedding is an important feature for many text boxes, especially in media-rich applications. Sometimes it's enough to support _attaching_ an image or video, but some use cases call for allowing a user to insert their chosen media in-line. In rich text editors built with CKEditor 5, users can easily insert images, videos, and other media into their content and align, resize, and caption them. For this blog website example, the option for embedded media is very important.

### Undo/Redo

Supporting undo and redo is an important but thankless task. If your text editor does not support a quick undo and redo, it's likely to frustrate users pretty quickly. Fortunately, CKEditor 5 makes it simple to support users easily undoing and redoing 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. Not every rich text editor should feel the same, so it's a nice bonus that you can customize the appearance for your application's needs and style.

### Collaboration

CKEditor 5 has a built-in collaboration feature, allowing multiple users to work on the same document in real-time. You don't _have_ to leverage this, but it's a great head start on a really complicated (and useful!) feature set.

### Plugins and add-ons

CKEditor 5 has a wide range of available plugins and add-ons, which can be used to extend its functionality. Features like notifications, dialogs, or even integrations with other text platforms like Google Docs can all be expedited with publicly available plugins.

### Multilanguage support

CKEditor 5 supports a variety of languages, making it easy for users around the world to use your application. This is [important for every application](https://www.honeybadger.io/blog/creating-multi-language-user-interface-with-react/), even those that don't have a large international user base.

### Mobile support

CKEditor 5 is fully responsive and can be used cross-platform on both desktop and mobile devices. You won't have to make changes to the rich text editor to support different screen sizes!

## Developing a React rich text editor

Let's dive right in and make a sample app to demonstrate! We'll make a React CKEditor component called "App" that acts as a simple note-taking application. The component will use the CKEditor library to provide a rich text editor for users to create and edit notes. It will also store 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
```

Next, 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: "" }); }
```

### Rendering notes

The next step in building our rich text editor 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 rich text editor application with the following command:

```css
npm start
```

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

## Building your own rich text editor

This code creates a simple note-taking application with a React rich text editor 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. A WYSIWYG editor can be a very useful tool - we hope this guide will be of use in making your own.

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. To expand on this guide, consider adding the option for embedded media, which is explained in the documentation.

---

## Try Honeybadger for FREE

Intelligent logging, error tracking, and Just Enough APM™ in one dev-friendly platform. Find and fix problems before users notice.

[Start free trial](https://app.honeybadger.io/users/sign_up)

[See plans and pricing](https://www.honeybadger.io/plans/)
