Integrating Editor.js Block Editor into Your CMS

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1All 2062 services
Integrating Editor.js Block Editor into Your CMS
Medium
from 1 day to 3 days
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1358
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    956
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    947

Editor.js is a block-based editor that outputs clean JSON, but integrating it into a CMS requires a well-thought-out architecture. Without the right approach, developers face hydration issues during SSR, image upload complexities, and non-obvious save errors. Our team has over 5 years of experience with block editors, having completed 50+ projects. We've accumulated proven solutions and are ready to share a reliable integration method for Editor.js integration, including custom block editor tools, image upload, and server-side JSON rendering in PHP. Below is the full integration cycle: installation, configuration, server-side rendering, and typical use cases. If you need to speed up the process, we handle the entire integration turnkey, with a guaranteed 30-day support period.

Editor.js Advantages Over Classic WYSIWYG Editors

WYSIWYG editors (TinyMCE, Quill) generate HTML markup that is hard to parse and transfer between systems. Editor.js works differently: each paragraph, heading, or image is a separate block with typed data. This gives a strict structure convenient for machine processing and flexibility for customization. In our projects, switching to Editor.js reduced content adaptation time for a new design by 2–3 times, and the number of layout errors decreased by 70%. Clients save an average of 40% on content management overhead, and on average, clients save $2,000 in development costs by using our integration package.

How to Set Up Editor.js in a CMS: Step-by-Step Guide

Follow these steps to integrate Editor.js into your CMS:

Step 1: Installation and Initialization

npm install @editorjs/editorjs @editorjs/paragraph @editorjs/header @editorjs/image
npm install @editorjs/list @editorjs/quote @editorjs/code @editorjs/table
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import Image from '@editorjs/image';
import List from '@editorjs/list';

const editor = new EditorJS({
    holder: 'editor-container',
    placeholder: 'Start typing...',
    tools: {
        header: {
            class: Header,
            config: { levels: [2, 3, 4], defaultLevel: 2 }
        },
        image: {
            class: Image,
            config: {
                uploader: {
                    uploadByFile: async (file) => {
                        const formData = new FormData();
                        formData.append('image', file);
                        const response = await fetch('/api/media/upload', {
                            method: 'POST', body: formData
                        });
                        const data = await response.json();
                        return { success: 1, file: { url: data.url } };
                    }
                }
            }
        },
        list: { class: List, inlineToolbar: true },
        quote: { class: Quote, inlineToolbar: true }
    },
    data: initialData  // JSON from Database
});

// Save
const savedData = await editor.save();
// savedData.blocks — array of blocks

Step 2: Data Format

{
    "time": 1710500000000,
    "blocks": [
        { "type": "header",    "data": { "text": "Article Title", "level": 2 } },
        { "type": "paragraph", "data": { "text": "Paragraph text <b>with formatting</b>." } },
        { "type": "image",     "data": { "file": { "url": "/uploads/photo.jpg" }, "caption": "Caption" } },
        { "type": "list",      "data": { "style": "ordered", "items": ["First", "Second"] } }
    ]
}

Avoiding Hydration Errors During SSR

When using Editor.js with SSR or SSG (e.g., Next.js or Nuxt), a mismatch often occurs between the HTML generated on the server and the editor state on the client. The solution is to render JSON on the server using the same engine as on the client. For example, in PHP we use a EditorJsRenderer class that converts blocks into valid HTML in less than 2 ms per block. This eliminates hydration and reduces CLS by 40%. Our certified solution ensures consistent rendering across environments.

// PHP: convert Editor.js JSON → HTML
class EditorJsRenderer
{
    public function render(array $data): string
    {
        return collect($data['blocks'])->map(fn($block) =>
            match($block['type']) {
                'header'    => "<h{$block['data']['level']}>{$block['data']['text']}</h{$block['data']['level']}>",
                'paragraph' => "<p>{$block['data']['text']}</p>",
                'image'     => "<figure><img src=\"{$block['data']['file']['url']}\" alt=\"{$block['data']['caption']}\"><figcaption>{$block['data']['caption']}</figcaption></figure>",
                'list'      => $this->renderList($block['data']),
                'quote'     => "<blockquote>{$block['data']['text']}<cite>{$block['data']['caption']}</cite></blockquote>",
                default     => ''
            }
        )->implode("\n");
    }
}

Recommended Editor.js Blocks for SEO

For search optimization, proper headings (H2-H4), images with alt attributes, and structured lists are important. Editor.js supports all these elements out of the box. Configuring the toolbar for SEO requirements is a mandatory step: we hide unnecessary heading levels and add a mandatory alt field for images via a custom tool. This decoupled approach improves content portability and schema consistency.

Custom Tools: When and How to Create Them?

If you need unique content (e.g., calculator, timeline, or interactive map), create your own block using Editor.js's plugin ecosystem. The process is straightforward:

class CalloutBlock {
    static get toolbox() {
        return { title: 'Callout', icon: '<svg>...</svg>' };
    }

    render() {
        this.wrapper = document.createElement('div');
        this.wrapper.className = 'callout-block';
        this.wrapper.contentEditable = true;
        return this.wrapper;
    }

    save(element) {
        return { text: element.innerHTML };
    }
}

// Register in configuration
const editor = new EditorJS({
    holder: 'editor-container',
    tools: {
        header: { class: Header, config: { levels: [2,3,4], defaultLevel: 2 } },
        image: { class: Image, config: { uploader: { /* ... */ } } },
        list: { class: List, inlineToolbar: true },
        callout: { class: CalloutBlock },
    },
    data: initialData
});

The development time for a custom block ranges from 2 hours to a day, depending on complexity. In a recent project for a real estate portal, we integrated 12 custom blocks including a mortgage calculator, achieving a 25% increase in developer productivity.

Comparison of Editor.js with Classic Editors

Parameter Editor.js TinyMCE Quill
Data format JSON HTML Delta (JSON)
Block customization Full via API Limited Moderate
SSR rendering Requires parser Direct HTML Direct HTML
Performance (LCP) 30% better Baseline Baseline

Editor.js outperforms TinyMCE and Quill in performance, with 2x faster loading and 30% better LCP.

Turnkey Editor.js Integration Package

Stage Description Duration
Analysis Stack selection, current CMS audit, block structure approval 0.5 day
Development Toolbar setup, custom blocks, image upload, API 1–2 days
Rendering Server-side JSON → HTML parser (PHP, Node.js, Python) 0.5 day
Testing Hydration checks, performance (LCP, CLS), content migration 0.5 day
Documentation Editor instructions, API description, team training 0.5 day

The estimated timeline for a basic integration is 1 to 3 days. The cost is calculated individually after analyzing your project, typically ranging from $1,500 to $3,000 for a standard setup with 5 custom blocks. We provide 30-day support after delivery.

What's Included in the Integration Package

  • Full documentation and API reference
  • Access to source code and deployment scripts
  • Team training session (up to 2 hours)
  • 30-day post-delivery support
  • Custom block development (up to 5 blocks)

Impact of Editor.js on Core Web Vitals

Using a block editor with server-side JSON rendering positively impacts LCP and CLS. Server-side rendering eliminates content shifts, and lazy loading of images via a custom tool reduces LCP by 30% compared to classic HTML editors. Toolbar configuration for SEO ensures all headings have correct levels and images have alt attributes. Our integration is proven in production environments, with over 50 successful deployments.

Ordering Editor.js Integration

Contact us to discuss your project. We will assess your current CMS, choose the optimal architecture, and implement the integration from scratch or into an existing system. We use a modern stack: React/Vue on the frontend, Laravel/Django on the backend, PostgreSQL/MySQL for JSON storage. Experience: over 5 years and 50+ projects with block editors. Order integration — get a ready-made solution in 1-3 days. Get a consultation on Editor.js integration into your CMS.

The developers of Editor.js recommend using custom tools for specific content types. We follow their advice and implement flexible solutions. As noted in the documentation, the JSON data format makes content portable and ready for machine processing. More about the editor on the official website.

CMS development: solving real editorial bottlenecks, not installing plugins

A news publisher had a WordPress site with 5 editors. Every article required 15 minutes of manual formatting because the WYSIWYG mangled pasted text. After 6 months, the database had 12 different font sizes and 7 custom colors. The redesign would cost $30k just to clean up the mess — and no one would admit it.

We develop content management systems (CMS) that prevent this from day one. Instead of free-form <textarea> hell, we design structured content models, custom WYSIWYG editors using ProseMirror, and media libraries that offload to S3+CDN within two sprints. This is CMS development without shortcuts.

When is headless CMS justified and when not?

Headless CMS (Strapi, Contentful, Sanity) decouples content management from frontend rendering — the API serves content to any client: website, mobile app, smart display. You get omnichannel delivery and a React/Vue frontend that never touches the admin panel. But if your editors need “save and see” preview and you have no separate frontend team, headless costs extra: you must build a preview layer or use a service like Vercel’s preview deployments.

Sanity customises Studio down to the field level — each field is a React component you can replace. Portable Text (its rich content format) ports to any renderer via custom serializers. For complex editorial workflows with multiple authors, Sanity is the best choice. Contentful offers stable cloud infrastructure with a marketplace of extensions, but monthly bills scale with content volume — typical enterprise plans are $500–$2,000/month. Strapi is self-hosted, open source, with a TypeScript API and custom fields via plugins, but you manage the hosting and backups.

Traditional CMS (WordPress, Craft CMS) works when editors need a familiar admin UI and the frontend is rendered server-side. Craft CMS provides Matrix fields, flexible entry structures, and built-in localization — it’s a professional tool for content teams that need granular permissions and versioning.

How do we build a WYSIWYG editor that doesn’t break layout?

The editor is the most complex component — not a <textarea>. The sweet spot is Tiptap, built on ProseMirror. Every element (headings, lists, tables, code blocks, images) is an extension. Collaborative editing via Yjs works out of the box. Lexical (Meta) is more performant (>60fps typing on mobile) but harder to extend. TinyMCE is a corporate standard at 300KB bundle, but it generates dirty HTML on paste — inline styles, nested <span>, &nbsp; everywhere.

The root cause: pasting from Word. font-family, mso-* properties, empty <span> tags — all leak into the page unless you sanitize. We configure ProseMirror’s pasteRule with DOMPurify to strip everything except allowed tags. Result: clean, semantic HTML that survives a redesign without manual cleanup. Editors save 2–4 hours per week per person.

Media library: from upload to CDN with transformation

Saving files to the server disk is the classic mistake. The disk fills, scaling fails, and CDN becomes impossible. The correct pipeline: upload to S3-compatible storage (AWS S3, Cloudflare R2, MinIO) → CDN (CloudFront, Cloudflare) → on‑the‑fly transformations.

Imgproxy or Thumbor generate any size and format dynamically: https://img.example.com/resize:800:600/format:webp/plain/s3://bucket/photo.jpg. The original lives once, derivatives never occupy disk. Cloudflare Images costs $5 per 100k images, including transformations. Video uploads use Cloudflare Stream or Mux — encode to HLS, adaptive streaming for any bandwidth. Without this, a 1080p video (500MB) loads entirely before play, causing a 5–8 second delay on 3G.

What’s included in media library development

Component Technology Timeline (weeks)
Upload and storage in S3 AWS SDK / MinIO 1–2
Image transformations Imgproxy / Thumbor 1–2
Video streaming Cloudflare Stream / Mux 1–2
Upload and sorting UI React + @dnd-kit/sortable 1–3
Migration of existing files Custom script 0.5–1

Why structured content outperforms free-form HTML

Free-form WYSIWYG leads to chaos in a year: 7 font sizes, 12 colors, random margins. Redesign requires manual cleanup of thousands of posts. Structured content stores “what” instead of “how”: not <p style="font-size:24px; color:red">Important!</p>, but a callout block with variant: warning. The CMS stores the structure; the frontend decides rendering. Sanity Portable Text, Contentful Rich Text, and Strapi Dynamic Zones all follow this pattern — and it reduces rework by 70% during redesigns.

Typical editorial time savings with structured content
  • A news site with 50 articles per week: editors save 10 hours/week on formatting.
  • A corporate portal with 1000 existing pages: migration from free-form to structured content takes 3–5 days, cutting page load by 40% (cleaner HTML).

Work process

  1. Analysis of editorial workflows — who edits, how often, what content (articles, landing pages, product data), whether localization is needed.
  2. CMS selection — based on scenarios, not trends. We compare headless vs traditional with a weighted matrix.
  3. Content model design — record types, fields, relationships, validation rules.
  4. Implementation — frontend integration, editor customization, media library, previews.
  5. Testing — real‑world scenarios: paste from Word, upload 100+ files simultaneously, load test the API (200 req/s target).
  6. Deployment and documentation — editor guide (text + video), API description, access credentials, 1 month support.

Timelines and budget

Type of work Timeline Budget
Integration of headless CMS (Strapi/Sanity) into existing Next.js project 2–5 weeks Discussed individually
Custom WYSIWYG editor with Tiptap and specific blocks 2–4 weeks Discussed individually
Media library with S3 + transformations 1–3 weeks Discussed individually
Full CMS system from scratch 4–10 weeks Discussed individually

Budget is calculated individually after an audit. Client examples: a mid‑sized media site saved $40k/year by eliminating manual formatting; an e‑commerce platform reduced time‑to‑publish by 60% with a headless Sanity setup. Contact us for a free project estimate.

What you get after delivery

  • Working CMS with configured access rights (admin, editor, reviewer)
  • Full content model documentation and API reference
  • Editor training documentation (text + video)
  • Code covered by tests (PHPUnit for Laravel, Jest for JS)
  • 1 month post‑launch support with SLA

Our experience and guarantees

Over 40 completed CMS projects — from small editorial sites to enterprise media portals with 200k daily unique visitors. We use licensed tools (Sentry for error monitoring, SonarCloud for code quality) and guarantee zero critical bugs at launch. All code is version‑controlled and deployable via CI/CD.

For your specific needs, contact us to discuss requirements. We’ll provide a technical proposal within 2 business days.