Upgrade TinyMCE to v6 in Rails/Stimulus
djchadderton
Posted on February 11, 2023
A couple of years ago, I wrote a post on how to integrate the text editor TinyMCE into a Rails app using Stimulus.
While most of that post is still relevant, even after upgrading to Rails 7 and replacing Webpack with esbuild, the upgrade from v5 to v6 of TinyMCE did break a few things, so here's how to get it working again.
First of all, add the upgraded version to package.json
by changing
"tinymce": "^5.8.0"
to
"tinymce": "^6.3.0"
and run the yarn
command to update it.
In the Stimulus controller, as well as importing tinymce
, you need to import the model, so the start of the controller file will read
import { Controller } from '@hotwired/stimulus'
// Import TinyMCE
import tinymce from 'tinymce/tinymce'
import 'tinymce/models/dom/model'
Some plugins have been removed or incorporated into the main bundle, so delete any import statements for bbcode
, colorpicker
, contextmenu
, fullpage
, hr
, imagetools
, legacyoutput
, noneditable
, paste
, print
, spellchecker
, tabfocus
, textcolor
, textpattern
, toc
.
Within your toolbar entries, rename styleselect
to style
, e.g.
toolbar: ['styles | bold italic underline strikethrough superscript | blockquote numlist bullist link | alignleft aligncenter alignright | table']
Some other options have changed, so check the documentation on Migrating from TinyMCE 5 to TinyMCE 6 on the TinyMCE web site if anything isn't working as expected.
My current working Stimulus controller in full is:
import { Controller } from '@hotwired/stimulus'
// Import TinyMCE
import tinymce from 'tinymce/tinymce'
import 'tinymce/models/dom/model'
// Import icons
import 'tinymce/icons/default/icons'
// Import theme
import 'tinymce/themes/silver/theme'
// Import plugins
// import 'tinymce/plugins/advlist'
// import 'tinymce/plugins/anchor'
// import 'tinymce/plugins/autolink'
import 'tinymce/plugins/autoresize'
// import 'tinymce/plugins/autosave'
// import 'tinymce/plugins/charmap'
import 'tinymce/plugins/code'
// import 'tinymce/plugins/codesample'
// import 'tinymce/plugins/directionality'
// import 'tinymce/plugins/emoticons'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/help'
// import 'tinymce/plugins/image'
// import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
// import 'tinymce/plugins/media'
// import 'tinymce/plugins/nonbreaking'
// import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/preview'
// import 'tinymce/plugins/quickbars'
// import 'tinymce/plugins/save'
// import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/table'
// import 'tinymce/plugins/template'
// import 'tinymce/plugins/visualblocks'
// import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/wordcount'
export default class extends Controller {
static targets = ['input']
initialize () {
this.defaults = {
autoresize_bottom_margin: 10,
browser_spellcheck: true,
content_css: false,
content_style: `
html {
font-family: Roboto, sans-serif; line-height: 1.5;
}
h3, h4 {
font-family: 'Montserrat', sans-serif;
color: hsla(197, 55%, 26%, 1);
line-height: 1;
margin: .9rem 0;
}
`,
invalid_elements: 'span',
link_context_toolbar: true,
link_default_target: '_blank',
link_title: false,
max_height: 700,
menubar: false,
mobile: {
toolbar: [
'styles | bold italic underline strikethrough superscript',
'blockquote numlist bullist link | alignleft aligncenter alignright | table',
'undo redo | fullscreen preview code help'
]
},
plugins: 'link lists fullscreen help preview table code autoresize wordcount',
relative_urls: false,
skin: false,
style_formats: [
{ title: 'Heading', format: 'h3' },
{ title: 'Sub Heading', format: 'h4' },
{ title: 'Sub Heading 2', format: 'h5' },
{ title: 'Sub Heading 3', format: 'h6' },
{ title: 'Paragraph', format: 'p'}
],
toolbar: [
'styles | bold italic underline strikethrough superscript | blockquote numlist bullist link | alignleft aligncenter alignright | table',
'undo redo | fullscreen preview code help'
],
valid_styles: { '*': 'text-align' }
}
}
connect () {
// Initialize TinyMCE
if (!this.preview) {
let config = Object.assign({ target: this.inputTarget }, this.defaults)
this.tc = tinymce.init(config)
}
}
disconnect () {
if (!this.preview) tinymce.remove(this.tc.id)
}
get preview () {
return document.documentElement.hasAttribute('data-turbo-preview')
}
}
Additional note for upgrading to v7
TinyMCE version 7 has added an extra requirement to specify either the open source GPLv2+ or a commercial licence in the config options object or it will warn in the console that it is running in evaluation mode. Add the following to this.defaults
to continue using the open source version:
license_key: "gpl",
Posted on February 11, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
February 3, 2022