Migrating from TinyMCE 5 to TinyMCE 8

Overview

TinyMCE has evolved significantly from version 5 to version 8.0, introducing architectural improvements, modern UI enhancements, stricter security defaults, and updated plugin structures. This comprehensive guide outlines the critical breaking changes, recommended migration action steps, and top-level configuration adjustments required to upgrade from TinyMCE v5 to v8.0.

This guide provides a complete migration path from TinyMCE 5 to TinyMCE 8, covering all changes across versions 6, 7, and 8 in a single comprehensive document.

Key Changes

UI Themes and Skins

  • Minor Adjustments: Oxide-based skins from v5 remain mostly compatible but may require small CSS adjustments for v8.0.

  • Impact: Test custom skins visually, as minor DOM changes can affect layout and styling.

  • Browser Support: Internet Explorer 11 is no longer supported in v8.0 (dropped in v6), requiring modern browsers.

  • Split Button Changes: TinyMCE 8 introduces structural changes to split buttons that may affect custom skins.

Example:
tinymce.init({
  selector: "textarea",
  skin: "oxide-dark",
  content_css: "dark",
});

Plugin Ecosystem

The TinyMCE plugin ecosystem underwent a significant overhaul starting in version 6.0, with many plugins either removed, integrated into the core, or made premium-only. The following summarizes these changes.

  • Removed Plugins (no longer available as of TinyMCE 6.0):

    • bbcode, fullpage, legacyoutput: Deprecated in 5.9.0. Removed in 6.0.

    • imagetools: Removed in 6.0. Replaced by the premium Enhanced Image Editing feature, available via the editimage plugin introduced in TinyMCE 6.0.

    • textcolor: Removed in 6.0. Use the premium Color Picker plugin instead.

  • Integrated into TinyMCE core:

    • paste, hr, table, noneditable, nonbreaking, print, colorpicker and contextmenu: These plugins were absorbed into TinyMCE core and no longer require separate installation. See Copy and Paste, Table, Non-editable Content, and Context Menu for more information.

    • contextmenu: Deprecated in version 5.0 following the integration of context menu functionality into TinyMCE core editor. Removed in version 6.0. For more information, see the contextmenu documentation.

    • tabfocus: Removed in 6.0. Keyboard navigation via Tab is now handled by the browser and TinyMCE core.

  • Now Premium Only:

    • mediaembed, tableofcontents: These features are available through premium plugins. See Media Embed and Table of Contents for more information.

    • spellchecker: Deprecated in 5.9.0. Removed in 6.0.

      • Use browser_spellcheck: true or the premium Spell Checker plugin.

    • advtemplate: Replaces the template plugin for advanced templating use cases.

    • template: Removed in 7.0. Replaced by the premium Templates plugin.

    • toc: Renamed to tableofcontents and now premium.

Plugin Migration Examples

  • contextmenu (removed in v6):

  • bbcode (removed in v6):

    • Implement custom parsing or server-side processing if BBCode support is required.

  • fullpage (removed in v6):

    • Use custom templates or server-side logic to handle full HTML documents.

  • template (removed in v7):

    • Use the premium advtemplate plugin or implement custom modal dialogs.

  • textcolor (removed in v6):

    • Use the forecolor and backcolor toolbar buttons for text color functionality.

  • imagetools: (removed in v6):

Toolbar and Menu name changes

If you used the following toolbar buttons or menu options, they have changed names across major TinyMCE versions. Please refer to the release notes for each version for complete migration details.

TinyMCE 5 โ†’ TinyMCE 6:

  • formatselect โ†’ blocks (toolbar item)

  • blockformats โ†’ blocks (menu item)

  • styleselect โ†’ styles (toolbar item)

  • formats โ†’ styles (menu item)

  • fontselect โ†’ fontfamily (toolbar item)

  • fontformats โ†’ fontfamily (menu item)

  • fontsizeselect โ†’ fontsize (toolbar item)

  • fontsizes โ†’ fontsize (menu item)

  • imagetools โ†’ editimage (plugin and related toolbar items)

  • toc โ†’ tableofcontents (plugin, menu item, and toolbar item)

  • tocupdate โ†’ tableofcontentsupdate (toolbar item)

TinyMCE 6 โ†’ TinyMCE 7:

  • InsertOrderedList and InsertUnorderedList commands were removed from TinyMCE core and are now provided by the Lists plugin.

  • Default text pattern triggers were updated to activate on Space instead of Enter. A trigger property was added to configure block-level text pattern behavior.

TinyMCE 7 โ†’ TinyMCE 8:

  • Several API methods have been deprecated or removed (see the API Changes section below for details)

  • License key system has been updated with new format requirements

  • DOMPurify sanitization has been strengthened

Refer to the latest release notes at latest release notes for further details.

Always refer to the latest plugin documentation at plugins for up-to-date availability and migration guidance.
Example of Toolbar Changes:
tinymce.init({
  selector: "textarea",
  toolbar: "undo redo | forecolor backcolor | bold italic | alignleft aligncenter alignright alignjustify",
  plugins: ["lists link image table code"] // Note: xref:lists.adoc[Lists], xref:link.adoc[Link], xref:image.adoc[Image], xref:table.adoc[Table], and xref:code.adoc[Code] plugins
});

Content Structure

  • Removed: forced_root_block: false.

    • Requirement: All editor content must be enclosed in block elements (e.g., <p>).

Example:
tinymce.init({
  selector: "textarea",
  forced_root_block: "p"
});

Configuration Changes

  • Removed in TinyMCE 6.0: Legacy mobile theme was removed, but mobile-specific configuration is still supported through the mobile option.

  • UI API Updates:

    • Update custom plugins to use editor.ui.registry.*.

    • Replace deprecated methods like editor.addButton, editor.addMenuItem, and editor.windowManager.open.

  • Promise-Based Methods:

    • media_url_resolver now requires a Promise return for asynchronous handling.

  • Removed Options:

    • force_hex_color has been removed. Use standard CSS color declarations.

Text Pattern Changes (v7)

TinyMCE 7.0 updated the default behavior of text_patterns to apply formats when the user presses the Space key instead of Enter.

Impact:

  • Markdown-style formatting now triggers on Space key press

  • Previous Enter key behavior can be restored by configuring trigger: 'enter'

  • This affects all text patterns including headings, lists, blockquotes, and horizontal rules

Migration Steps:

  1. Test existing text pattern behavior

  2. Update configurations if Enter key triggering is required

  3. Review user experience with new Space key triggering

  4. Consider updating user documentation about text pattern behavior

Example:
// Default TinyMCE 7+ behavior (Space key trigger)
tinymce.init({
  selector: "textarea",
  text_patterns: [
    { start: '#', format: 'h1', trigger: 'space' },
    { start: '##', format: 'h2', trigger: 'space' },
    { start: '1.', cmd: 'InsertOrderedList', trigger: 'space' },
    { start: '*', cmd: 'InsertUnorderedList', trigger: 'space' },
    { start: '>', cmd: 'mceBlockQuote', trigger: 'space' }
  ]
});

// Restore previous behavior (Enter key trigger)
tinymce.init({
  selector: "textarea",
  text_patterns: [
    { start: '#', format: 'h1', trigger: 'enter' },
    { start: '##', format: 'h2', trigger: 'enter' },
    { start: '1.', cmd: 'InsertOrderedList', trigger: 'enter' },
    { start: '*', cmd: 'InsertUnorderedList', trigger: 'enter' },
    { start: '>', cmd: 'mceBlockQuote', trigger: 'enter' }
  ]
});

The remove_trailing_brs setting was removed from the DomParser API in TinyMCE 7.0, after being deprecated in TinyMCE 6.5.

Autocompleter Configuration Changes (v7)

The ch configuration property for autocompleters has been removed. Use the trigger property instead.

Migration Steps:

  1. Replace ch: '<string>' with trigger: '<string>' in autocompleter configurations

  2. Test autocompleter functionality

  3. Update any custom autocompleter implementations

Example:
// Old TinyMCE 6 configuration
editor.ui.registry.addAutocompleter('myautocompleter', {
  ch: '@',
  minChars: 0,
  fetch: function(pattern) {
    return [
      { value: 'john@example.com', text: 'John Doe' },
      { value: 'jane@example.com', text: 'Jane Smith' }
    ];
  }
});

// New TinyMCE 7+ configuration
editor.ui.registry.addAutocompleter('myautocompleter', {
  trigger: '@',
  minChars: 0,
  fetch: function(pattern) {
    return [
      { value: 'john@example.com', text: 'John Doe' },
      { value: 'jane@example.com', text: 'Jane Smith' }
    ];
  }
});

table_responsive_width replaced by table_sizing_mode (v7)

Example:
// Old TinyMCE 6 configuration
editor.ui.registry.addAutocompleter('myautocompleter', {
  ch: '@',
  minChars: 2,
  fetch: function(pattern) {
    return Promise.resolve(['item1', 'item2']);
  }
});

// New TinyMCE 7+ configuration
editor.ui.registry.addAutocompleter('myautocompleter', {
  trigger: '@',
  minChars: 2,
  fetch: function(pattern) {
    return Promise.resolve(['item1', 'item2']);
  }
});
  • table_responsive_width replaced by table_sizing_mode.

    • Default Changes in TinyMCE 7.0:

  • sandbox iframes: Now defaults to true (adds sandbox attribute to iframes)

  • convert_unsafe_embeds: Now defaults to true (converts object/embed elements to safer alternatives)

  • highlight_on_focus: Now defaults to true (adds focus outline to editors)

    • New Options in TinyMCE 7.0:

  • license_key: Must be set to gpl or a valid license key

  • sandbox_iframes_exclusions: List of URL hosts to exclude from iframe sandboxing

    • New Options in TinyMCE 8.0:

  • Enhanced license key system with new format requirements

  • Stricter DOMPurify sanitization with SAFE_FOR_XML enabled by default

  • New crossorigin configuration option for cross-origin resource loading

Example:
tinymce.init({
  selector: "textarea",
  toolbar: "undo redo | blocks | bold italic | alignleft aligncenter alignright alignjustify | outdent indent | removeformat",
  toolbar_mode: "floating",
  license_key: "T8LK:...", // New format required in TinyMCE 8.0
  // Security options now enabled by default in TinyMCE 7.0
  sandbox_iframes: true,
  convert_unsafe_embeds: true,
  // Optional: exclude specific domains from iframe sandboxing
  sandbox_iframes_exclusions: ["youtube.com", "vimeo.com"],
  // Accessibility improvement, now enabled by default
  highlight_on_focus: true,
  // New in TinyMCE 8.0: Cross-origin resource loading
  crossorigin: (url, resourceType) => 'anonymous'
});
For up-to-date plugin availability and configuration references, see link:https://www.tiny.cloud/docs/plugins/.

Refer to version-specific release notes for changes in toolbar button names and command availability across versions 5, 6, 7, and 8. For example:

TinyMCE 5 โ†’ TinyMCE 6:

  • formatselect โ†’ blocks

  • styleselect โ†’ styles

  • fontselect โ†’ fontfamily

  • fontsizeselect โ†’ fontsize

  • imagetools โ†’ editimage

  • toc โ†’ tableofcontents

TinyMCE 6 โ†’ TinyMCE 7:

  • InsertOrderedList / InsertUnorderedList commands removed from TinyMCE core (use lists plugin).

  • Default text pattern triggers updated from Enter to Space, configurable via trigger.

TinyMCE 7 โ†’ TinyMCE 8:

  • editor.selection.setContent โ†’ editor.insertContent

  • editor.fire() โ†’ editor.dispatch()

  • editor.documentBaseUrl โ†’ editor.documentBaseURI.getURI()

Licensing Changes (GPL v2+ and Commercial)

  • Legacy License: TinyMCE 5 was licensed under LGPL 2.1.

  • New License: TinyMCE 8.0 is licensed under GPL v2+ or a commercial license.

  • Impact: The License key option is required as part of your editor configuration if self-hosting TinyMCE. This requirement does not apply if you are loading TinyMCE from the cloud.

License Key System Update in TinyMCE 8

TinyMCE 8 introduces a new license key system that requires immediate attention:

  • New Format: License keys now use the prefix T8LK: for commercial licenses or GPL+T8LK: for GPL with Premium Features

  • Mandatory Requirement: Self-hosted deployments now require a valid license key; without one, the editor will be set to readonly

  • License Key Manager: Self-hosted commercial deployments require the new License Key Manager addon

For complete details, see License Key System Update in the 7โ†’8 migration guide.

Example:
tinymce.init({
selector: "textarea",
license_key: "T8LK:your-license-key" // New format required
});

API Changes

Several API methods have been deprecated or removed across versions 6-8. Key changes include:

  • Deprecated in TinyMCE 8:

    • editor.selection.setContent โ†’ Use editor.insertContent instead

    • editor.fire() โ†’ Use editor.dispatch() instead

    • editor.documentBaseUrl โ†’ Use editor.documentBaseURI.getURI() instead

skipFocus and skip_focus Consolidation (v8)

The skipFocus and skip_focus options for the ToggleToolbarDrawer command have been consolidated into a single, more consistent argument in TinyMCE 8.0.

Impact:

  • Reduces API complexity

  • Clarifies intended behavior

  • Requires updating command calls

Migration Steps:

  1. Locate all instances of ToggleToolbarDrawer command usage

  2. Replace skip_focus with skipFocus in command parameters

  3. Test toolbar drawer behavior

Example:
// Old TinyMCE 7 usage
editor.execCommand('ToggleToolbarDrawer', false, null, { skip_focus: true });

// New TinyMCE 8 usage
editor.execCommand('ToggleToolbarDrawer', false, { skipFocus: true });
  • Removed Methods:

    • editor.addButton, editor.addMenuItem, editor.windowManager.open (replaced by editor.ui.registry.* API)

For complete API migration details, see Core API Changes in the 7โ†’8 migration guide.

Plugin Changes

Template Plugin Removal

The template plugin was removed in TinyMCE 7.0. If you were using this plugin, you need to migrate to the premium Templates plugin.

Migration Steps:

  1. Remove template from your plugins list

  2. Add templates to your plugins list

  3. Update your configuration to use the new Templates plugin API

  4. Ensure you have a valid commercial license for the Templates plugin

Example:
// Old TinyMCE 5/6/7 configuration
tinymce.init({
  selector: "textarea",
  plugins: "template",
  templates: [
    {title: 'Test template 1', content: 'Test 1'},
    {title: 'Test template 2', content: 'Test 2'}
  ]
});

// New TinyMCE 8 configuration
tinymce.init({
  selector: "textarea",
  plugins: "templates",
  templates: [
    {title: 'Test template 1', content: 'Test 1'},
    {title: 'Test template 2', content: 'Test 2'}
  ]
});

Media URL Resolver Changes (v7)

The media_url_resolver option now requires a Promise-based implementation instead of synchronous callbacks.

Example:
// Old TinyMCE 5/6 implementation
tinymce.init({
  selector: "textarea",
  media_url_resolver: function (data, resolve) {
    resolve({
      html: '<iframe src="' + data.url + '" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>'
    });
  }
});

// New TinyMCE 7+ implementation
tinymce.init({
  selector: "textarea",
  media_url_resolver: function (data) {
    return new Promise(function (resolve) {
      resolve({
        html: '<iframe src="' + data.url + '" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>'
      });
    });
  }
});

UI and UX Changes

Table Height Changes (v7)

TinyMCE 7.0 changed how table heights are handled. Tables now use min-height instead of height for better responsive behavior.

Impact:

  • Existing table height configurations may need adjustment

  • Custom CSS targeting table heights should be reviewed

  • Responsive table behavior may change

Split Button Changes (v8)

TinyMCE 8.0 introduces structural changes to split buttons that may affect custom skins and CSS.

Changes: * Split button DOM structure has been updated * CSS selectors for split buttons may need adjustment * Custom skins should be tested for split button compatibility

Testing: * Verify split button functionality in custom skins * Check CSS compatibility with new split button structure * Test split button interactions and dropdowns

Security Changes

DOMPurify Update

TinyMCE 8.0 updates the DOMPurify dependency to version 3.2.6 and enables the SAFE_FOR_XML flag by default. This is a breaking change: content that previously passed sanitization in TinyMCE 7 may now be stripped or altered during the sanitization process.

Impact:

  • Stricter content sanitization

  • Some previously allowed content may be stripped

  • XML-specific sanitization rules are now applied

Migration Steps:

  1. Test content sanitization behavior with your specific content

  2. Review any custom sanitization configurations

  3. Update content if necessary to comply with stricter rules

Example:
// Content that may be affected by stricter sanitization
const content = '<div><script>alert("test")</script></div>';

// Test sanitization behavior
const sanitized = editor.dom.sanitize(content);
console.log('Sanitized content:', sanitized);

Cross-Origin Resource Loading

Migration Steps:

  1. Test existing content for sanitization changes

  2. Review custom sanitization configurations

  3. Update any content that relies on previous sanitization behavior

Cross-Origin Resource Loading

TinyMCE 8.0 introduces stricter controls for cross-origin resource loading.

New Configuration:

  • crossorigin attribute support for external resources

  • Enhanced security for loading external content

  • Better control over resource loading policies

Migration Steps:

  1. Review external resource loading configurations

  2. Add crossorigin attributes where appropriate

  3. Test cross-origin resource loading behavior

Service Changes

Java Swing Integration Deprecation

Java Swing integration has been deprecated in TinyMCE 8.0 and will reach end-of-life as of December 31, 2025.

Impact:

  • Java Swing-based integrations need migration planning

  • Alternative integration methods should be considered

  • Legacy Java integrations may stop working

Migration Steps:

  1. Identify Java Swing integrations in your application

  2. Plan migration to modern integration methods

  3. Test alternative integration approaches

Medical English Dictionary Discontinuation

The "Medical English (UK)" dictionary has been discontinued.

Impact:

  • Applications using this dictionary need to switch to alternatives

  • Spell checking configurations may need updates

  • Language pack references should be updated

Migration Steps:

  1. Remove references to "Medical English (UK)" dictionary

  2. Switch to alternative English dictionaries

  3. Update spell checking configurations

Service Version Decoupling

TinyMCE services are now decoupled from the editor version, allowing for independent updates.

Benefits: * Services can be updated independently * Better security and performance updates * Reduced dependency on editor version updates

Migration Steps:

  1. Review service integration configurations

  2. Update service endpoints if needed

  3. Test service functionality with TinyMCE 8

WAR File to Container Migration

TinyMCE services are transitioning from Java WAR files to containerized services.

Impact:

  • Deployment methods need to be updated

  • Service configurations may change

  • Infrastructure requirements may be different

Migration Steps:

  1. Plan migration from WAR file deployments

  2. Update deployment infrastructure

  3. Test containerized service deployments

Migration Tips

  1. Backup and Prepare: Ensure comprehensive backups before upgrading.

  2. Update Core Initialization:

    1. Update theme, skin, and to reflect the new oxide theme and skin.

      1. In TinyMCE 4, there were multiple themes available including 'modern', 'inlite', and 'mobile'. These themes were removed in TinyMCE 5 and combined into a single responsive theme called "Silver".

    2. Update forced_root_block: false options to forced_root_block: "p".

    3. Consolidate toolbars.

    4. Review new v8.0 defaults for security settings.

    5. Update license key to new format if self-hosting.

  3. Plugin Migration:

    1. Remove deprecated plugins from your configuration.

    2. Update renamed plugins (e.g., spellchecker โ†’ tinymcespellchecker).

    3. Verify premium plugins for compatibility.

    4. Install License Key Manager addon if using commercial license.

  4. Custom Code Updates:

    1. Rewrite custom plugins using the editor.ui.registry.* API.

    2. Replace v5 API methods like editor.addButton, editor.addMenuItem, editor.windowManager.open.

    3. Update media embed handling (media_url_resolver API changes). see media_url_resolver.

    4. Replace deprecated API methods (editor.selection.setContent, editor.fire(), etc.).

  5. CSS Updates:

    1. Update custom styles to align with the new Oxide standard. While many .mce-* classes have been replaced with .tox-* classes, some .mce-* prefixes remain in use. Review your CSS to ensure compatibility.

    2. Update split button CSS if using custom skins (TinyMCE 8 change).

  6. Testing and Deployment:

    1. Thoroughly test your updated configuration before production deployment.

    2. Validate media, iframe, and content security settings.

    3. Test license key functionality and premium features.

    4. Verify DOMPurify sanitization behavior with your content.

To make your upgrade smooth, check the following version-specific migration guides:

These include deeper configuration notes, plugin replacements, and examples.

Next Steps

Ensure you follow the migration steps carefully to avoid common issues like missing plugins, broken UI, and unexpected formatting changes. Consider running your updated editor in a staging environment for a complete verification before final deployment.

Migration Checklist

Before deploying to production, verify:

  • License key is updated to new format (T8LK: prefix)

  • License Key Manager addon is installed (commercial licenses)

  • All deprecated API methods have been replaced (editor.selection.setContent, editor.fire(), etc.)

  • Custom skins have been rebuilt for TinyMCE 8 compatibility

  • DOMPurify sanitization behavior is tested with your content

  • Cross-origin resource loading is configured if needed

  • All premium features are working correctly

  • Media URL resolver has been updated to use Promises

  • Template plugin has been replaced with premium Templates plugin if needed

  • Language pack files are updated to RFC5646 format

  • Accessibility checker configurations are updated for W3C standards

  • Empty file references are removed from build processes

  • Java Swing integration migration is planned (if applicable)

  • Medical English dictionary references are removed

  • WAR file deployments are migrated to containerized services

  • Split button CSS is updated for custom skins

  • Table height handling is tested

  • Notification close button behavior is verified

  • Sandbox iframes configuration is reviewed

  • Convert unsafe embeds behavior is tested