How to implement EditorJs with NextJs

How do you make your content stand out? You should start with some great content. Great content doesn't only means some. It should have all type of interactive data like text, images, tables, lists. Creating all of this manually for each content / blog/ article you write is obviously headache. That's why rich-text editors came into picture.

What is Rich Text?

Rich text is more exciting than plain text. It supports text formatting, such as bold, italics, and underlining, as well as different fonts, font sizes, and colored text. Rich text documents can also include page formatting options, such as custom page margins, line spacing, and tab widths. It may also refer to a multimedia document that can include images, audio and video.

What is Rich Text Editor?

An rich-text editor is the interface for editing rich text within web browsers, which presents the user with a "what-you-see-is-what-you-get" editing area. The aim is to reduce the effort for users trying to express their formatting directly as valid HTML.

There are too many rich-text editors are available out there. Some of them are listed below:

  1. EditorJs
  2. Draft.js
  3. Slate
  4. TinyMCE
  5. QuillJs

EditorJs:

It is a block-styled editor. It returns clean data output in JSON. Designed to be extendable and pluggable with a simple API.  

Let's see how to implement EditorJs with Next.js:

Step 1: Setup NextJs App

$ npx create-next-app next-editorjs

Now enter to the project directory and install the dependencies

$ cd next-editorjs
$ npm install @editorjs/editorjs @editorjs/paragraph @editorjs/header 

Create "Components" folder to the root of the app and "Editor.js" inside it.

$ mkdir Components
$ cd Components
$ touch Editor.js

Editor.js:

import EditorJS from "@editorjs/editorjs"
import Header from "@editorjs/header"
import Paragraph from "@editorjs/paragraph"
import {useRef, useEffect} from 'react'

export default function Editor () {
    // Initiate editor reference
    const editorRef = useRef(null)

    // Function to initiate editor
    const initEditor = () => {
        const editor = new EditorJS({
            holder: 'editorjs', // Editor holder
            tools: { // Tools for more see https://editorjs.io/configuration
                header: Header,
                paragraph: Paragraph
            },
            data: {
                time: Date.now(),
                blocks: [
                    {
                        type: 'header',
                        data: {
                            text: 'Hello world!',
                            level: 1
                        }
                    },
                    {
                        type: 'paragraph',
                        data: {
                            text: 'This Editor.js has been created using the wonderful https://editorjs.io WYSIWYG editor.'
                        }
                    }
                ]
            },
            onReady: () => {
                editorRef.current = editor 
                console.log('Editor.js is ready to work!')
            },
            onChange: () => {
                console.log('Editor content changed!')
            },
            onSave: () => {
                console.log('Content saved!')
            }
        })
    }
    
    // Initiate once component mounted
    useEffect(() => {
        if(!editorRef.current){
            initEditor()
        }
    })

    const handleSave = async () => {
        const output = await editorRef.current.save()
        console.log(output)
        // Your queries
    }

    return (<div>
        <div id="editorjs" />
        <button onClick={handleSave}> Save </button>
    </div>)
}

Now import and use it in any page you want, We'll be using it in 'index.js'

We'll be using nextjs's dynamic feature to import Editor.

// import modules
import dynamic from 'next/dynamic'

const Editor = dynamic(
    () => import('../Components/Editor'),
    { ssr: false } // This is needed to prevent the error: "window not defined"
)

export default function Home () {
    return <div>
            <h1> EditorJs in NextJs </h1>
            <Editor />
        </div>
   
}