Image and file options

Controlling or adjusting allowed image and file formats

images_file_types

This option configures which image file formats are accepted by the editor. Changing this option will adjust the following editor behaviour:

  • Which image file formats are allowed to be uploaded in the Image dialog.

  • Which image file formats are recognized and placed in an img element by the core paste and PowerPaste smart_paste functionality.

Type: String

Default value: 'jpeg,jpg,jpe,jfi,jif,jfif,png,gif,bmp,webp'

Possible values: A list of valid web image file extensions. For a list of possible values see: MDN Web Docs - Image file type and format guide.

Example: using images_file_types

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  plugins: 'image',
  toolbar: 'image',
  images_file_types: 'jpg,svg,webp'
});

file_picker_types

This option enables you to specify what types of file pickers you need by a space or comma separated list of type names. There are currently three valid types: file, image and media.

Type: String

Possible values: 'file', 'image', 'media'

Example: using file_picker_types

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  file_picker_types: 'file image media'
});

block_unsupported_drop

When the block_unsupported_drop option is set to true, the editor blocks unsupported images and files from being dropped into the editor. If the block_unsupported_drop option is set to false, dropping an unsupported file into the editor will cause the browser to navigate away from the page containing the editor.

Type: Boolean

Default value: true

Possible values: true, false

Example: using block_unsupported_drop

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  block_unsupported_drop: false
});

Adding a file browser to image and media dialogs

file_picker_callback

This hook can be used to add custom file picker to those dialogs that have it. Once you define file_picker_callback, small browse button will appear along the fields of supported file types (see file_picker_types). When user clicks the button, TinyMCE will automatically call the callback with three arguments:

  • callback - a callback to call, once you have hold of the file; it expects new value for the field as the first argument and optionally meta information for other fields in the dialog as the second one

  • value - current value of the affected field

  • meta - object containing values of other fields in the specified dialog (notice that meta.filetype contains the type of the field)

It should be noted, that we only provide a hook. It is up to you to implement specific functionality.

Type: Function

The following example demonstrates how you can use file_picker_callback API, but doesn’t pick any real files. Check the Interactive example for a more functional example.

Example: using file_picker_callback

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  file_picker_callback: (callback, value, meta) => {
    // Provide file and text for the link dialog
    if (meta.filetype == 'file') {
      callback('mypage.html', { text: 'My text' });
    }

    // Provide image and alt text for the image dialog
    if (meta.filetype == 'image') {
      callback('myimage.jpg', { alt: 'My alt text' });
    }

    // Provide alternative source and posted for the media dialog
    if (meta.filetype == 'media') {
      callback('movie.mp4', { source2: 'alt.ogg', poster: 'image.jpg' });
    }
  }
});

Interactive example

  • TinyMCE

  • HTML

  • JS

  • Edit on CodePen

<textarea id="file-picker"></textarea>
tinymce.init({
  selector: 'textarea#file-picker',
  plugins: 'image code',
  toolbar: 'undo redo | link image | code',
  /* enable title field in the Image dialog*/
  image_title: true,
  /* enable automatic uploads of images represented by blob or data URIs*/
  automatic_uploads: true,
  /*
    URL of our upload handler (for more details check: https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_url)
    images_upload_url: 'postAcceptor.php',
    here we add custom filepicker only to Image dialog
  */
  file_picker_types: 'image',
  /* and here's our custom image picker*/
  file_picker_callback: (cb, value, meta) => {
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');

    input.addEventListener('change', (e) => {
      const file = e.target.files[0];

      const reader = new FileReader();
      reader.addEventListener('load', () => {
        /*
          Note: Now we need to register the blob in TinyMCEs image blob
          registry. In the next release this part hopefully won't be
          necessary, as we are looking to handle it internally.
        */
        const id = 'blobid' + (new Date()).getTime();
        const blobCache =  tinymce.activeEditor.editorUpload.blobCache;
        const base64 = reader.result.split(',')[1];
        const blobInfo = blobCache.create(id, file, base64);
        blobCache.add(blobInfo);

        /* call the callback and populate the Title field with the file name */
        cb(blobInfo.blobUri(), { title: file.name });
      });
      reader.readAsDataURL(file);
    });

    input.click();
  },
  content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:16px }'
});

Customizing how images and files are handled

images_upload_handler

This option allows you to specify a function that is used to replace TinyMCE’s default JavaScript upload handler function with custom logic.

The upload handler function takes two arguments:

  • blobInfo

  • A progress callback that takes a value between 1 and 100.

and returns a Promise that will resolve with the uploaded image URL or reject with an error. The error can be either a string or an object containing the following properties:

  • message - The error message to display in the UI.

  • remove - A flag to remove the image from the document, defaults to false if not set.

When this option is not set, TinyMCE utilizes an XMLHttpRequest to upload images one at a time to the server and resolves the Promise with the JSON location property for the remote image returned by the server.

Type: Function

Example: using images_upload_handler

const example_image_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest();
  xhr.withCredentials = false;
  xhr.open('POST', 'postAcceptor.php');

  xhr.upload.onprogress = (e) => {
    progress(e.loaded / e.total * 100);
  };

  xhr.onload = () => {
    if (xhr.status === 403) {
      reject({ message: 'HTTP Error: ' + xhr.status, remove: true });
      return;
    }

    if (xhr.status < 200 || xhr.status >= 300) {
      reject('HTTP Error: ' + xhr.status);
      return;
    }

    const json = JSON.parse(xhr.responseText);

    if (!json || typeof json.location != 'string') {
      reject('Invalid JSON: ' + xhr.responseText);
      return;
    }

    resolve(json.location);
  };

  xhr.onerror = () => {
    reject('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
  };

  const formData = new FormData();
  formData.append('file', blobInfo.blob(), blobInfo.filename());

  xhr.send(formData);
});

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  images_upload_handler: example_image_upload_handler
});

images_upload_url

This option lets you specify a URL for the server-side upload handler. Upload will get triggered whenever you call editor.uploadImages() or - automatically, if automatic_uploads option is enabled. Upload handler should return a new location for the uploaded file in the following format:

{ "location": "folder/sub-folder/new-location.png" }

Be sure to checkout a demo implementation of the server-side upload handler here (written in PHP).

Type: String

Example: using images_upload_url

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  images_upload_url: 'postAcceptor.php'
});

files_upload_handler

This option specifies a function that handles file uploads in the link dialog’s upload tab. This is similar to images_upload_handler, but is specifically designed for document and file uploads.

The upload handler function takes two arguments:

  • blobInfo - An object containing information about the file blob to upload

  • A progress callback that takes a value between 1 and 100

and returns a Promise that will resolve with an object containing the uploaded file url and fileName, or reject with an error. The resolved object must have the following structure:

  • url - The URL of the uploaded file

  • fileName - The filename of the uploaded file

The error can be either a string or an object containing the following properties:

  • message - The error message to display in the UI.

  • remove - A flag to remove the file from the document, defaults to false if not set.

When both files_upload_handler and documents_file_types are configured, the link dialog displays an "Upload" tab that enables file uploads via the function defined by files_upload_handler.

Type: Function

Default value: undefined

Example: using files_upload_handler

This example shows a client-side JavaScript handler that uploads files to a server endpoint. The server should return a JSON response with a location property containing the URL of the uploaded file.

const files_upload_handler = (blobInfo, progress) => new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest();
  xhr.withCredentials = false;
  xhr.open('POST', 'upload-handler.php');

  xhr.upload.onprogress = (e) => {
    progress(e.loaded / e.total * 100);
  };

  xhr.onload = () => {
    if (xhr.status === 403) {
      reject({ message: 'HTTP Error: ' + xhr.status, remove: true });
      return;
    }

    if (xhr.status < 200 || xhr.status >= 300) {
      reject('HTTP Error: ' + xhr.status);
      return;
    }

    const json = JSON.parse(xhr.responseText);

    if (!json || typeof json.location != 'string') {
      reject('Invalid JSON: ' + xhr.responseText);
      return;
    }

    resolve({
      url: json.location,
      fileName: blobInfo.filename()
    });
  };

  xhr.onerror = () => {
    reject('File upload failed due to a XHR Transport error. Code: ' + xhr.status);
  };

  const formData = new FormData();
  formData.append('file', blobInfo.blob(), blobInfo.filename());

  xhr.send(formData);
});

tinymce.init({
  selector: 'textarea',
  plugins: 'link',
  toolbar: 'link',
  files_upload_handler: files_upload_handler,
  documents_file_types: [
    { mimeType: 'application/pdf', extensions: [ 'pdf' ] },
    { mimeType: 'application/msword', extensions: [ 'doc' ] },
    { mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extensions: [ 'docx' ] },
    { mimeType: 'text/plain', extensions: [ 'txt' ] }
  ]
});

Server-Side Handler Requirements

The server endpoint (e.g., upload-handler.php in the example above) should:

  • Accept a POST request with a file in the request body (sent as FormData with the field name file)

  • Return a JSON response with a location property containing the URL of the uploaded file: { "location": "<path-to-your-web-server>/uploaded/file.pdf" }

  • Handle errors by returning appropriate HTTP status codes (e.g., 403 for forbidden file types, 400 for invalid requests, 500 for server errors)

  • Set appropriate CORS headers if needed for cross-origin requests

This is similar to how images_upload_url works, but files_upload_handler gives you full control over the client-side upload logic, including custom error handling, progress tracking, and request customization.

documents_file_types

This option specifies which file types (MIME types and extensions) are supported for file uploads in the link dialog. When both the Link plugin and the files_upload_handler are configured, the link dialog displays an "Upload" tab that enables file uploads.

The option should be an array of objects, where each object contains:

  • mimeType - A string representing the MIME type (e.g., 'application/pdf')

  • extensions - An array of strings representing the file extensions (e.g., ['pdf'])

Type: Array

Default value: undefined

Priority Behavior

When documents_file_types is set, it acts as the source of truth for supported file types throughout the editor. This means:

  • The Link plugin uses this custom list instead of its default supported file types

If documents_file_types is not set:

  • The Link plugin uses its default list of supported file types

Example: using documents_file_types

tinymce.init({
  selector: 'textarea',
  plugins: 'link',
  toolbar: 'link',
  // Configure the file upload handler to handle the file uploads
  files_upload_handler: async (blobInfo, progress) => {
    return { url: 'https://example.com/file.pdf', fileName: 'file.pdf' };
  },
  // Configure the list of supported file types
  documents_file_types: [
    { mimeType: 'application/msword', extensions: [ 'doc' ] },
    { mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', extensions: [ 'docx' ] },
    { mimeType: 'application/pdf', extensions: [ 'pdf' ] },
    { mimeType: 'text/plain', extensions: [ 'txt' ] }
  ]
});

Options for improving custom file handling

automatic_uploads

Enable or disable automatic upload of images represented by data URLs or blob URIs. Such images get generated, for example, as a result of image manipulation through the Image Editing plugin, or after image is drag-n-dropped onto the editor from the desktop.

This option will do nothing if images_upload_url or images_upload_handler is not specified.

Type: Boolean

Default value: true

Possible values: true, false

Example: using automatic_uploads

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  images_upload_url: 'postAcceptor.php',
  automatic_uploads: false
});

images_upload_base_path

This option lets you specify a basepath to prepend to URLs returned from the configured images_upload_url page.

Type: String

Example: using images_upload_base_path

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  images_upload_url: 'postAcceptor.php',
  images_upload_base_path: '/some/basepath'
});

images_upload_credentials

The images_upload_credentials option specifies whether calls to the configured images_upload_url should pass along credentials (such as cookies, authorization headers, or TLS client certificates) for cross-domain uploads. When set to true, credentials will be sent to the upload handler, similar to the withCredentials property of XMLHttpRequest.

Type: Boolean

Default value: false

Possible values: true, false

Example: using images_upload_credentials

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  images_upload_url: 'postAcceptor.php',
  images_upload_credentials: true
});

images_reuse_filename

By default TinyMCE will generate unique filename for each uploaded file (for details refer to Upload Images). Sometimes this might have undesirable side-effects. For example, when automatic_uploads is enabled, every manipulation on the image done with the Image Editing plugin, results in file upload and each time under a different filename, despite the fact that the image stays the same.

Setting images_reuse_filename to true tells TinyMCE to use the actual filename of the image, instead of generating a new one each time. Take into account that src attribute of the corresponding <img> tag gets replaced with whatever filename you send back from the server (see images_upload_url). It can be the same filename or something else, but the next time that filename is used for the upload.

Type: Boolean

Default value: false

Possible values: true, false

Example: using images_reuse_filename

tinymce.init({
  selector: 'textarea',  // change this value according to your HTML
  automatic_uploads: true,
  images_upload_url: 'postAcceptor.php',
  images_reuse_filename: true
});