---
title: Customizing the CKEditor in Craft CMS
date: 2024-05-21T09:00:00-04:00
author: John Morton
canonical_url: "https://supergeekery.com/blog/customizing-the-ckeditor-in-craft-cms"
section: Blog
---
# Customizing the CKEditor in Craft CMS

*May 21, 2024* by John Morton

![CKEditor UX interface](https://static.supergeekery.com/site-assets/2024-05-20_14-55-32_2024-05-20-230039_fpze.png)

When I create a new rich text field in Craft CMS, I use the first-party [<u>CKEditor</u>](https://plugins.craftcms.com/ckeditor) plugin. My nest task is to configure the field with some standard updates which is what we’ll cover in this post.

Before diving in to my customizations, check out the plugin’s [<u>official documentation</u>](https://github.com/craftcms/ckeditor) to understand the basic usage of the field type and learn about one of its *superpowers*, [<u>nested entries</u>](https://github.com/craftcms/ckeditor?tab=readme-ov-file#longform-content-with-nested-entries), which I won’t cover here. [*<u>You’re not going to miss Redactor.</u>*](https://github.com/craftcms/redactor/issues/489) 🍻

## **The to-do list**

I have a routine set of tasks each time I use CKEditor.

1. Customize the font family selection
2. Occasionally, I adjust the text-alignment options
3. Customize the font-size options
4. Allow an author to specify if a link should open in a new window
5. Allow the user to paste in a YouTube URL to create a video embed

## **Customize the CKEditor Config**

In the Craft control panel, you can create configs that will customize what the content author sees in their rich text editing window. Your CKEditor can have multiple configs. You’ll find them in the control panel in Settings -&gt; Plugins -&gt; CKEditor.

Here’s a Gist of starter configuration if you simply want to copy and paste in the *Config Options* section of one of your config definitions.

[<u>https://gist.github.com/johnfmorton/4272cc5a8c3228816efde337cf54e06a</u>](https://gist.github.com/johnfmorton/4272cc5a8c3228816efde337cf54e06a)

Let’s look at some specific things in that file.

### **fontFamily**

You can easily configure the **fontFamily** with the font stacks used on your site. I think the only thing to point out here is that font names that include a space in the name should be wrapped in single quotes inside the doubled quoted font cascade, like *EB Garamond*, in my example.

```plaintext
'EB Garamond', Georgia, serif
```

Adding this configuration doesn't automatically add the option to the toolbar for your content authors. Drag and drop the font family picker so that it's available in the toolbar.

![](https://static.supergeekery.com/site-assets/2024-05-20_14-55-32_2024-05-20-230039_fpze.png)

Customized toolbar options, shown with arrows: alignment, font-family, font-size, link, embed
### **text-alignment options**

You’ll see in my sample config that I’ve included all options, **left**, **center**, **right**. Those options are there so I can simply remove one if I choose. If you don’t need to customize alignment, you can leave this config block out entirely. Add the text-alignment button to the toolbar if you want to give users this option.

### **fontSizes**

The **fontSizes** in CKEditor include five [<u>built-in options</u>](https://github.com/ckeditor/ckeditor5/blob/1eb3a95efd013f986bde6af8d2f03770f30211c1/packages/ckeditor5-font/src/fontsize/utils.ts#L27) for font sizes:

1. tiny
2. small
3. default — This option is not technically a “size,” but [<u>a way to remove any size class</u>](https://github.com/ckeditor/ckeditor5/blob/1eb3a95efd013f986bde6af8d2f03770f30211c1/packages/ckeditor5-font/src/fontsize/utils.ts#L96).
4. big
5. huge

Using them is pretty simple, the content author can highlight some text in the rich text editor and select one of the sizes which will add a span with a size class to it. For example, the **small** option will add a **span** with a class of **text-small**, like this.

```plaintext
<span class="text-small">This text will be small.</span>
```

In your config you can remove an option by simply leaving it out. But if you want to add an additional option, the example config will come in handy. Take a look at the addition of a **Bigger** option. I’ve placed it between two of the default names, **big** and **huge** so that it will appear in the order I want it to appear in.

```plaintext
"fontSize": {
    "options": [
      "tiny",
      "small",
      "default",
      "big",
      {
        "model": "bigger",
        "title": "Bigger",
        "view": {
          "classes": [
            "text-bigger"
          ],
          "name": "span"
        }
      },
      "huge"
    ]
  },
```

Add the font-size picker option to the toolbar so that its available for content authors.

In addition, you’ll need to define a style in the “Custom Styles” section in your configuration screen since Craft won’t know style your custom style. Notice the **.ck.ck-content** class name. This will limit the rules so that they only apply to the CKEditor and don’t inadvertently style other elements of the control panel.

```plaintext
.ck.ck-content .bigger {
  font-size: 1.5rem;
}
```

With those settings in place, your author can now choose “Bigger” as an option which will generate the new size class.

```plaintext
<span class="text-bigger">This text will be bigger.</span>
```

Lastly, be sure to include the styling options in your CSS for the front-end for the styles you’re providing for your users.

### **Open links in a new tab**

If you’re coming to CKEditor from Redactor, you might miss the option that allows links to opened in a new window. It’s not included in the CKEditor defaults, but you can easily add it with the **link** configuration in the same file.

```plaintext
"link": {
    "addTargetToExternalLinks": false,
    "decorators": {
      "openInNewTab": {
        "attributes": {
          "rel": "noopener noreferrer",
          "target": "_blank"
        },
        "label": "Open in a new tab",
        "mode": "manual"
      }
    }
  }
```

![Example of the UX of the CKEditor opening links in a new tab.](https://static.supergeekery.com/site-assets/2024-05-17_13-22-10.png)

Example of the UX of the CKEditor opening links in a new tab.
## **Adding video**

When you added the buttons for the toolbar for font-family, alignment, font-size, etc., you might have also added the embed content button. If you want to allow video embeds, you did the right thing, but you’re not done yet.

### **The HTML Purifier config**

If you’ve never updated the HTML Purifier in Craft, the out of the box configuration will likely strip out the video an author has inserted into the CKEditor interface when the entry was saved.

This is the HTML Purifier doing its work. It may appear tempting to simply disable HTML Purification entirely. Don’t do this. ☠️☠️☠️ Your future self will thank you. HTML Purification is there for security reasons.

To keep those video embeds, check out this sample [<u>htmlpurifier-config.json</u>](https://gist.github.com/johnfmorton/1f92f09ab3b2ffd23e4df4c06b0333a8).

Use that as a starter config for your own HTML Purifier. It’s written to allow YouTube embeds to not be stripped out during the purification process. Note that I also have a Vimeo URL in my example. I won’t show the code for Vimeo in the next section, but you’ll see how to do that based on the YouTube example.

### **Converting the embed tag to a video tag**

If you allow embedded media with the CKEditor, you’ll need to take the embed tag and convert it to render the content you want to display. The CKEditor documentation has a [<u>section on how to unfurl nearly any media type</u>](https://ckeditor.com/docs/ckeditor5/latest/features/media-embed.html#displaying-embedded-media-on-your-website) by including the third-party **embed.js** library in your site. This library requires an [<u>API key</u>](https://iframely.com/docs/embedjs) and has a [<u>pay-as-you go plan</u>](https://iframely.com/pricing).

This libray is overkill, IMO. Why? You need to know the content that you expect so that you can properly write your HTML Purifier. And, since you know what to expect, you can easily write the Javascript to handle the embeds you will have. For my purposes, I’m expecting YouTube videos. That’s all. I don’t need a library that will unfurl every possible embed type. Plus, if you write the unfurling code yourself, you have more control of the final output.

Here’s a Gist for embedding YouTube videos: [<u>https://gist.github.com/johnfmorton/6b7961fb13e09fe3ef8d5d19ed657614</u>](https://gist.github.com/johnfmorton/6b7961fb13e09fe3ef8d5d19ed657614)

No API key required. No problem.

I’ve got some styles built into the function, but you can remove them or customize them pretty easily.

## **Wrapping up**

These updates deal with the majority of all CKEditor fields I create. Did I miss anything you use regularly? I’d love to hear about it. Click the [<u>Conact</u>](https://supergeekery.com/contact) link and tell me about it.
## Update 13MAY2025: creating a custom plugin

Sometimes you need functionality that only a custom plugin can provide. You can write a custom plugin, which is just Javascript, and use it in your Craft CKEditor.

Here's an example of one I needed recently. All it does is prevent the content author from using the Enter key to make new paragraphs. The approved design on the site was to not allow paragraphs, but we needed to allow other formatting in that single paragraph.

```plaintext
// Create your custom plug-in
function MyNoParagraphPlugin( editor ) {
  // Intercept the Enter key and kill its default behavior
  editor.editing.view.document.on( 'enter', ( evt, data ) => {
    data.preventDefault();
    evt.stop();
  }, { priority: 'high' } );
  // Also block Shift+Enter (no <br> either)
  editor.keystrokes.set( 'Shift+Enter', ( data, cancel ) => cancel() );
  return editor;
}
// Then use your custom plugin
return {
  extraPlugins: [ MyNoParagraphPlugin ]
};
```

Paste the code directly into your Config Options in the control panel like this. Note that you need to select the JavaScript option, not the JSON option.

![Screenshot of using a custom plugin in CK Editor in Craft CMS](https://static.supergeekery.com/site-assets/2025-05-13_10-34-58.png)

---

**Tags:** craftcms, ux

## Related Posts

- [The HTML email template in Craft CMS](https://supergeekery.com/blog/craftcms-html-email-template-missing-documenation)
- [Entry Editor Links, a new Craft CMS plugin](https://supergeekery.com/blog/entry-editor-links-a-new-craft-cms-plugin)
- [Craft CMS: A bigger “Plain Text” field.](https://supergeekery.com/blog/craft-cms-a-bigger-plain-text-field)
