Home / Blog / How to integrate Editor JS in NextJs App Router and ReactJs

How to integrate Editor JS in NextJs App Router and ReactJs

5 min read.Apr 16, 2024

How to integrate Editor JS in NextJs App Router and ReactJs

A guide to integrate editorJs in NextJs and React. Adding multiple editorjs tools like heading, Hyperlink image etc.

Table of Content

  1. Installation

  2. Configurations for EditorJs

  3. Building up a reusable Editor Component

  4. How to use it on React

  5. How to use it on NextJs App Router

  6. Source Code

Lets begin the journey to implement EditorJs.

Installation

Install Editor Js

npm i @editorjs/editorjs

install different tools of editorJs

npm i @editorjs/checklist @editorjs/code @editorjs/embed @editorjs/header @editorjs/image @editorjs/inline-code @editorjs/list @editorjs/paragraph @editorjs/quote editorjs-hyperlink

Configurations for EditorJS

Intialize a React and NextJs project

npx create-react-app editorjs-react

npx create-next-app editorjs-nextjs

creating an editor js config file

//editorjs.config.js

import CheckList from "@editorjs/checklist";
import Code from "@editorjs/code";
import Embed from "@editorjs/embed";
import InlineCode from "@editorjs/inline-code";
import Hyperlink from "editorjs-hyperlink";
import List from "@editorjs/list";
import Quote from "@editorjs/quote";
import Paragraph from "@editorjs/paragraph";
import Header from "@editorjs/header";
import Image from '@editorjs/image';

const EDITOR_CONFIG = {

    code: Code,

    header: {
        class: Header,
        config: {
            placeholder: 'Enter a Heading',
            levels: [2, 3, 6], //configure heading tags (e.g. h1,h2,h3 etc) to be shown in editorjs component
            defaultLevel: 2
        }
    },

    hyperlink: {
        class: Hyperlink,
        config: {
            shortcut: 'CMD+L',
            target: '_blank',
            rel: 'nofollow',
            availableTargets: ['_blank', '_self'],
            availableRels: ['author', 'noreferrer'],
            validate: false,
        }
    },

    paragraph: {
        class: Paragraph,
        inlineToolbar: true
    },

    image: {
        class: Image,
        config: {
            uploader: {
                uploadByFile: (file) => { //this function will be triggered when image gets selected
                    return {
                        success: 1,
                        file: {
                            // i'm creating a blob from the image file you can do your api call to upload the image somewhere and store the actual url
                            url: URL.createObjectURL(file),
                            raw: file
                        }
                    }
                }
            }
        }

    },

    checklist: CheckList,

    embed: Embed,

    inlineCode: InlineCode,

    list: {
        class: List,
        inlineToolbar: true
    },

    quote: Quote
}

export { EDITOR_CONFIG }

Building up an Reusable Editor Component

//Editor.jsx

'use client';
import EditorJS from "@editorjs/editorjs";
import classes from '../styles/editorjs.module.css';
import { useEffect, useRef } from "react";
import { EDITOR_CONFIG } from "../configs/editorjs.config";

const Editor = ({ value, onChange, holder }) => {

    const ref = useRef();

    useEffect(() => {

        if (!ref.current) {
            const editor = new EditorJS({
                holder: holder,
                tools: EDITOR_CONFIG,
                placeholder: 'Write an Amazing Blog',
                data: value,
                async onChange(api, event) {
                    const data = await api.saver.save();
                    onChange(data);
                },
                i18n: {
                    toolNames: {
                        Hyperlink: 'Link'
                    },
                    tools: {
                        hyperlink: {
                            Save: 'Salvar',
                            'Select target': 'Seleziona destinazione',
                            'Select rel': 'Wählen rel'
                        }
                    }
                }
            })

            ref.current = editor;
        }

        return () => {
            if (ref.current && ref.current.destroy) {
                ref.current.destroy();
            }
        };
    }, []);


    return (
        <div id={holder} className={classes.editorjs} py={4} border={'1px solid rgb(190, 195, 224, 0.4)'} borderRadius={6} />
    )
}


export default Editor;

How to use it on React

// App.jsx

import { useState } from 'react'
import Editor from './components/Editor'

const App = () => {

  const [data, setData] = useState('');

  return (
    <div>
      <Editor value={data} onChange={setData} holder="editorjs-container" />
    </div>
  )
}

export default App

How to use it on NextJs App Router

'use client';
import dynamic from "next/dynamic";
import { useState } from "react";

const Editor = dynamic(() => import("@/components/Editor"), { ssr: false });

const page = () => {

  const [data, setData] = useState('');

  return (
    <div>
      <Editor value={data} onChange={setData} holder="editorjs-container" />
    </div>
  )
}

export default page;

Source Code

Check Source Code

Published InJavaScript & NodeJs

A deep dive into modern JavaScript practices, frameworks, performance optimization, and clean coding techniques