woman's hand on a keyboard

Upgrading to CKEditor 5 from CKEditor 4 on a Drupal 7 site

As of February 2024, 46% of Drupal sites globally are still on Drupal 7. As much as we’d love to see all Drupal 7 sites upgraded to Drupal 10 by now, the reality is that many legacy Drupal 7 sites are still being maintained — and will be for some time. Indeed, Drupal 7’s end-of-life kept getting pushed back for this very reason.

If your D7 site is running CKEditor 4, it’s recommended that you migrate to CKEditor 5 as soon as possible. However, since there aren’t many available options for doing this in Drupal 7, we decided to post some tips that worked for us — as well as the ones that didn’t.

Why upgrading is inevitable

The CKEditor 4 library hit its end-of-life at the end of June 2023. Many Drupal 7 sites rely on CKEditor 4 for its rich text fields.

Regardless of Drupal 7’s enduring presence, sticking with CKEditor 4 is not an option. In the words of the CKEditor team:

It’ll no longer be updated, have security patches and bug fixes, or new features. Given this, projects with CKEditor 4 implementations need to take action to ensure a secure and uninterrupted editing experience beyond its EOL… the last free open source version of CKEditor 4 (4.22.1) contains known security issues and should no longer be used.

— Gökçe Tosun, Senior Marketing Specialist, CKSource

So,  what to do with Drupal 7 sites that use the CKEditor 4 for their rich text fields? It’s not as simple as updating to the CKEditor 5 library, because the CKEditor D7 contrib module (which implements CKEditor) hasn’t been updated to work with it. We imagine many others are facing this predicament along with us, so we thought it might be helpful to share our own upgrading experience.

Here’s what didn’t work…

Drupal 7 CKEditor module

The module only works with CKEditor 4 and there are no plans to upgrade it to work with CKEditor 5. In fact, the module’s description is “CKEditor 4 – WYSIWYG HTML editor”

Drupal 7 CKEditor long-term support module

This module maintains support for the CKEditor 4 library, allowing you or your client to obtain a long-term support license for the CKEditor 4 library from the CKEditor team. One problem: this license is very expensive. Obtaining it is done on an email-inquiry basis, and seems intended for large enterprise clients.

Backdrop CMS’s CKEditor 5 module

This module was previously a standalone Backdrop CMS module and is now rolled into the Backdrop CMS core. It includes the CKEditor 5 library within the module folder, in keeping with Backdrop CMS’s philosophy.

We tried pulling the CKEditor 5 module out of the Backdrop CMS’s GIT repo to use in a non-Backdrop Drupal 7 build. This didn’t work out, because the module makes too many calls to custom Backdrop CMS core functions. In some cases, these are just renames of Drupal 7 core functions. In other cases, they’re entirely new functions.

…and the approach that did work

Patched WYSIWYG module

There’s a patch for the WYSIWYG module that lets it work with the CKEditor 5 library. This means you’ll need to replace the CKEditor module with the WYSIWYG module. These modules perform similar roles, except the latter was built to work with multiple rich text editor libraries. If you’re already using the WYSIWYG module, you’ll have fewer steps to take. 

How to replace the CKEditor module with the WYSIWYG module:

  1. Disable the CKEditor module and delete both the module and the CKEditor library from the codebase. Then, clear cache. 
  2. Download the WYSIWYG module. We used the latest stable release: https://www.drupal.org/project/wysiwyg/releases/7.x-2.10. Then, apply this patch to it: https://www.drupal.org/files/issues/2022-12-07/wysiwyg_ckeditor5-3123281-6.patch
  3. Create a custom CKEditor 5 build (these instructions are modified from the issue where we obtained the patch. Have a look at that issue for some context.)
    1. Go to https://ckeditor.com/ckeditor-5/online-builder/
    2. Click “Classic”.
    3. Choose the plugins that you want to use, and remove the ones you don’t need. We suggest that you login to an instance of your site that uses CKEditor (eg. live)  for an idea of which plugins you will need, using the CKEditor with whichever format has the most buttons enabled (usually, Full HTML). For example, this is what our online build looked like for a site that uses more than the average number of plugins.
    4. While picking plugins, we recommend spawning a new browser tab from each plugin’s Documentation button to see the edits you may need to make on the ckeditor.js file later. Some plugins will require edits to that file, though many will not.
    5. After choosing your plugins, click the button “Next step”.
    6. The UI to configure the toolbar is displayed. However, due to the fact that the WYSIWIYG CKEditor 5 patch simply creates a ckeditor5.js file, the layout of the toolbar gets overridden by the patched code in wysiwyg/editors/js/ckeditor5.js. So you can skip this step. Click the button “Next step”.
    7. Choose a language for your editor and click the button “Next step”.
    8. Click the “Start” button to create the custom CKEditor 5 build.
    9. Unpack the download and put it in sites/all/libraries. Rename the folder to ‘ckeditor5’. This should be the result: sites/all/libraries/ckeditor5/build/ckeditor.js
  4. Enable the WYSIWYG module.
  5. Create your WYSIWYG profiles at  /admin/config/content/WYSIWYG and assign the CKEditor5 editor to your profile. Normally you will want this for the Filtered HTML and Full HTML formats.
    1. We found that the defaults for the WYSIWIYG profiles worked fine for us, though you may want to compare these fields to your CKEditor profiles on the site instance where you still have that enabled (ie. live), at /admin/config/content/ckeditor. The CKEditor profiles are set up differently than the WYSIWYG profiles, but they still share some aspects.
  6. Add a node that has a rich text field, and test out how the WYSIWYG editor is working. We suggest concurrently testing on the environment where you still have CKEditor running in order to do a side-by-side comparison. 
  7. Since you were not able to edit the toolbar layout while building your CKEditor library, (step 3.6 above) at this point you may notice buttons that are missing despite having selected it as one of your plugins. The buttons in the toolbar (and their order) are hard-coded per text format. To customize the toolbar, edit the file wysiwyg/editors/js/ckeditor5.js. This is the point at which the documentation that you spawned tabs out of in step 3.d may come in handy.
    1. There are separate definitions in ckeditor5.js for the layouts for each text format. Existing definitions in the file are for full_html and filtered_html, but you can add more as needed Some of the configuration in that file is shared across the text formats. 
    2. If you added image plugins, edit the image toolbar in the ClassicEditor settings – this is the toolbar that displays when you click on an image.
    3. Save your ckeditor5.js changes, clear the cache, and then reload your editor. Re-test your rich text field, and repeat step 7 until you get things right.
    4. This will probably take you a few runs. You may also need to repeat the building process of the CKEditor 5 library, as described in step 3. For this, we found it helpful to use the “previous step” button to go back to add or remove plugins, though the build resets itself on ckeditor.com after about half an hour.
    5. When you’re happy with the editor for all your profiles, we suggest making a patch file for your ckeditor.js changes.
  8. If you use Features, update them. In our case, we removed the dependency on the CKEditor module and added a dependency on the WYSIWYG module. We also removed the CKEditor profiles, and added the WYSIWYG profiles — these are their own components in the Features UI..

Caveat: uploading images from within the editor

This is where we ran into our biggest challenge. Among our several CKEditor 5 upgrades, we had one client that had the Media Browser button set up in their previous editor according to these instructions from Drupal.org, plus another client that set up the IMCE button in their previous editor according to its readme. We were unable to get either of these to work. 

The Media Browser integration seems like the tougher nut to crack. We got close with the IMCE integration but ended up having a permissions issue when the editor tried to write the image to the files directory.

In both cases, image uploading wasn’t needed within the editor, so we moved on. We ended up using the “link image” plugin as an effective workaround (seen in my CKEditor build screenshot above). With this plugin, a user simply pastes a link to an image and it will embed itself into the content. If you can provide an alternate way for them to upload the image, they can copy the link and paste it.

If you end up having better luck with this than we did, please let me know through my Drupal.org contact form

Text Formats

Text formats are configured at /admin/config/content/formats. Text formats affect the view, as opposed to the edit. In our case, switching from CKEditor to WYSIWYG didn’t require any changes to the text formats. However, if your changes to the editor end up changing the kind of markup that is generated, you may need to make changes here. 

Field Height

One of the more noticeable differences for users between WYSIWYG and CKEditor is the height of the editor block. With CKEditor, the Rows property of the field sets the initial height, and then the user can drag the block to any height. With WYSIWYG, the Rows property is ignored. The block is a minimal height when unpopulated and grows according to its content. If you don’t like this behavior, here are some issues you can look at:

Drupal 7 site admins, take note 

Not all site administrators may be aware that CKEditor 5 is a critical upgrade for Drupal 7 sites. By now, many of these sites may be off of a site admins’ radars entirely. On a Drupal 7 Status Report page, no warnings are shown — indeed the CKEditor 4 library is shown in green. Conversely, the Update Manager does flag this in red. As a site administrator, now would be a good time to ensure your Drupal 7 sites have the Update Manager module enabled and that you’re on the email list at admin/reports/updates/settings. We have no way of knowing what other critical upgrades to Drupal 7 contrib projects will be needed before our sites are finally upgraded to Drupal 10 or beyond, and the Update Manager is a good way to stay in the loop.

Speaking of which, therein lies the most effective long-term solution to your CKEditor woes — upgrading your sites to Drupal 10! While upgrading 7 to 8 was a big undertaking that came with a considerable set of challenges, it’s been smooth sailing ever since. We’re now looking at a dramatically better package than Drupal 7 was — one that’s more powerful and secure, much easier to maintain, better for both end users and developers, and is current with the latest web technologies.

Here at Kanopi, we’ve upgraded several of our client sites to Drupal 10, and we can partner with you through every stage of the process — design (including content strategy), build, and support. All you need to do to get started is contact us.