TinyMCE image upload: finish the upload before capturing saved HTML

A pasted image can appear in TinyMCE while its upload is still pending. Before saving the document, await editor.uploadImages() and check each returned image's status. Capture editor.getContent() only after successful results, then send that HTML through the application's save route. Capturing too early can retain Base64 data instead of the uploaded location. Image upload documentation

Consider an original repair bulletin with a photograph of a cracked valve. The author pastes the photograph and immediately chooses Save. The useful result is a stored bulletin whose image address still works when the maintenance reviewer opens it tomorrow.

Connect the upload service to the editor

Merge these options into the application's existing TinyMCE initialization:

const repairImageOptions = {
  plugins: 'image',
  toolbar: 'undo redo | image',
  automatic_uploads: true,
  images_upload_url: '/api/repair-images'
};

Keep the existing selector, other plugins, toolbar items, distribution and license configuration. The object shows the upload options; it does not initialize an editor or implement /api/repair-images.

The endpoint receives image uploads, stores the accepted image and returns JSON with a location string. For example, this fictional response describes an application-relative address:

{"location":"/media/repairs/valve-018.png"}

Return the actual stored address. A successful HTTP response containing a login page or a link property does not satisfy this contract. The server must enforce upload authorization, file size and permitted image content, and assign a storage name that avoids accidental overwrites.

The image plugin supplies image insertion controls. It does not supply your storage service. Consult the Image plugin reference for the dialog options used by your installation.

Capture the value after pending uploads complete

Place the ordering in the real Save handler:

async function captureRepairBulletin(editor) {
  const results = await editor.uploadImages();
  if (results.some(result => result.status !== true)) {
    throw new Error('An image upload did not complete successfully.');
  }
  return editor.getContent();
}

Here editor is the initialized instance for this bulletin. The Editor API describes per-image results; the current upload implementation exposes a Boolean status. A resolved Promise can contain an unsuccessful result. Await this helper and pass its returned string to the existing document-save operation. Show an upload or save failure to the author and retain the editable document for retry.

Prevent overlapping Save actions while this operation runs. If the product promises a single captured revision, also keep the editing and record-switching policy explicit during upload and capture. Otherwise, an author can add another image or switch bulletins while the operation is pending. A resolved upload Promise alone cannot establish which application record should receive the HTML.

When submitting a backing form, synchronize its editor value after uploads as required by that integration. Reading a stale textarea earlier in the handler can undo the correct ordering. The TinyMCE current-content guide explains editor HTML and backing-field synchronization.

Use the current custom-handler contract when necessary

If the application needs its own transport, images_upload_handler receives blobInfo and a progress callback. It returns a Promise resolving to the uploaded image URL. Reject the Promise on failure. This is a different contract from the built-in endpoint's JSON response, although the resulting image location serves the same purpose.

Older examples may show callback arguments instead of the current Promise interface. Match the handler to the installed TinyMCE release. Do not report 100 percent progress merely because the request started; progress should reflect the transfer information available from your transport.

For cross-origin endpoints, examine the actual browser request and CORS response. Enabling credentials changes which requests send credentials; it does not grant upload permission or make a missing CORS policy work.

Trace the valve photograph through two saved objects

In the development application, paste the photograph and choose Save immediately. Inspect the image upload response, the editor HTML after uploads resolve, and the document-save payload. The payload should reference the accepted stored image rather than the earlier local representation.

Reopen the bulletin in the intended reviewer view. Confirm the photograph loads beside the cracked-valve instruction, then try a rejected image and a failed upload. Those failures should remain visible to the author and should not be reported as a completed bulletin save.

Finally, check the image's lifetime and reader permissions. A stored document can outlive a temporary media URL. Retain the valve photograph until both the saved bulletin and its maintenance reviewer can retrieve it through the application's real access rules.

Keep reading