Ondřej Chrastina
Menu

CKEditor 5 Pitfall: Don't Forget the Paragraph Plugin

When integrating CKEditor 5, it's tempting to start small—using the CKEditor Builder or diving into the crash course. But there’s a subtle gotcha that trips up even experienced developers: the Essentials plugin doesn’t include Paragraph support. Without it, your editor silently fails—no errors, just an empty editing area. This post shows the problem, the fix, and why remembering to add the Paragraph plugin is... well, essential. 🚀

Back to journal

When you're adding CKEditor 5 to your platform, chances are you're starting simple—maybe testing in a sandbox project or integrating through the excellent CKEditor Builder, or diving into the CKEditor Framework Crash Course.

In my case, I tried both approaches:

  • 🧱 Using the CKEditor Builder
  • ⚙️ Following the CKEditor framework crash course

Both are fantastic resources. However, there's one small but crucial detail that’s easy to overlook:

💡 You need **two plugins** to make even a minimal CKEditor 5 setup work:  

  • Essential
  • 🚨 Paragraph (yes, it's not included in Essentials!)
ClassicEditor.create(element, {
    licenseKey: 'GPL',
    plugins: [
        Essentials, // * ✅ Essential
        Paragraph // 🚨 Paragraph 🚨 
    ]
});


The Pitfall: Only Using Essentials

It might seem like the following setup is enough:

// Import the editor.
import {
    ClassicEditor,
    Essentials,
} from 'ckeditor5';

// Import the styles.
import 'ckeditor5/ckeditor5.css';

// Get the HTML element with the ID of 'app'.
const element = document.querySelector('#app');

// Instantiate the editor using the `create` method.
const editor = await ClassicEditor.create(element, {
    licenseKey: 'GPL',
    plugins: [
        Essentials
    ]
});

The editor initializes, but nothing works—no content, no cursor, and no error messages either! 😱

Yes, the configuration is slightly richer, but it still behaves the same in the editor area.

Take a look at this case:

“Are you missing something?”
Yes. Yes, you are (and it is in the docs):

YES, it it in the docs

(alias) class Essentials
import Essentials

A plugin including all essential editing features. It represents a set of features that enables similar functionalities to a <textarea> element.

It includes:

  • :ui/editorui/accessibilityhelp/accessibilityhelp~AccessibilityHelp,
  • :clipboard/clipboard~Clipboard,
  • :enter/enter~Enter,
  • :select-all/selectall~SelectAll,
  • :enter/shiftenter~ShiftEnter,
  • :typing/typing~Typing,
  • :undo/undo~Undo.

This plugin set does not define any block-level containers (such as :paragraph/paragraph~Paragraph). If your editor is supposed to handle block content, make sure to include it.

The Fix: Add the Paragraph Plugin 🎉

// Import the editor.
import {
    ClassicEditor,
    Essentials,
    Paragraph
} from 'ckeditor5';

// Import the styles.
import 'ckeditor5/ckeditor5.css';

// Get the HTML element with the ID of 'app'.
const element = document.querySelector('#app');

// Instantiate the editor using the `create` method.
const editor = await ClassicEditor.create(element, {
    licenseKey: 'GPL',
    plugins: [
        Essentials,
        Paragraph
    ]
});

And voilà:
“Much better!”

🧠 Key Takeaway

  • Essentials plugin ≠ has everything you need for editing.
  • For a working CKEditor instance, especially one with block content, add the Paragraph feature.
  • Always double-check the docs—even for plugins that sound... well, essential.

Keep this in mind as you build your rich text editing experiences! 💡

  • Twitter
  • GitHub
  • LinkedIn
  • Facebook
  • Instagram
  • YouTube
  • Medium
  • dev.to
  • Discord
    • © Ondřej Chrastina 2020
    • Design: HTML5 UP
    • 💾 Source code
  • Home
  • Journal
  • Projects
  • PWA series
  • GitHub
Close