Migrating from TinyMCE 6 to TinyMCE 8

Overview

The process for setting up a basic TinyMCE 8.0 instance is similar to TinyMCE 6, but there are important changes across versions 7 and 8 that require attention.

Most configuration changes in TinyMCE 8.0 affect complex use cases, such as custom plugins and customized user interface components, but some breaking changes require immediate attention.

This documentation details the changes in TinyMCE 8.0 that integrators using TinyMCE 6 should consider when upgrading.

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

For support related to migration, please contact Tiny Support.
Open Source users: please report issues in the TinyMCE GitHub Repository.

Key Changes

UI Themes and Skins

The theme and skin system has been updated across versions 7 and 8:

  • Modern Theme: Replaced by the silver theme with oxide skin

  • Lightgray Theme: Replaced by the silver theme with oxide skin

  • Mobile Theme: Replaced by the silver theme with oxide skin

Migration Steps:

  1. Update theme configuration to use silver theme

  2. Update skin configuration to use oxide skin

  3. Test UI appearance and functionality

Example:
// Old TinyMCE 6 configuration
tinymce.init({
  selector: "textarea",
  theme: "modern",
  skin: "lightgray"
});

// New TinyMCE 7+ configuration
tinymce.init({
  selector: "textarea",
  theme: "silver",
  skin: "oxide"
});

Plugin Ecosystem

The TinyMCE plugin ecosystem underwent changes starting in version 7.0, with several plugins being removed or reclassified.

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

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

  • Now Premium Only:

    • 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.

Plugin Migration Examples

  • template (removed in v7):

  • imagetools (removed in v6):

    • Use the premium Enhanced Image Editing feature.

    • Ensure you have a valid commercial license for the Enhanced Image Editing feature.

  • textcolor (removed in v6):

    • Use the premium Color Picker plugin.

    • Ensure you have a valid commercial license for the Color Picker feature.

Content Structure

The content structure requirements have been updated:

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

Configuration Changes

Several configuration options have been updated across versions 7 and 8:

  • New Defaults:

Example:
tinymce.init({
  selector: "textarea",
  highlight_on_focus: true,
  convert_unsafe_embeds: true,
  sandbox_iframes: true,
  sandbox_iframes_exclusions: ["youtube.com", "vimeo.com"],
  license_key: "T8LK:...", // New format required
  crossorigin: (url, resourceType) => 'anonymous'
});

Licensing Changes (GPL v2+ and Commercial)

TinyMCE 8.0 introduces significant changes to the licensing system:

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

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

  • Mandatory License Key: All deployments now require a valid license key

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

API Changes

Deprecated in TinyMCE 8

editor.selection.setContent

The editor.selection.setContent API has been deprecated and will be removed in TinyMCE 9.

Migration Steps:

  1. Replace editor.selection.setContent with editor.insertContent

  2. Update custom plugins that use the old method

  3. Test content insertion in your editor instances

Example:
// Deprecated in TinyMCE 8, will be removed in 9
editor.selection.setContent('<p>New content</p>');

// New approach
editor.insertContent('<p>New content</p>');

fire() method

The fire() method has been replaced by dispatch() for event handling. The fire() method will be removed in TinyMCE 9 to avoid confusion with its name.

Migration Steps:

  1. Search codebase for all uses of the fire() method

  2. Replace each instance with dispatch()

  3. Review and update third-party plugins

  4. Test all custom event handling

Example:
// Deprecated in TinyMCE 8, will be removed in 9
editor.fire('someEvent');

// New approach
editor.dispatch('someEvent');

addButton, addMenuItem, and windowManager.open

The addButton, addMenuItem, and windowManager.open methods have been replaced by the editor.ui.registry.* API.

Migration Steps:

  1. Replace all instances of editor.addButton with editor.ui.registry.addButton

  2. Replace all instances of editor.addMenuItem with editor.ui.registry.addMenuItem

  3. Replace all instances of editor.windowManager.open with editor.windowManager.open

  4. Update custom plugins that use the old methods

  5. Test button and menu functionality in your editor instances

Example:
// Deprecated in TinyMCE 8, will be removed in 9
editor.addButton('myButton', {
  text: 'My Button',
  onclick: function() {
    editor.insertContent('Hello World!');
  }
});

// New approach
editor.ui.registry.addButton('myButton', {
  text: 'My Button',
  onAction: function() {
    editor.insertContent('Hello World!');
  }
});

editor.documentBaseUrl

The editor.documentBaseUrl property has been removed. Use editor.editorManager.documentBaseURI.getURI() instead.

Migration Steps:

  1. Search your codebase for all instances of editor.documentBaseUrl

  2. Replace them with tinymce.activeEditor.documentBaseURI.getURI() (or editor.documentBaseURI.getURI() if you have an editor reference)

  3. Test any functionality that depends on document base URL

Example:
// Deprecated in TinyMCE 8, will be removed in 9
const baseUrl = editor.documentBaseUrl;

// New approach
const baseUrl = editor.documentBaseURI.getURI();

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 approach
editor.execCommand('ToggleToolbarDrawer', false, { skip_focus: true });

// New approach
editor.execCommand('ToggleToolbarDrawer', false, { skipFocus: true });

Removed Methods

Legacy API Methods (removed in v6)

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

Autocompleter ch property (removed in 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' }
    ];
  }
});

remove_trailing_brs property (removed in v7)

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

Impact:

  • DomParser no longer supports the remove_trailing_brs option

  • This affects custom DomParser configurations

  • May impact content parsing behavior

Migration Steps:

  1. Remove remove_trailing_brs from DomParser configurations

  2. Test content parsing behavior

  3. Update any custom DomParser implementations

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' }
  ]
});

table_responsive_width replaced by table_sizing_mode (v7)

The table_responsive_width option has been replaced by table_sizing_mode in TinyMCE 7.0.

Migration Steps:

  1. Replace table_responsive_width with table_sizing_mode in your configuration

  2. Update the option value to match the new API

  3. Test table responsive behavior

Example:
// Old TinyMCE 6 configuration
tinymce.init({
  selector: "textarea",
  table_responsive_width: true
});

// New TinyMCE 7+ configuration
tinymce.init({
  selector: "textarea",
  table_sizing_mode: "responsive"
});

force_hex_color option (removed in v7)

The force_hex_color option has been removed. Only RGB values in absolute format like rgb(255, 255, 255) are now converted to HEX values.

Plugin Changes

Template Plugin Removal (v7)

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

Image Tools Plugin Removal

The imagetools plugin was removed in TinyMCE 6.0. If you were using this plugin, you need to migrate to the premium Enhanced Image Editing feature.

Migration Steps: 1. Remove imagetools from your plugins list 2. Add editimage to your plugins list (premium feature) 3. Ensure you have a valid commercial license for the Enhanced Image Editing feature 4. Update any custom image editing configurations

Example:
// Old TinyMCE 5 configuration
tinymce.init({
  selector: "textarea",
  plugins: "imagetools",
  imagetools_toolbar: "rotateleft rotateright | flipv fliph | editimage imageoptions"
});

// New TinyMCE 6+ configuration
tinymce.init({
  selector: "textarea",
  plugins: "editimage", // Premium feature
  editimage_toolbar: "rotateleft rotateright | flipv fliph | editimage imageoptions"
});

Text Color Plugin Removal

The textcolor plugin was removed in TinyMCE 6.0. If you were using this plugin, you need to migrate to the premium Color Picker plugin.

Migration Steps: 1. Remove textcolor from your plugins list 2. Add colorpicker to your plugins list (premium feature) 3. Ensure you have a valid commercial license for the Color Picker feature 4. Update any custom color picker configurations

Example:
// Old TinyMCE 5 configuration
tinymce.init({
  selector: "textarea",
  plugins: "textcolor",
  toolbar: "forecolor backcolor"
});

// New TinyMCE 6+ configuration
tinymce.init({
  selector: "textarea",
  plugins: "colorpicker",
  toolbar: "forecolor backcolor"
});

Media URL Resolver Changes (v7)

In TinyMCE 6 and earlier, the media_url_resolver option provided resolve and reject callbacks, rather than a Promise. In TinyMCE 7, the media_url_resolver option now requires a Promise to be returned.

Migration Steps:

  1. Update media_url_resolver implementations to return Promises

  2. Test media URL resolution functionality

  3. Update any custom media handling logic

Example:
// Old TinyMCE 6 approach
tinymce.init({
  selector: "textarea",
  media_url_resolver: function(data, resolve, reject) {
    // Custom logic here
    resolve(data.url);
  }
});

// New TinyMCE 7+ approach
tinymce.init({
  selector: "textarea",
  media_url_resolver: function(data) {
    return new Promise(function(resolve, reject) {
      // Custom logic here
      resolve(data.url);
    });
  }
});

UI and UX Changes

Table Height Changes (v7)

In TinyMCE 7.0, the way cell and row heights are applied to tables has been changed:

  • When a table is resized using the resize handles or the "Row properties" dialog, existing height styles will be stripped from td/th elements where applicable and only applied to the table element and tr elements.

Notification Close Button (v7)

In previous versions of TinyMCE, notifications were able to be displayed without a close button (X). Accessibility is an important component of the editor, and when this button is not in a notification, that notification cannot be closed via keyboard navigation.

In TinyMCE 7.0, notifications are now forced to have a close button to improve accessibility.

Split Button Changes (v8)

In TinyMCE 8.0, split toolbar buttons now render as two distinct components: one for the primary action and one for the dropdown chevron.

This structural change modifies the DOM layout of split buttons and may break custom CSS rules that rely on the previous structure.

Migration Steps:

  1. Update your split button usage to align with the new structure, including support for the chevronTooltip option. Refer to Split Toolbar Buttons for updated configuration details.

  2. Test the rendering and interaction of split buttons in your editor to verify expected behavior.

Security Changes

Sandbox Iframes (v7)

In TinyMCE 7.0, the default for sandbox_iframes will change from false to true, meaning that all iframe elements inserted into the editor will be given the sandbox="" attribute by default, preventing most actions, including scripting and same-origin access, which may break existing editor content or produce undesirable effects.

To prevent any expected iframes from being sandboxed, we recommend adding the source domains of such iframes to the new sandbox_iframes_exclusions option list, and including the domains in the default list where necessary. To prevent all iframes from being sandboxed, set the option sandbox_iframes to false in your editor configuration.

Convert Unsafe Embeds (v7)

In TinyMCE 7.0, the default value for convert_unsafe_embeds will change from false to true, meaning that all object and embed tags will automatically be converted to different elements when inserted to the editor.

DOMPurify Update (v8)

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

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 (v8)

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

Migration Steps:

  1. Evaluate alternative integration options

  2. Plan migration timeline to complete before December 31, 2025

Medical English Dictionary Discontinuation

The "Medical English (UK)" dictionary has been discontinued and is no longer available in TinyMCE 8.0.

Migration Steps:

  1. Remove "Medical English (UK)" from spellchecker configurations

  2. Remove any custom dictionary integrations related to Medical English

  3. Test spellchecker functionality with remaining dictionaries

  4. Configure alternative medical dictionary if required

Transition from Java WAR Files to Containerized Services (v8)

TinyMCE 8.0 no longer includes Java WAR files for backend services like the spell checker. Customers are required to migrate to modern Docker/OCI containers for self-hosted deployments.

Migration Steps:

  1. Inventory current WAR file deployments

  2. Review containerization requirements for your environment

  3. Plan transition timeline to containerized services

  4. Set up container infrastructure (Docker/Kubernetes)

  5. Deploy and test containerized services

  6. Update service connection configurations

  7. Contact Tiny Support if legacy WAR files are still needed

Migration Tips

License Migration checklist:

  • Contact support for new TinyMCE 8.0 license key or use GPL for the open source version

  • Install license key manager addon for commercial licenses

  • Update configuration with new license key format

  • Test editor functionality with new license

  • Verify all premium features are working

Custom Skin Migration checklist:

  • Confirm whether your project uses a custom skin.

  • Rebuild your custom skin using the TinyMCE 8 codebase. See Creating a Skin for instructions.

  • Update your split button usage to align with the new structure, including support for the chevronTooltip option. Refer to Split Toolbar Buttons for updated configuration details.

  • Test the rendering and interaction of split buttons in your editor to verify expected behavior.

General Migration checklist:

  • 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

  • Autocompleter configuration uses trigger instead of ch

  • 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

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

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

Next Steps

After completing your migration:

  • Test all functionality thoroughly

  • Update your documentation

  • Train your team on any new features

  • Consider upgrading to the latest TinyMCE version for ongoing support