TinyMCE in React
Here's how to setup TinyMCE in react using the "self-hosted" option, without TinyMCE cloud.
Full Code TLDR
import 'tinymce/tinymce'; import 'tinymce/icons/default'; import 'tinymce/themes/silver'; import 'tinymce/plugins/paste'; import 'tinymce/plugins/link'; import 'tinymce/plugins/image'; import 'tinymce/plugins/table'; import 'tinymce/skins/ui/oxide/skin.min.css'; import 'tinymce/skins/ui/oxide/content.min.css'; // import 'tinymce/skins/content/default/content.min.css'; import { Editor } from '@tinymce/tinymce-react' const EditorComponent = () => { const [value, setValue] = React.useState("Type something here...") console.log(5 + 2) return ( <Editor initialValue={value} disabled={false} onEditorChange={(value) => handleValueChange(value)} init={{ skin: false, content_css: 'tinymcecontent.css', inline:false, statusbar: false, menubar: false, plugins: [ 'link image', 'table paste', ], toolbar: "undo redo paste | formatselect | bold italic backcolor | \ alignleft aligncenter alignright alignjustify | \ bullist numlist outdent indent | removeformat | table" }} /> ) }
Additional Steps
Install TinyMCE-react
npm install --save @tinymce/tinymce-react
Install TinyMCE
npm install --save tinymce
Custom Styles (Optional)
/public/tinymcecontent.css/** * Copyright (c) Tiny Technologies, Inc. All rights reserved. * Licensed under the LGPL or a commercial license. * For LGPL see License.txt in the project root for license information. * For commercial licenses see https://www.tiny.cloud/ */ body, .mce-content-body { font-family: "Arial"; font-size: 0.9rem; line-height: 1.4; margin: 1rem; } table { border-collapse: collapse; } /* Apply a default padding if legacy cellpadding attribute is missing */ table:not([cellpadding]) th, table:not([cellpadding]) td { padding: 0.4rem; } /* Set default table styles if a table has a positive border attribute and no inline css */ table[border]:not([border="0"]):not([style*="border-width"]) th, table[border]:not([border="0"]):not([style*="border-width"]) td { border-width: 1px; } /* Set default table styles if a table has a positive border attribute and no inline css */ table[border]:not([border="0"]):not([style*="border-style"]) th, table[border]:not([border="0"]):not([style*="border-style"]) td { border-style: solid; } /* Set default table styles if a table has a positive border attribute and no inline css */ table[border]:not([border="0"]):not([style*="border-color"]) th, table[border]:not([border="0"]):not([style*="border-color"]) td { border-color: #ccc; } figure { display: table; margin: 1rem auto; } figure figcaption { color: #999; display: block; margin-top: 0.25rem; text-align: center; } hr { border-color: #ccc; border-style: solid; border-width: 1px 0 0 0; } code { background-color: #e8e8e8; border-radius: 3px; padding: 0.1rem 0.2rem; } .mce-content-body:not([dir=rtl]) blockquote { border-left: 2px solid #ccc; margin-left: 1.5rem; padding-left: 1rem; } .mce-content-body[dir=rtl] blockquote { border-right: 2px solid #ccc; margin-right: 1.5rem; padding-right: 1rem; }