How to build a rich text editor for your React app with CKEditor 5
Honeybadger Staff
Posted on February 20, 2024
This article was originally written by Muhammed Ali on the Honeybadger Developer Blog.
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.
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
:
npx create-react-app app
cd app
Now install the necessary dependencies for CKeditor 5:
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.
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.
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.
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.
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.
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.
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.
export default App;
Now, paste the following code in App.css. This is just basic styling for the note application.
.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:
npm start
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 and see everything it provides and its limitations.
Posted on February 20, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024
November 28, 2024