You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

589 lines
22 KiB

  1. = Migrating from {productname} 7 to {productname} {productmajorversion}
  2. :navtitle: Migrating from TinyMCE 7
  3. :description: Guidance for migrating from TinyMCE 7 to TinyMCE 8
  4. :keywords: migration, considerations, premigration, pre-migration
  5. :release-version: 8.0
  6. :page-toclevels: 3
  7. == Introduction
  8. This guide provides a comprehensive overview of the breaking changes introduced in {productname} {release-version}, along with the necessary steps to migrate from {productname} 7.x. It covers key updates to APIs, plugins, and service configurations, including deprecated methods, renamed components, and removed features. These changes are designed to enhance performance, simplify configuration, and align with modern web standards, ensuring a smoother transition and continued compatibility for your integrations.
  9. [IMPORTANT]
  10. .Breaking Changes Quick Reference
  11. ====
  12. The following table summarizes all breaking changes in {productname} {release-version}. Each item links to detailed information further in the guide.
  13. Any items marked **"High"** level require immediate attention during migration.
  14. [cols="2,3,1",options="header"]
  15. |===
  16. |Breaking Change |Impact |Level
  17. |xref:license-key-system-update[License Key System]
  18. |Self-hosted deployments now require a new license key format and license key manager. Old keys are **not compatible**.
  19. |High
  20. |xref:dompurify-update-breaking-change[DOMPurify Update]
  21. |Sanitization is now stricter; content previously allowed may be stripped or altered.
  22. |High
  23. |xref:editor-selection-setcontent-deprecated[editor.selection.setContent]
  24. |Method deprecated. Use `editor.insertContent` instead.
  25. |Medium
  26. |xref:fire-method-deprecation[fire()]
  27. |Method deprecated. Use `dispatch()` for event handling.
  28. |Medium
  29. |xref:editor-documentbaseurl-removal[editor.documentBaseUrl]
  30. |Undocumented property removed. Use `editor.editorManager.documentBaseURI` instead.
  31. |Low
  32. |xref:skipfocus-consolidation[skipFocus and skip_focus]
  33. |Options consolidated to `skipFocus` in `ToggleToolbarDrawer`.
  34. |Low
  35. |xref:split-button-css-breaking-change[Split buttons]
  36. |Split button CSS classes and structure have changed.
  37. |Low
  38. |===
  39. ====
  40. [[license-key-system-update]]
  41. === Transition from Version 7 License Keys to Version {release-version} License Keys
  42. // #EPIC-192
  43. [IMPORTANT]
  44. ====
  45. This section applies to self-hosted installations only. For cloud deployments, license key management is handled automatically.
  46. ====
  47. {productname} {release-version} introduces an enhanced license key system that requires specific attention during migration.
  48. The complete licensing documentation xref:license-key.adoc[License Key Management] covers:
  49. * Detailed explanations of all license types (GPL, Commercial, GPL with Premium Features)
  50. * Time-based vs Version-locked license key differences
  51. * License states (Active, Grace Period, Expired, Invalid)
  52. * Deployment options (Cloud-only, Self-hosted, Hybrid)
  53. * Step-by-step configuration examples for each setup
  54. * Commercial License Key Manager setup and requirements
  55. * Troubleshooting and FAQ
  56. **Impact**: The new license key system introduces breaking changes that require updates to your configuration and code.
  57. **Key Migration Considerations**:
  58. * *License Key Format Change:* Version 7 keys are:
  59. ** Not compatible with {productname} {release-version}.
  60. ** New keys use the prefix `T8LK:` for commercial licenses or `GPL+T8LK:` for GPL with Premium Features.
  61. * *Mandatory Key Requirement:* Self-hosted deployments **now require** a valid license key; without one, the editor will be set to `readonly`.
  62. * *Commercial License Manager:* Self-hosted commercial deployments **require** the new License Key Manager addon.
  63. **Migration Steps:**
  64. . *Obtain New License Key:*
  65. +
  66. * link:https://www.tiny.cloud/contact/[Contact us] to obtain a new {productname} {release-version} license key, or use `gpl` for the open source version. See: xref:license-key.adoc#setting-the-license[setting the license] for details.
  67. +
  68. . *Update Configuration:*
  69. +
  70. [source, javascript]
  71. ----
  72. // Old TinyMCE 7 configuration
  73. tinymce.init({
  74. selector: '#editor',
  75. // No license key required
  76. });
  77. // New TinyMCE 8 configuration
  78. tinymce.init({
  79. selector: '#editor',
  80. license_key: 'T8LK:...' // New format required
  81. });
  82. ----
  83. ==== License Key Manager Setup
  84. When migrating to {productname} {release-version} with a commercial license, the License Key Manager addon is required for the editor to operate. The setup varies based on your deployment method:
  85. *CDN/Static Hosting:*
  86. * Ensure the supplied `licensekeymanager` folder is in your {productname} plugins directory:
  87. [tree]
  88. ----
  89. your-site/
  90. ├── tinymce/
  91. │ └── plugins/
  92. │ ├── licensekeymanager/ # Add this folder
  93. │ │ ├── plugin.min.js
  94. │ │ └── index.js
  95. │ └── ... other plugins
  96. ----
  97. *NPM/Module Bundler:*
  98. Install {productname} and ensure the license key manager is imported:
  99. [source, javascript]
  100. ----
  101. // Import TinyMCE
  102. import tinymce from 'tinymce';
  103. // Import the license key manager
  104. import 'tinymce/plugins/licensekeymanager';
  105. tinymce.init({
  106. selector: '#editor',
  107. license_key: 'T8LK:...' // New format required
  108. });
  109. ----
  110. *React/Next.js:*
  111. When using the `@tinymce/tinymce-react` package:
  112. [source, javascript]
  113. ----
  114. import { Editor } from '@tinymce/tinymce-react';
  115. import 'tinymce/plugins/licensekeymanager';
  116. export default function MyEditor() {
  117. return (
  118. <Editor
  119. init={{
  120. license_key: 'T8LK:...'
  121. }}
  122. />
  123. );
  124. }
  125. ----
  126. *PHP/Laravel:*
  127. Ensure the license key manager is included when publishing {productname} assets:
  128. [source, php]
  129. ----
  130. <script src="{{ asset('path/to/tinymce/tinymce.min.js') }}"></script>
  131. <script src="{{ asset('path/to/tinymce/plugins/licensekeymanager/plugin.min.js') }}"></script>
  132. <script>
  133. tinymce.init({
  134. selector: '#editor',
  135. license_key: 'T8LK:...'
  136. });
  137. </script>
  138. ----
  139. [IMPORTANT]
  140. ====
  141. * The license key manager is automatically included when using {companyname} Cloud.
  142. * The plugin does not need to be added to the `plugins` configuration option.
  143. * For bundled applications, the license key manager must be loaded before {productname} initialization.
  144. * For bundled applications, ensure the license key manager is not excluded during build optimization.
  145. ====
  146. For complete details on license key manager setup and troubleshooting, see xref:license-key.adoc##setting-up-the-commercial-license-key-manager[Setting up the Commercial License Key Manager].
  147. **License Migration checklist:**
  148. * [ ] Contact support for new {productname} {release-version} license key or use GPL for the open source version
  149. * [ ] Install license key manager addon for commercial licenses
  150. * [ ] Update configuration with new license key format
  151. * [ ] Test editor functionality with new license
  152. * [ ] Verify all premium features are working
  153. [[dompurify-update-breaking-change]]
  154. === DOMPurify Update and Stricter Sanitization (Breaking Change)
  155. // #TINY-12056
  156. {productname} {release-version} 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 {productname} 7 may now be stripped or altered during the sanitization process.
  157. [IMPORTANT]
  158. ====
  159. This change improves security and aligns with DOMPurify's recommended defaults. However, existing content and integrations that relied on the previous, less strict sanitization behavior may be impacted.
  160. ====
  161. **Key Changes**:
  162. * **DOMPurify upgraded to 3.2.6**
  163. * **`SAFE_FOR_XML` enabled** — This setting enforces stricter handling of comments and attribute values, preventing certain XSS vectors.
  164. * **Content Impact** — HTML comments containing tags, Internet Explorer conditional comments, and attributes with HTML-like values may now be removed during sanitization. Content that was previously allowed may be stripped.
  165. **Impact**: This change improves security by preventing potential XSS attacks through comments and attributes that were previously allowed. However, it may also result in content being stripped or altered unexpectedly.
  166. **Migration Steps:**
  167. * Review workflows and test content that previously relied on relaxed sanitization.
  168. * {productname} now provides the xref:content-filtering.adoc#allow_html_in_comments[Content Filtering: allow_html_in_comments option] option. Enabling this option allows HTML tags in comments with sanitization still enabled.
  169. [WARNING]
  170. Using `allow_html_in_comments` increases the risk of XSS vulnerabilities. xref:security.adoc#allow_html_in_comments[allow_html_in_comments] is not recommended for production use unless you fully understand the implications and have appropriate security measures in place.
  171. .Example: Content Differences
  172. |===
  173. |Content |{productname} 7 Output |{productname} {release-version} Output
  174. |`<div><!-- <p>Hello World</p> --></div>`
  175. |`<div><!-- <p>Hello World</p> --></div>`
  176. |`<div></div>`
  177. |`<iframe><!-- Hello World --></iframe>`
  178. |`<p><iframe sandbox=""><!-- Hello World --></iframe></p>`
  179. |``
  180. |`<script><!-- Hello World --></script>`
  181. |`<script><!-- Hello World --></script>`
  182. |``
  183. |===
  184. [NOTE]
  185. ====
  186. For information on disabling DOMPurify sanitization (not recommended), see xref:security.adoc#xss_sanitization-option[xss_sanitization option].
  187. ====
  188. == Core Changes
  189. [[split-button-css-breaking-change]]
  190. === Split button CSS structure updates
  191. // #TINY-8665
  192. {productname} {productmajorversion} updates the internal structure of split buttons. Split buttons now render as two separate components for the main action and the dropdown chevron.
  193. **Impact**: This change only affects users with custom skins.
  194. **Migration steps**:
  195. If you have a custom skin, rebuild it using the {productname} {productmajorversion} codebase. See xref:creating-a-skin.adoc[Creating a Skin] for guidance on the custom skin development process.
  196. **Migration checklist:**
  197. * [ ] Identify if you are using a custom skin.
  198. * [ ] Rebuild your custom skin using the {productname} {productmajorversion} codebase.
  199. * [ ] Test your custom skin with split buttons in {productname} {productmajorversion}.
  200. * [ ] Refer to xref:creating-a-skin.adoc[Creating a Skin] for details.
  201. == Core API Changes
  202. [discrete]
  203. === Breaking Changes Overview
  204. IMPORTANT: The following sections detail important changes that require updates to your code. Please review each section carefully.
  205. === Updated Methods
  206. [[skipfocus-consolidation]]
  207. ==== skipFocus and skip_focus
  208. // #TINY-12044
  209. The `skipFocus` and `skip_focus` options for the `ToggleToolbarDrawer` command have been consolidated into a single, more consistent argument. This reduces API complexity and clarifies the intended behavior.
  210. **Impact**: This change simplifies focus management, reducing the risk of confusion and unexpected behavior.
  211. **Migration steps:**
  212. [source, javascript]
  213. ----
  214. // Old approach (Deprecated) in TinyMCE 8
  215. editor.execCommand('ToggleToolbarDrawer', { skip_focus: false }, { skipFocus: true });
  216. // New approach (Recommended)
  217. editor.execCommand('ToggleToolbarDrawer', false, { skipFocus: true });
  218. ----
  219. **Migration checklist:**
  220. * [ ] Locate all instances of `ToggleToolbarDrawer` command usage
  221. * [ ] Replace `skip_focus` with `skipFocus` in command options
  222. * [ ] Update any custom plugins using this command
  223. * [ ] Test toolbar drawer behavior after changes
  224. '''
  225. === Removed Methods
  226. [[editor-documentbaseurl-removal]]
  227. ==== editor.documentBaseUrl
  228. [.discrete]
  229. // #TINY-12182
  230. The undocumented `editor.documentBaseUrl` property has been removed.
  231. .Example Usage
  232. [source,javascript]
  233. ----
  234. // Removed in TinyMCE 8
  235. console.log('documentBaseUrl', editor.documentBaseUrl);
  236. // Use this instead
  237. console.log('documentBaseURI', editor.documentBaseURI.getURI());
  238. ----
  239. TIP: Use `tinymce.activeEditor.documentBaseURI.getURI()` for all base URL operations.
  240. **Impact**: This change improves URL handling consistency by removing an undocumented API that was not aligned with the documented `documentBaseURI` property.
  241. **Migration steps:**
  242. To update all references of `documentBaseUrl` to the new API, replace any usage of `editor.documentBaseUrl` (or similar) with `tinymce.activeEditor.documentBaseURI.getURI()`. The property `documentBaseUrl` has been removed, and the correct way to access the document base URL is now through the `documentBaseURI` property, which is a URI object. You can then call `.getURI()` on it to get the string value of the URL.
  243. .For example, update this:
  244. [source, js]
  245. ----
  246. const baseUrl = editor.documentBaseUrl;
  247. ----
  248. to:
  249. [source, js]
  250. ----
  251. const baseUrl = tinymce.activeEditor.documentBaseURI.getURI();
  252. ----
  253. This change is necessary because the undocumented `editor.documentBaseUrl` API has been removed to improve URL handling consistency. The new approach uses the documented `documentBaseURI` property, which provides a URI object with methods such as `getURI()` to retrieve the full URL string.
  254. For more information see: link:https://www.tiny.cloud/docs/tinymce/latest/apis/tinymce.editor/#properties[tinymce.editor/#properties].
  255. **Migration checklist:**
  256. * [ ] Search your codebase for all instances of `editor.documentBaseUrl`.
  257. * [ ] Replace them with `tinymce.activeEditor.documentBaseURI.getURI()` (or `editor.documentBaseURI.getURI()` if you have an `editor` reference).
  258. '''
  259. === Deprecated Methods
  260. [[editor-selection-setcontent-deprecated]]
  261. ==== editor.selection.setContent
  262. [.discrete]
  263. // #TINY-12109
  264. The `editor.selection.setContent` API has been deprecated and will be removed in {productname} 9.
  265. *Impact*: This change simplifies content manipulation by consolidating insertion methods.
  266. **Migration steps:**
  267. To replace `editor.selection.setContent`, use `editor.insertContent` instead. The new method is more consistent with other content manipulation methods in {productname}.
  268. .Example Usage
  269. [source,javascript]
  270. ----
  271. // Deprecated in TinyMCE 8, will be removed in 9
  272. editor.selection.setContent('<p>New content</p>');
  273. // Recommended replacement
  274. editor.insertContent('<p>New content</p>');
  275. ----
  276. **Migration checklist:**
  277. * [ ] Replace all instances of `editor.selection.setContent` with `editor.insertContent`
  278. * [ ] Update custom plugins that use the old method
  279. * [ ] Test content insertion in your editor instances
  280. [[fire-method-deprecation]]
  281. ==== `fire()`
  282. // #TINY-12012, ref TINY-8102
  283. The `fire()` method has been replaced by `dispatch()` for event handling. The `fire()` method will be removed in {productname} 9 to avoid confusion with its name.
  284. [source, javascript]
  285. ----
  286. // Deprecated in TinyMCE 8, will be removed in 9
  287. // Old approach for dispatching custom events
  288. editor.fire('someEvent');
  289. // New approach for dispatching custom events
  290. editor.dispatch('someEvent');
  291. ----
  292. **Impact**: This change aligns {productname} with modern event handling conventions, making the API more intuitive for developers.
  293. **Migration checklist:**
  294. * [ ] Search codebase for all uses of the `fire()` method
  295. * [ ] Replace each instance with `dispatch()`
  296. * [ ] Review and update third-party plugins
  297. * [ ] Test all custom event handling
  298. '''
  299. === Plugin Updates
  300. ==== Language Pack Filename Changes
  301. // #TINY-12090
  302. Language pack filenames have been standardized to follow the RFC5646 format. This update ensures consistent language handling across platforms and improves internationalization support. While both the legacy underscore format (e.g., `en_GB.js`) and the new hyphenated format (e.g., `en-GB.js`) are supported in {productname} {release-version}, the underscore format is deprecated and will be removed in {productname} 9. Migrating to the RFC5646 format now will ensure future compatibility and reduce maintenance overhead during upcoming upgrades.
  303. **Impact**: Custom language packs and configurations using the underscore-based format should update before upgrading to {productname} 9 to avoid loading failures.
  304. **Migration checklist:**
  305. * [ ] Identify all language pack files in your deployment
  306. * [ ] Rename files to RFC5646 format (e.g., `en_GB.js` → `en-GB.js`)
  307. * [ ] Update configuration references to language files
  308. * [ ] Update build scripts that handle language files
  309. * [ ] Test language switching in your application
  310. * [ ] Update custom translation files to use the new format
  311. [source, javascript]
  312. ----
  313. // Deprecated format (supported only in versions 8.x)
  314. language_url: '/langs/en_GB.js'
  315. // Recommended format
  316. language_url: '/langs/en-GB.js'
  317. ----
  318. [IMPORTANT]
  319. Support for the underscore format will be removed in {productname} 9. Early migration is recommended.
  320. ==== Update to Image and Accessibility Checker Plugins
  321. // #TINY-12226
  322. The Image and Accessibility Checker plugins now follow the latest W3C standards for decorative images, requiring an empty alt attribute rather than a `+role="presentation"+` attribute. This change helps improve accessibility support.
  323. **Impact**: Customers using these plugins will need to update their configurations to ensure continued compliance with accessibility standards.
  324. **Migration checklist:**
  325. * [ ] Identify images previously using `role="presentation"` for decorative purposes in your content
  326. * [ ] Replace those with empty alt attributes `alt=""`
  327. * [ ] Update image plugin configuration if customized
  328. * [ ] Test accessibility checker with updated content
  329. For more information on the changes, see: xref:a11ychecker.adoc##image-rules[Accessibility Checker: Image rules].
  330. === Cross-Origin Resource Loading Configuration
  331. // #TINY-12228, TINY-12326
  332. When upgrading to {productname} 8, you will need to review and possibly update how your integration handles cross-origin resource loading. {productname} 8 provides a new configuration option for controlling the `crossorigin` attribute on loaded resources.
  333. **What to check:**
  334. . If you're using {cloudname}:
  335. +
  336. * Ensure your script tag includes both required attributes:
  337. +
  338. [source,html,subs="attributes+"]
  339. ----
  340. <script src="{cdnurl}" referrerpolicy="origin" crossorigin="anonymous"></script>
  341. ----
  342. +
  343. . If your application loads resources (scripts or stylesheets) from different domains:
  344. +
  345. * Configure the new crossorigin function to control the `crossorigin` attribute for all resources.
  346. +
  347. .Example: Configuring the crossorigin function
  348. [source, javascript]
  349. ----
  350. const crossOriginFunction = (url, resourceType) => {
  351. // Returning 'anonymous' or 'use-credentials' here would explicitly set the attribute
  352. return 'anonymous';
  353. // return 'use-credentials';
  354. // return undefined; // Omits the 'crossorigin' attribute for all resources by returning undefined
  355. };
  356. tinymce.init({
  357. selector: "textarea",
  358. crossorigin: crossOriginFunction
  359. });
  360. ----
  361. +
  362. . If you're using content_css from a different domain:
  363. * The `content_css_cors` option takes precedence for stylesheets.
  364. * Review your `content_css` configuration if you use cross-origin stylesheets.
  365. **Migration checklist:**
  366. * [ ] Verify script tag attributes for Cloud deployments.
  367. * [ ] Configure `crossorigin` function if using cross-origin resources.
  368. * [ ] Test resource loading in your deployment environment.
  369. * [ ] Review `content_css` configuration if using cross-origin stylesheets.
  370. For complete details on the new crossorigin function API, see: xref:tinymce-and-cors.adoc#crossorigin[crossorigin configuration option].
  371. === Technical Cleanup
  372. ==== Removed Empty Files
  373. // #TINY-11287, #TINY-12084
  374. Several empty files have been removed from the codebase to reduce clutter and improve maintenance:
  375. * Empty CSS file from the **Comments** plugin
  376. * Empty LESS file from the **Mentions** plugin
  377. **Impact**: These changes have no functional impact but may affect custom build processes that explicitly reference these files.
  378. **Migration checklist:**
  379. * [ ] Check build processes for references to Comments plugin CSS
  380. * [ ] Check build processes for references to Mentions plugin LESS
  381. * [ ] Remove any imports of these empty files
  382. * [ ] Test Comments and Mentions plugins after removal
  383. === Service and Configuration Changes
  384. ==== Discontinuation of Medical English (UK)
  385. // #EPIC-255
  386. [WARNING]
  387. The "Medical English (UK)" dictionary has been removed due to licensing constraints. Customers using this feature must update their configurations accordingly.
  388. **Impact**: Users relying on this dictionary will need to make alternative arrangements for medical-specific spell checking.
  389. **Migration checklist:**
  390. * [ ] Remove "Medical English (UK)" from spellchecker configurations
  391. * [ ] Remove any custom dictionary integrations related to Medical English
  392. * [ ] Test spellchecker functionality with remaining dictionaries
  393. * [ ] Configure alternative medical dictionary if required
  394. ==== Decoupling of Service Versions from {productname} Editor
  395. // #EPIC-247, #EPIC-265
  396. Services previously bundled with the editor, such as Java Servlet services, are no longer included in {productname} {release-version} packages. Customers should migrate to xref:bundle-intro-setup.adoc[Containerized service deployments] or consider alternative hosting options.
  397. **Impact**: This reduces the dependency between the editor and backend services, simplifying updates and maintenance.
  398. **Migration steps:**
  399. * Update the applications deployment architecture to use xref:bundle-intro-setup.adoc[Containerized services] where applicable
  400. ==== Transition from Java WAR Files to Containerized Services
  401. // #EPIC-247
  402. {productname} {release-version} 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.
  403. **Impact**: This reduces infrastructure complexity and aligns with modern DevOps practices.
  404. **Migration checklist:**
  405. * [ ] Inventory current WAR file deployments
  406. * [ ] Review containerization requirements for your environment
  407. * [ ] Plan transition timeline to containerized services
  408. * [ ] Set up container infrastructure (Docker/Kubernetes)
  409. * [ ] Deploy and test containerized services
  410. * [ ] Update service connection configurations
  411. * [ ] Contact link:{supporturl}/[{supportname}] if legacy WAR files are still needed
  412. For more information on deploying the server-side components using Docker, see: xref:bundle-intro-setup.adoc[Containerized service deployments].
  413. == Conclusion
  414. Upgrading to {productname} {release-version} requires integrators to update their API calls, plugin configurations, and service integrations to accommodate the breaking changes introduced in this release. While some adjustments may involve significant code updates, these enhancements are intended to simplify development, and improve the overall editor experience.
  415. For more guidance, refer to the:
  416. * link:https://www.tiny.cloud/docs[{productname} Documentation].
  417. * link:https://www.tiny.cloud/contact/[Contact {supportname}] for assistance.
  418. * Try {productname}’s new **Ask AI** widget is ready to assist you, just click the icon in the bottom-right corner of any documentation page.
  419. image::ask-ai/ask-ai-widget.png[Ask AI Widget, width=600, align="left"]
  420. == Additional Resources
  421. For additional details on {productname} {release-version} changes, see xref:8.0-release-notes.adoc#overview[{productname} {release-version} release notes].