Install TinyMCE 8.3.2 WYSIWYG editor compatible with react-invenio-forms which uses React 16.13.0. Features include rich text editing, Markdown import, and image upload with base64 storage and automatic compression.
Team decisions:
- Base64 storage for images
- PDF import shelved for now
- Auto-compress images for descriptions (low resolution acceptable)
Ubuntu/WSL2 environment Node.js 20.x installed react-invenio-forms uses React 16.13.0
Step 1: Create React project cd ~/msdlive/react-projects npx create-react-app wysiwyg-tinymce-react16 cd wysiwyg-tinymce-react16
Step 2: Downgrade to React 16.13.0 npm install react@16.13.0 react-dom@16.13.0 --legacy-peer-deps
Verify installation:
npm list react react-dom --depth=0 Expected output shows react@16.13.0 and react-dom@16.13.0
Step 3: Install TinyMCE and dependencies npm install tinymce@8.3.2 @tinymce/tinymce-react --legacy-peer-deps npm install formik --legacy-peer-deps npm install marked@4.3.0 --legacy-peer-deps npm install dompurify --legacy-peer-deps npm install browser-image-compression --legacy-peer-deps Note: marked@4.3.0 (older version) required due to old Babel in react-scripts not supporting modern JavaScript syntax
Step 4: Copy TinyMCE files to public folder cp -r node_modules/tinymce public/ Verify copy:
ls public/tinymce/tinymce.min.js
Step 5: Fix Node.js OpenSSL compatibility Edit package.json and update the scripts section.
Change the start script from: "start": "react-scripts start"
To: "start": "NODE_OPTIONS=--openssl-legacy-provider react-scripts start"
This fixes Node.js 20.x compatibility with old webpack in react-scripts.
Step 6: Fix React 16 API in index.js Edit src/index.js and replace entire content.
The default create-react-app uses React 18 API which doesn't exist in React 16.
Change from React 18 API:
import ReactDOM from 'react-dom/client' ReactDOM.createRoot()
To React 16 API:
import ReactDOM from 'react-dom' ReactDOM.render()
Step 7: Create directory structure
mkdir -p src/components mkdir -p src/plugins
##Files to Create
src/components/TinyMCEEditor.js - Main editor with image compression src/components/FormikTinyMCE.js - Formik integration src/components/ComparisonDemo.js - Demo wrapper src/plugins/MarkdownImportPlugin.js - Markdown import src/App.js - Main app src/App.css - Styling
Version: 8.3.2 (latest, verified with React 16.13.0) License: GPL v2+ self-hosted with license_key: 'gpl' Loading: Self-hosted from public/tinymce/ folder Toolbar mode: wrap (multi-row, no overflow menu) No external CDN dependencies
Storage: Base64 encoding (security requirement) Auto-compression: Yes (browser-image-compression library) Target size: 200KB maximum after compression Max dimensions: 1200x1200 pixels Original quality maintained while reducing file size
Two input methods: Upload .md file or paste text Conversion: marked library (v4.3.0) Security: DOMPurify sanitization (XSS prevention) Format: GitHub Flavored Markdown supported
Status: Shelved (team decision) Reason: Can be added later if needed
react: 16.13.0 react-dom: 16.13.0 tinymce: 8.3.2 @tinymce/tinymce-react: 6.x formik: 2.4.x marked: 4.3.0 - Older version. latest version not compatible with react version dompurify: 3.x browser-image-compression: latest Why These Versions React 16.13.0: Required by react-invenio-forms (cannot change)
TinyMCE 8.3.2: Latest version, tested and confirmed compatible with React 16.13.0, modern UI with better features
marked@4.3.0: Older version required - newer versions use optional chaining and .at() method that old Babel cannot compile
browser-image-compression: Latest version works fine, provides automatic image size reduction
Issue 1: Can't resolve 'react-dom/client' Blank page, error about missing module
Fix: Update src/index.js to use React 16 API
Reason: Default create-react-app template uses React 18 API which doesn't exist in React 16
Issue 2: Module parse failed: Unexpected token Compilation error with marked or other libraries
Fix: Install older versions (marked@4.3.0)
Reason: Newer packages use modern JavaScript syntax that old Babel in react-scripts 5.x cannot compile
Issue 3: Peer dependency warnings npm install shows many warnings about incompatible versions
Fix: Use --legacy-peer-deps flag on all npm install commands
Reason: React 16 creates peer dependency conflicts with newer packages, flag tells npm to ignore them
Main TinyMCE editor component Image upload with automatic compression Markdown plugin integration
Key features:
Compresses images larger than 200KB automatically Converts to base64 for storage Registers Markdown import plugin Toolbar in wrap mode (multi-row, no overflow) - overflow mode doesn't close properly after image/MD upload
The component includes:
- handleImageUpload function with compression logic
- setupEditor function for plugin registration
- Markdown dialog functions (upload file and paste text)
- convertMarkdownToHTML with DOMPurify sanitization
- TinyMCE initialization with full configuration
- handleEditorChange function
Configuration highlights in init:
height: 500 menubar: false toolbar_mode: 'wrap' license_key: 'gpl' ( this is important to and without this TinyMCE would require API key) tinymceScriptSrc: '/tinymce/tinymce.min.js' plugins: standard plugins plus 'markdownimport' toolbar: full toolbar with markdown button
Simple wrapper component that integrates TinyMCE with Formik forms.
Demo page
Simple wrapper that renders the demo component
Provides styling for the demo page and editor.
The handleImageUpload function in TinyMCEEditor.js uses browser-image-compression library.
- maxSizeMB: 0.2 (200KB target)
- useWebWorker: true (non-blocking)
Registered in setupEditor function within TinyMCEEditor.js
- Upload .md file from computer
- Paste markdown text in dialog
- Converts using marked library (GitHub Flavored Markdown)
- Sanitizes with DOMPurify
-
Removes script tags
-
Strips event handlers (onclick, onerror, etc.)
-
Blocks javascript: URLs
-
Only allows safe HTML tags and attributes
-
Allowed tags: h1, h2, h3, h4, h5, h6, p, br, strong, em, u, strike, ul, ol, li, a, code, pre, blockquote, table, thead, tbody, tr, th, td, hr, img, div, span
-
Allowed attributes: href, src, alt, title, class, id
-
Everything else stripped out for security.