javascripttinymcetinymce-5

TinyMCE detect remote image dragged-in or uploaded


As documented, TinyMCE allows uploading images automatically: one defines an endpoint (images_upload_url), which is expected to upload the image and return the location for TinyMCE to use in markup.

However, when pasting, dragging or inserting an image from a URL — for example, https://somecdn.com/image.png — TinyMCE will simply embed the image tag with the somecdn.com source, instead of sending the URL to images_upload_url to be uploaded.

I've scoured through the docs here and haven't found any way to configure TinyMCE to do this. Is there a method I can override in order to upload images from URLs as well as local image uploads?

Summary

To clarify:


Solution

  • With some tinkering, I was able to figure out how to handle remote images in TinyMCE!

    As I'm using TinyMCE with React, I added an onDrop event:

    <Editor
        onDrop={onDrop}
    

    And here is my method implementation, with comments:

    const onDrop = useCallback((e) => {
    const image_url = e.dataTransfer.getData("URL");
    
    /*
        If this is a local file, use the default functionality
        provided using images_upload_url
      */
    if (!image_url) {
      return;
    }
    
    /*
        Otherwise, intercept the drop event, get the file URL,
        send it to the API to be uploaded, then embed in content
      */
    
    e.preventDefault();
    
    filesAPI
      .upload({
        image_url,
      })
      .then((response) => {
        const { location } = response.data;
        editorRef.current.execCommand(
          "mceInsertContent",
          false,
          `<img src='${location}' />`
        );
      });
    
    return false;
    }, []);
    

    The implementation seems to work pretty well! When local images are dropped in, they're processed by the default handler; otherwise the onDrop method uploads the images & inserts a tag with their location. Note that filesAPI in this context is just my app's wrapper around an axios fetch call.