14-day Cloud trial
Start today. For free.

One editor. 50+ features. Zero constraints. After your trial, retain the advanced features.

Try Professional Plan for FREE
PricingContact Us
Log InGet Started Free

Best WYSIWYG editor image upload solutions compared: under pressure

November 29th, 2023

11 min read

Different images that represent light appear around a text editor - sparks, a lightbulb, a flying bird of paradise

Written by

Joe Robinson

Category

World of WYSIWYG

Whether you need a single specific feature from your app’s WYSIWYG, or your app’s customers need a smorgasbord of features, image handling is a priority. If your WYSIWYG editor image upload feature turns out to be an involved process, that's a problem. But getting the right WYSIWYG image upload solution and information, right at the beginning of your planning, can help. Let’s dig into solving this challenge.

This article covers: Information on WYSIWYG image upload, specifically a comparison between the different rich text editors’ functionality.

Not all WYSIWYG editors are the same, nor do they all bring the features to the table that you need, when they’re called. With this guide, you can get an idea of what’s available in regards to custom image upload processing, error handling, image filtering, and other useful features.

TL;DR

  • Editors like TinyMCE, CKEditor, and Froala have some useful image filtering and custom image upload capabilities, so there’s no need to design and build everything yourself.
  • Editors like Tiptap, and Slate require you to build everything related to images – from rendering to image upload into the WYSIWYG
  • To develop a specific solution yourself, Slate or Tiptap are viable – but for quickly getting image upload completed, TinyMCE has the most flexibility, and effortless customization capability

If you’re looking for a guide to get started and understand how WYSIWYG editors with image upload compare, read on.

✏️ NOTE: The comparisons of different editors can be found in the section on exploring top WYSIWYG editors.

Why image upload matters in WYSIWYG editors

Effective WYSIWYG editor image upload features matters for two main reasons:

  1. They provide customers with the ability to add visual information to their content as photos, charts, diagrams, or infographics.
  2. They add additional security and protection from hidden scripts inside the file objects that underlie the images themselves.

In regards to the first reason, the information quality directly affects retention of the message. Good visual information supports communication by adding context and enhancing both the content’s appearance and overall quality (that is, if it’s done well and the visual elements are accessible with alt text). 

These are the true reasons why image upload requirements come up again and again in application design.

In regards to the second point, security is a concern particularly when it comes to image formats. Image files like the Scalable Vector Graphic (SVG) file contain scripts that a browser interprets. Any information, including malicious code, could be hidden within those scripts. This is why image filtering is one of several important features to investigate when looking at a WYSIWYG or text editor with image upload.

Features to look for in text editors with image upload

The key points of comparison used in the following guide, are these four features:

  • Error handling: The ability to catch or return errors so image upload troubleshooting is possible.
  • Image filtering: Checking the file type attributes of the image, and refusing or accepting particular files into the WYSIWYG. How effective and fast the image filtering option is to configure is a point of comparison.
  • Header content control: A good WYSIWYG image upload option should give you the ability to control what information is sent in the header content when image data is passed to the server scripts during the upload process.
  • Custom image upload: Rather than only one method of uploading images, the ability to use provided options, or build your own custom solution from scratch, should be given.

IMPORTANT: Documentation with examples is another key point, and a good WYSIWYG editor with image upload should also come with clear docs that explain options and processes – with code snippets for reference.

Exploring the best WYSIWYG editors with image upload capabilities

Here’s how the most popular WYSIWYG editors with image upload capacity compared:

 

TinyMCE

 

Froala



Quill

TipTap

Slate

CKEditor 5

Error Handling

Image filtering

Not out-of-the box

Must be custom built

Must be custom built

Header content control

Depends on the package or custom build

Must be custom built

Must be custom built

Custom image upload

Follows specific parameters

Depends on the package or custom build

Documented example

Limited examples

Depends on the package or custom build

No

No

TinyMCE image upload

TinyMCE provides some useful options that make WYSIWYG image upload easier and faster to configure. These are options for setting up image filtering, specifying the server-side script URL for saving the image, and keeping or changing the original image file name

The third important feature is an example of TinyMCE's customization and user friendly features – there’s no need to spend time researching and building the option to keep or change image file names. 

TinyMCE WYSIWYG image upload works with images as blob objects (an abbreviation of Binary Level Object). Blob objects are essentially a sequence of bytes with attributes that describe the object size, and the object media type. For a custom WYSIWYG image upload process, TinyMCE requires a promise that interacts with images as blob objects. Beyond this interaction, the rest of the process is flexible. 

For example, TinyMCE's effortless customizability means you can include different error handling methods, such as using Axios with a promise in a React app:

//Import the rich text editor installed with npm
import { Editor } from '@tinymce/tinymce-react';
import axios from 'axios';

export default function TinyMCE() {

const handleImageUpload = async (blobInfo, progress, failure) => {
        const formData = new FormData();
        formData.append("file", blobInfo.blob(), blobInfo.filename());
      
        try {
              const response =  await axios.post("http://localhost:8080/server.php", formData, {
                headers: { "Content-Type": "multipart/form-data" },
                  onUploadProgress: (progressEvent) => {
                    const percentCompleted = Math.round(
                      (progressEvent.loaded * 100) / progressEvent.total);
                    if (progress && typeof progress === "function") {
                      progress(percentCompleted);
                    }
                  }
               });
        
            if (response.status === 403) { //403 code check
              throw new Error("HTTP Error: " + response.status);
            } 
      
            if (response.status < 200 || response.status >= 300) { //A range code check
              throw new Error("HTTP Error: " + response.status);
            }
      
            const json = response.data;
      
            if (!json || typeof json.location !== "string") {
              throw new Error("Invalid JSON: " + JSON.stringify(json));
            } else {
              return(json.location);
            }
          } catch (error) {
            if (failure && typeof failure === "function") {
              failure(error.message);
            }
          }
      };

TinyMCE’s comprehensive image upload documentation also includes an example of a server-side script for handling the essential storage step of image upload.

💡NOTE: for more on configuring TinyMCE for WYSIWYG image upload, check on the How-to guide for a complete React app demo. Be aware that the guide makes use of an XHR script instead of an Axios script.

Froala image upload

For WYSIWYG image upload header content, Froala offers a specific pair of options you can configure in your Froala script: imageUploadURL, imageUploadParams. The first option is the server-side address for storage of images uploaded into the Froala editor. The second option is useful, demonstrating Froala’s image upload capability, by giving you the ability to control the information sent in the header request.

The parameters are an array of information in JSON format:

imageUploadParams: {
    id: 'my_editor',
    'Content-Type': 'multipart/form-data',
    },

The documentation explains these options, but does not offer more examples of what is and is not valid information to pass in the upload request.

Froala provides an imageAllowedTypes option that takes a list of allowed image file formats by MIME type, which makes configuring image filtering easier. Error handling is also made somewhat faster to configure using Froala's image.error option, which parses different WYSIWYG image upload errors, and offers different error codes for an effective response.

The tradeoff of these functionalities seems to be restriction: the overall ability to establish your own customized WYSIWYG image upload process is limited. So using Froala, means working within the parameters for error handling, which reduces the flexibility for custom image upload when compared to other editors.

Quill image upload

The first thing you need to know about Quill's WYSIWYG image upload capacity is that images are part of the toolbar, and configuring a Quill toolbar requires either setting up the format option names in an array, or specifying a custom HTML container. For example:

formats = [
  "header",
  "bold",
  "italic",
  "underline",
  "strike",
  "blockquote",
  "list",
  "bullet",
  "indent",
  "link",
  "image",
];

Configuring Quill takes more time when compared to the other editors. Quill’s standard image upload procedure encodes images in Base-64 format, which is how most WYSIWYG editors store images when there’s no discernable server-side pathway detected. To set up custom image upload in Quill, a third party package is needed, or you would need to create your own scripts that work with Quill.

There are also community developed packages for more flexible, custom WYSIWYG image upload available. However, the error handling is, as a result, a matter of working within the JavaScript Promise completion or failure response set by the individual package.

Image filtering is not available out-of-the-box when using Quill. It’s also something you need to implement yourself. You could configure this within your server-side script, parsing image file names with PHP regular expression matching.

More granular control of Quill header content also depends on the WYSIWYG image upload package formData choices. For a fetch request in a promise, you could specify as much information in the header as needed, such as in the following example:

  upload: file => {
    return new Promise((resolve, reject) => {
      const formData = new FormData();|
      formData.append("image", file);

      fetch(
        "https://api.imgbb.com/1/upload?key=d36eb6591370ae7f9089d85875e56b22",|
        {
          method: "POST",
          body: formData
        }
      )

The documentation depends largely on the community in this case, which means varied levels of technical demos and guides explaining how the WYSIWYG editor image upload package works.

TipTap image upload

Tiptap's design as a headless WYSIWYG, has advantages and disadvantages. It's flexible, allowing for complete control of each step of the image upload process. But comprehensive custom configurations call for a large time investment – and this applies to all the comparison points. 

Error handling, for instance, depends on your JavaScript experience in checking for errors. This could escalate in this case, since Tiptap's image rendering must be configured first before even getting to WYSIWYG image upload.

For example, looking at the Tiptap documentation, to get started with images, you need to install and import the Tiptap image package, and then design some image handling procedures. The documentation has an example, thankfully:

  const addImage = useCallback(() => {
   const url = window.prompt('URL')
    if (url) {
      editor.chain().focus().setImage({ src: url }).run()
<span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;">    }
</span><span style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;">  }, [editor])
</span>  if (!editor) {
    return null
  }

This is one example of the complete control you gain from using Tiptap, but the drawback is there’s no built-in helpful libraries or packages to speed up your development and testing time. 

Looking at the examples available showing Tiptap WYSIWYG image upload, there's a lot of customization. So if that's part of your project, then Tiptap offers complete customization. The customization could be optimal though, if you're working toward a targeted WYSIWYG that does a small set of user input tasks really well.

If you're aiming to do a lot more with the WYSIWYG and configure many aspects yourself (like the combined workload of menu bar build and design, WYSIWYG image upload interface elements, different filters for image files), then all the little tasks can add up and become difficult to handle in a time sensitive environment.

Slate image upload

✏️NOTE: Slate is not designed as an out-of-the-box rich text editing solution. It is designed to be used as the building blocks when you’re creating a custom WYSIWYG interface and feature set from scratch.

For an WYSIWYG image upload solution with Slate, there’s a lot to consider before starting. You’ll need to make a plan for:

  1. Methods for handling the state of the editor
  2. Options for handling changes to the editor state
  3. Ways of parsing objects within the editor as text or images (a void for non-text content for example)
  4. Configurations for event handlers, and choosing the right packages or libraries to work with image-based event handling

As you can see, there's a lot of conceptual planning that goes into a Slate project before you can start coding the JavaScript and fitting it into your framework of choice. Like Tiptap, the flexibility of customization is the major highlight. But the time and resources involved is a drawback.

For a guide on what to expect with Slate image upload, Julian Krispel-Samsel has written an excellent walkthrough of the concepts to know ahead of time when considering Slate for WYSIWYG image upload, and a demo of how to implement them into your code.

CKEditor 5 image upload

The WYSIWYG image upload for CKEditor offers a direct pathway for an easier process overall, with helpful options as well as the ability to customize your WYSIWYG image upload. Setting up error handling isn't too much of a struggle to code and test. For example, a promise with the try and catch syntax for error handling works fine for most use cases.

Control of what header information your project sends when using CKEditor is also made easier by the effective documentation explaining XMLHttpRequest header methods. All CKEditor needs is configured variables called "file" and "fileize" to contain the image file contents and determine its size.

The CKEditor Simple WYSIWYG Image Upload plugin is another feature that provides a fast method for getting up and running:

simpleUpload: {
    uploadUrl: 'http://localhost:8080/server.php',
    withCredentials: false,
    headers: {
        'Content-Type': 'multipart/form-data',
        'X-CSRF-TOKEN': 'CSRF-Token',
        Authorization: ''
       }
    }

Authorization and CSRF tokens are explicitly named, demonstrating that CKEditor makes sending specific header information easier. You can add in server environment variables that reference security keys, and you're good to start testing with this plugin.

Image filtering is a challenge though. The syntax needs a separate constant, holding an array with the images you want or don't want uploaded to the server:

// Allow only JPEG and PNG images:
const imageUploadConfig = {
  types: ["png", "jpeg"],
};

It's one added extra layer of complexity that can slow down the testing process. The layers of complexity continue into configuring custom WYSIWYG image upload.

There are several additional plugins that need to be installed and imported into your CKEditor component file for setting up custom WYSIWYG image upload. This factor raises the risk of running into duplicate module errors as you check through the plugins needed. The documentation on the custom WYSIWYG image upload process is comprehensive, explaining what each plugin is, and why it’s needed.

Just remember you could find yourself spending extra time testing and retesting your app project to make sure you have all the required packages for CKEditor’s custom image upload to work correctly.

What to know for WYSIWYG image upload

The key points that emerged from the comparison:

  • TinyMCE and CKEditor both offer some of the most useful WYSIWYG image upload features, such as custom image upload, good documentation and examples.
  • TinyMCE’s options around image filtering, as well as the custom image upload capabilities, are implemented more quickly, which is useful if you need a solution completed in a short timeframe.
  • TinyMCE provides more out-of-the box solutions compared to CKEditor, Froala, and Quill. CKEditor has a more comprehensive set of features compared to Froala and Quill.
  • Tiptap and Slate require a lot of planning and image handling processes to complete before image upload can be considered, which makes these editors useful for specific solutions.

For more on TinyMCE’s image upload capacity, check on the guides explaining how to use TinyMCE’s dedicated framework integrations with image upload:

  1. TinyMCE and Angular with image upload
  2. Bootstrap, TinyMCE, and image upload
  3. Integrate TinyMCE with Vue, and configure image upload

If you’d like to find out more about TinyMCE’s capacity to support you for image upload or other useful features, contact us today.

ImagesWYSIWYGEditor Comparisons
byJoe Robinson

Technical and creative writer, editor, and a TinyMCE advocate. An enthusiast for teamwork, open source software projects, and baking. Can often be found puzzling over obscure history, cryptic words, and lucid writing.

Related Articles

  • World of WYSIWYGApr 5th, 2020

    New commercial packages for TinyMCE

Join 100,000+ developers who get regular tips & updates from the Tiny team.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.