Setting up a basic rich text editor in React

shaerins profile image Sharon Rachel Levin Updated on ・3 min read

As mentioned in my previous post, I've been working on a blogging app. I started writing up some posts of my own to document the experience, but quickly realized that the post content was not only plain-looking, but hard to read and unorganized.

Here's what my posts were looking like:

An image of a blog post. It contains a list of items using whitespace and asterisks in an attempt to organize the content.

Here's what I wanted them to look like!

An image of a blog post that contains a list with bulletpoints, and the headers are bigger and bolded. Certain important words and phrases are bolded/italicized.

I did a lot of research trying to find a straightforward library that would let me achieve the above. In my case, CKEditor 5 ended up being the easiest to implement in my opinion. Out of the box it is very user-friendly and has a nice, minimal design. Some features I appreciate are keyboard shortcuts (like Ctrl+B/CMD+B for bold or Ctrl+I/CMD+I for italic) and auto-formatting. Here's how I was able to set up a very basic rich text editor using CKEditor.

First up, choose your build

They have several different build options depending on what you're using it for, but in my case I used the Classic Build. Here's what the toolbar looks like:

CKEditor5's Classic Build toolbar

As you can see, it gives you the option to insert images, but you have to set up your own adapter to do so. I'll go over how to set that up in another post!

Install CKEditor and your build

Using npm:

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

Or using yarn:

yarn add @ckeditor/ckeditor5-react @ckeditor/ckeditor5-build-classic

Set up a component that will handle your form and text input

Import CKEditor and ClassicEditor (or whatever build you chose), then call on the CKEditor component inside your form. The component takes two necessary props: editor and onChange.

All you have to do is specify what build you're using in the editor prop, in this example it's editor={ClassicEditor}.

The onChange prop can be used to grab the stylized text. It uses a function that takes event and editor. We can use editor.getData() to grab that text. In my case, I'm storing it in my body state.

Note: For me, this component will be used in multiple parent components and I'm handling the form submission differently in each one, which is why I'm passing onSubmit as a prop. Your form submission might be different.
// TextEditor.js

import React, { useState } from 'react'
import CKEditor from '@ckeditor/ckeditor5-react'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'

const TextEditor = ({ onSubmit }) => {
    const [body, setBody] = useState('')

    const handleSubmit = (e) => {
        onSubmit({ body })

    return (
        <form onSubmit={handleSubmit}>
                onChange={(event, editor) => {
                    const data = editor.getData()
            <button type='submit'>Submit</button>

export default TextEditor

That's all you need to have a simple working rich text editor using React and CKEditor 5. The data I'm storing in body is in HTML, so if you want to display the output elsewhere you need to use dangerouslySetInnerHTML. Keep reading if you want to configure the toolbar plugins!

Configuring the toolbar plugins

Let's say you just want a very basic editor, and don't want to have the option to insert tables or images/media. In that case, you can set up a configuration object and pass it to your build's defaultConfig. You can also use this to separate the different sections and further personalize the toolbar to your needs.

// editorConfig.js

export const config = {
    toolbar: {
        items: [

Once the config is set up, I'm just importing it into my TextEditor file. Inside the component before the return statement, just pass the config in with ClassicEditor.defaultConfig = config.

// TextEditor.js

import React, { useState } from 'react'
import CKEditor from '@ckeditor/ckeditor5-react'
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'

// import the config here
import { config } from './editorConfig'

const TextEditor = ({ onSubmit }) => {
    const [body, setBody] = useState('')

        // and then plug it in here
    ClassicEditor.defaultConfig = config

    const handleSubmit = (e) => {
        // ...

    return (
        // ...

export default TextEditor

And that's it! Here's what mine looks like in my app:

The 'Create New Post' page of my app. Shows the CKEditor toolbar and some sample text that display it's usage.

Thanks for reading πŸ˜„

Posted on by:


Editor guide

Good work, yo!!!
why don't you think for a "work together" thing if you want. i am also learning react js and posting content on this platform. i will follow you on twitter and will say Hi.


thanks 😊 and sure, followed you!


Yes, texted you already in private twitter messages. waiting for reply.
and yeah thank you for following.


This looks so cool.


thanks πŸ™‚


Have u tried implementing a hovering toolbar?


i haven't personally , but ckeditor offers a couple of 'balloon' builds that i think can be set up similarly!