### Install @tinymce/tinymce-react and tinymce Source: https://context7.com/tinymce/tinymce-react/llms.txt Install the package and its peer dependencies using npm or yarn. ```bash npm install @tinymce/tinymce-react tinymce # or yarn add @tinymce/tinymce-react tinymce ``` -------------------------------- ### Self-hosted TinyMCE with bundler (Vite / Webpack) Source: https://context7.com/tinymce/tinymce-react/llms.txt Demonstrates how to import TinyMCE modules and assets directly and configure the Editor component for a self-hosted setup, skipping CDN injection by passing `tinymceScriptSrc={[]}` and providing a `licenseKey`. ```APIDOC ## Self-hosted TinyMCE with bundler (Vite / Webpack) When bundling TinyMCE directly rather than using Tiny Cloud, import TinyMCE modules manually, pass `tinymceScriptSrc={[]}` to skip CDN injection, and supply `licenseKey`. ```tsx // Import TinyMCE core and required assets import 'tinymce/tinymce'; import 'tinymce/themes/silver/theme'; import 'tinymce/icons/default/icons'; import 'tinymce/models/dom/model'; import 'tinymce/plugins/lists'; import 'tinymce/plugins/link'; import 'tinymce/plugins/image'; import 'tinymce/skins/ui/oxide/skin.min.css'; import { Editor } from '@tinymce/tinymce-react'; export default function BundledEditor() { return ( ); } ``` ``` -------------------------------- ### Initialize TinyMCE with Configuration Source: https://context7.com/tinymce/tinymce-react/llms.txt Pass a TinyMCE configuration object directly to the `init` prop. Standard TinyMCE options are valid, but `selector`, `target`, `readonly`, `disabled`, and `license_key` are managed by the component. Use the `licenseKey` prop instead of `license_key`. ```tsx { editor.on('init', () => console.log('Editor ready, id:', editor.id)); }, // init_instance_callback — runs after the editor is fully initialized init_instance_callback: (editor) => { console.log('Instance callback, content:', editor.getContent()); }, }} /> ``` -------------------------------- ### Handle Editor Initialization Event Source: https://context7.com/tinymce/tinymce-react/llms.txt The `onInit` event prop fires when the editor instance is ready. It provides the raw TinyMCE `Editor` object, useful for imperative API access via a ref. ```tsx import React, { useRef } from 'react'; import { Editor } from '@tinymce/tinymce-react'; import type { Editor as TinyMCEEditor } from 'tinymce'; export default function EditorWithRef() { const editorRef = useRef(null); const handleInit = (_evt: unknown, editor: TinyMCEEditor) => { editorRef.current = editor; }; const logContent = () => { if (editorRef.current) { console.log('HTML:', editorRef.current.getContent()); console.log('Text:', editorRef.current.getContent({ format: 'text' })); } }; return ( <> ); } ``` -------------------------------- ### Self-host TinyMCE with Vite/Webpack Source: https://context7.com/tinymce/tinymce-react/llms.txt Import TinyMCE core and assets directly when bundling. Use `tinymceScriptSrc={[]}` to prevent CDN injection and provide your `licenseKey`. ```tsx import 'tinymce/tinymce'; import 'tinymce/themes/silver/theme'; import 'tinymce/icons/default/icons'; import 'tinymce/models/dom/model'; import 'tinymce/plugins/lists'; import 'tinymce/plugins/link'; import 'tinymce/plugins/image'; import 'tinymce/skins/ui/oxide/skin.min.css'; import { Editor } from '@tinymce/tinymce-react'; export default function BundledEditor() { return ( ); } ``` -------------------------------- ### Editor with initialValue and Configuration Source: https://context7.com/tinymce/tinymce-react/llms.txt Sets the initial HTML content and configures editor settings like height, menubar, plugins, and toolbar. Use initialValue for loading fresh documents. ```tsx import { Editor } from '@tinymce/tinymce-react'; export default function ArticleEditor() { return ( ); } ``` -------------------------------- ### Set TinyMCE License Key Source: https://context7.com/tinymce/tinymce-react/llms.txt Use the `licenseKey` prop to provide your self-hosted license key. Set to "gpl" for GPL-licensed projects. ```tsx ``` -------------------------------- ### Minimal Editor Usage with initialValue Source: https://context7.com/tinymce/tinymce-react/llms.txt Basic integration of the Editor component, loading TinyMCE from Tiny Cloud. Requires an API key. ```tsx import { Editor } from '@tinymce/tinymce-react'; // Minimal usage – loads TinyMCE 8 from Tiny Cloud export default function App() { return ( ); } ``` -------------------------------- ### Shorthand Plugins and Toolbar Props Source: https://context7.com/tinymce/tinymce-react/llms.txt Use shorthand `plugins` and `toolbar` props to set TinyMCE options without nesting them in `init`. When both `plugins` prop and `init.plugins` are provided, they are merged. ```tsx ``` -------------------------------- ### Editor with API Key Configuration Source: https://context7.com/tinymce/tinymce-react/llms.txt Configure the TinyMCE editor to load from Tiny Cloud using the apiKey prop. A valid key is required to avoid a warning banner. ```tsx ``` -------------------------------- ### Load TinyMCE from Custom URL Source: https://context7.com/tinymce/tinymce-react/llms.txt Use the `tinymceScriptSrc` prop to load TinyMCE from a custom URL instead of Tiny Cloud. It accepts a URL string, an array of strings, or an array of `{ src, async?, defer? }` objects. An empty array skips script loading, useful when TinyMCE is bundled and already present in `window.tinymce`. ```tsx // Self-hosted TinyMCE from a local path ``` ```tsx // TinyMCE already bundled — no script injection needed import 'tinymce/tinymce'; import 'tinymce/themes/silver'; import 'tinymce/icons/default'; ``` -------------------------------- ### Create Typed Editor Wrapper with IAllProps Source: https://context7.com/tinymce/tinymce-react/llms.txt Leverage the `IAllProps` TypeScript interface to build custom wrappers for the TinyMCE React component, enforcing specific props like `apiKey` and adding custom functionality such as a save button. ```tsx import { Editor, IAllProps } from '@tinymce/tinymce-react'; import React from 'react'; // Build a typed wrapper that enforces an apiKey and adds a save button interface MyEditorProps extends Partial { onSave: (html: string) => void; } export function MyEditor({ onSave, ...props }: MyEditorProps) { const [content, setContent] = React.useState(props.initialValue ?? ''); return (
setContent(val)} />
); } ``` -------------------------------- ### Inline Editor Rendering Source: https://context7.com/tinymce/tinymce-react/llms.txt Render the editor inline by setting the `inline` prop to `true`. This converts the host element into the editable region. Requires the `tagName` prop to define the wrapping element. XSS sanitization of `initialValue` is handled internally by TinyMCE after mount. ```tsx
``` -------------------------------- ### Internal ScriptLoader API for Manual Loading Source: https://context7.com/tinymce/tinymce-react/llms.txt The ScriptLoader singleton manages script tag injection. Use `loadList` to manually load TinyMCE into a specific document, or `reinitialize` to reset cached loaders for testing. ```ts import { ScriptLoader } from '@tinymce/tinymce-react/lib/cjs/main/ts/ScriptLoader2'; // Load TinyMCE manually into a specific document ScriptLoader.loadList( document, [{ src: 'https://cdn.tiny.cloud/1/MY_KEY/tinymce/8/tinymce.min.js', async: true }], 0, // delay in ms () => console.log('TinyMCE loaded'), (err) => console.error('Load failed', err) ); // Reset all cached loaders (useful between tests) ScriptLoader.reinitialize(); ``` -------------------------------- ### Utility Props for DOM Integration Source: https://context7.com/tinymce/tinymce-react/llms.txt Props like `id`, `tabIndex`, `textareaName`, and `tagName` assist with DOM integration and form submission. ```tsx for form submission (iframe mode) initialValue="

Form editor

" /> ``` ```html
``` -------------------------------- ### Configure TinyMCE Cloud Channel Source: https://context7.com/tinymce/tinymce-react/llms.txt The `cloudChannel` prop selects the TinyMCE version channel from Tiny Cloud. Defaults to '8'. Supports specific versions or development builds. ```tsx // Pin to a specific minor release channel ``` ```tsx // Use the development build of TinyMCE 6 ``` -------------------------------- ### onScriptsLoad and onScriptsLoadError Source: https://context7.com/tinymce/tinymce-react/llms.txt Handle the loading status of the TinyMCE script. `onScriptsLoad` is called on success, and `onScriptsLoadError` is called if the script fails to load. This is useful for displaying loading indicators or implementing graceful degradation. ```APIDOC ## `onScriptsLoad` and `onScriptsLoadError` event props Called after the TinyMCE script tag has been successfully loaded (or failed to load). Useful for showing loading indicators or handling graceful degradation. ```tsx import React, { useState } from 'react'; import { Editor } from '@tinymce/tinymce-react'; export default function EditorWithLoadState() { const [status, setStatus] = useState<'loading' | 'ready' | 'error'>('loading'); return (
{status === 'loading' &&

Loading editor…

} {status === 'error' &&

Failed to load TinyMCE.

} setStatus('ready')} onScriptsLoadError={(err) => { console.error('Script load error:', err); setStatus('error'); }} />
); } ``` ``` -------------------------------- ### `ScriptLoader` — Internal Script Loading API Source: https://context7.com/tinymce/tinymce-react/llms.txt The `ScriptLoader` singleton manages script tag injection for TinyMCE. It can be used internally by the `` component or accessed directly for testing or manual script management, allowing for deduplicated, per-document script loading. ```APIDOC ## `ScriptLoader` — Internal Script Loading API The exported `ScriptLoader` singleton manages deduplicated, per-document script tag injection. It is used internally by `` but can be accessed for testing or manual script management. ```ts import { ScriptLoader } from '@tinymce/tinymce-react/lib/cjs/main/ts/ScriptLoader2'; // Load TinyMCE manually into a specific document ScriptLoader.loadList( document, [{ src: 'https://cdn.tiny.cloud/1/MY_KEY/tinymce/8/tinymce.min.js', async: true }], 0, // delay in ms () => console.log('TinyMCE loaded'), (err) => console.error('Load failed', err) ); // Reset all cached loaders (useful between tests) ScriptLoader.reinitialize(); ``` ``` -------------------------------- ### Handle TinyMCE Script Load Status Source: https://context7.com/tinymce/tinymce-react/llms.txt Use `onScriptsLoad` and `onScriptsLoadError` to manage loading indicators or graceful degradation when TinyMCE scripts are loaded or fail to load. ```tsx import React, { useState } from 'react'; import { Editor } from '@tinymce/tinymce-react'; export default function EditorWithLoadState() { const [status, setStatus] = useState<'loading' | 'ready' | 'error'>('loading'); return (
{status === 'loading' &&

Loading editor…

} {status === 'error' &&

Failed to load TinyMCE.

} setStatus('ready')} onScriptsLoadError={(err) => { console.error('Script load error:', err); setStatus('error'); }} />
); } ``` -------------------------------- ### Native DOM Event Props Source: https://context7.com/tinymce/tinymce-react/llms.txt The TinyMCE React component supports all standard browser DOM events such as `onClick`, `onKeyDown`, `onFocus`, `onBlur`, `onPaste`, etc. Each event handler receives the `editorEvent` and the `editor` instance. ```APIDOC ## Native DOM event props The component exposes every standard browser event (`onClick`, `onKeyDown`, `onKeyUp`, `onFocus`, `onBlur`, `onPaste`, `onCopy`, `onCut`, `onDrop`, `onMouseDown`, `onMouseUp`, `onInput`, `onCompositionStart`, `onCompositionEnd`, `onCompositionUpdate`, etc.) as props. Each handler receives `(editorEvent, editor)`. ```tsx { // Block the Delete key if (evt.key === 'Delete') { evt.preventDefault(); console.log('Delete blocked'); } }} onPaste={(evt, editor) => { console.log('User pasted. Current content:', editor.getContent()); }} onFocus={(_evt, editor) => { console.log('Editor focused:', editor.id); }} onBlur={(_evt, editor) => { console.log('Editor blurred. Final content:', editor.getContent()); }} /> ``` ``` -------------------------------- ### Control TinyMCE Script Loading Source: https://context7.com/tinymce/tinymce-react/llms.txt The `scriptLoading` prop controls how the TinyMCE script tag is injected. Options include `async`, `defer`, and a `delay` for lazy loading. ```tsx ``` -------------------------------- ### TinyMCE-Specific Event Props Source: https://context7.com/tinymce/tinymce-react/llms.txt Handle TinyMCE's own high-level events that do not have direct DOM equivalents. This includes events related to undo/redo, content serialization, object resizing, and load errors for skins, plugins, and themes. ```APIDOC ## TinyMCE-specific event props TinyMCE emits its own high-level events that have no direct DOM equivalent. These include undo/redo lifecycle events, content serialization hooks, object resize events, and load error events. ```tsx import type { EditorEvent, Events, Editor as TinyMCEEditor } from 'tinymce'; console.log('Undone:', editor.getContent())} onRedo={(evt, editor) => console.log('Redone:', editor.getContent())} onBeforeAddUndo={(evt: EditorEvent, editor) => { // Cancel adding an undo level conditionally if (editor.getContent({ format: 'text' }).length > 1000) { evt.preventDefault(); } }} // Content serialization onGetContent={(evt, editor) => console.log('Getting content')} onSetContent={(evt, editor) => console.log('Content was set:', evt.content)} // Node selection tracking onNodeChange={(evt, editor) => console.log('Selected node:', evt.element?.tagName)} // Load errors onSkinLoadError={(evt) => console.error('Skin failed to load', evt)} onPluginLoadError={(evt) => console.error('Plugin failed to load', evt)} onThemeLoadError={(evt) => console.error('Theme failed to load', evt)} // Comments (Premium) onCommentChange={(_evt, editor) => console.log('Comment changed')} /> ``` ``` -------------------------------- ### Handle Native DOM Events in TinyMCE Editor Source: https://context7.com/tinymce/tinymce-react/llms.txt Exposes standard browser events like `onClick`, `onKeyDown`, `onPaste`, `onFocus`, and `onBlur`. Handlers receive `(editorEvent, editor)` and can be used to intercept or react to user interactions. ```tsx { // Block the Delete key if (evt.key === 'Delete') { evt.preventDefault(); console.log('Delete blocked'); } }} onPaste={(evt, editor) => { console.log('User pasted. Current content:', editor.getContent()); }} onFocus={(_evt, editor) => { console.log('Editor focused:', editor.id); }} onBlur={(_evt, editor) => { console.log('Editor blurred. Final content:', editor.getContent()); }} /> ``` -------------------------------- ### Handle Editor Content Change Event Source: https://context7.com/tinymce/tinymce-react/llms.txt The `onEditorChange` event prop fires when content changes. It provides the updated HTML string and the editor instance. Useful for tracking character counts or implementing limits. ```tsx import React, { useState } from 'react'; import { Editor } from '@tinymce/tinymce-react'; import type { Editor as TinyMCEEditor } from 'tinymce'; export default function CharacterLimitEditor() { const LIMIT = 50; const [content, setContent] = useState('

Start typing…

'); const [charCount, setCharCount] = useState(0); const handleChange = (value: string, editor: TinyMCEEditor) => { const textLength = editor.getContent({ format: 'text' }).length; if (textLength <= LIMIT) { setContent(value); setCharCount(textLength); } // If over limit, do not update state → rollback kicks in }; return ( <> { if (editor.getContent({ format: 'text' }).length > LIMIT) { evt.preventDefault(); // Block undo history entry when over limit } }} />

Characters remaining: {LIMIT - charCount}

); } ``` -------------------------------- ### Set Editor to Readonly Mode Source: https://context7.com/tinymce/tinymce-react/llms.txt Use the `readonly` prop to put the editor into TinyMCE's `readonly` mode, allowing content display without editing. This is independent of the `disabled` prop. A readonly editor renders UI chrome, while a disabled editor greys out and prevents interaction. ```tsx import React, { useState } from 'react'; import { Editor } from '@tinymce/tinymce-react'; export default function ReadonlyToggle() { const [isReadonly, setIsReadonly] = useState(true); return ( <> ); } ``` -------------------------------- ### Handle TinyMCE-Specific Events Source: https://context7.com/tinymce/tinymce-react/llms.txt Utilize TinyMCE's custom events for undo/redo, content serialization, object resizing, and load errors. These provide finer control over the editor's lifecycle and content. ```tsx import type { EditorEvent, Events, Editor as TinyMCEEditor } from 'tinymce'; console.log('Undone:', editor.getContent())} onRedo={(evt, editor) => console.log('Redone:', editor.getContent())} onBeforeAddUndo={(evt: EditorEvent, editor) => { // Cancel adding an undo level conditionally if (editor.getContent({ format: 'text' }).length > 1000) { evt.preventDefault(); } }} // Content serialization onGetContent={(evt, editor) => console.log('Getting content')} onSetContent={(evt, editor) => console.log('Content was set:', evt.content)} // Node selection tracking onNodeChange={(evt, editor) => console.log('Selected node:', evt.element?.tagName)} // Load errors onSkinLoadError={(evt) => console.error('Skin failed to load', evt)} onPluginLoadError={(evt) => console.error('Plugin failed to load', evt)} onThemeLoadError={(evt) => console.error('Theme failed to load', evt)} // Comments (Premium) onCommentChange={(_evt, editor) => console.log('Comment changed')} /> ``` -------------------------------- ### Controlled Editor Component with value and onEditorChange Source: https://context7.com/tinymce/tinymce-react/llms.txt Drives the editor as a controlled React input using the value and onEditorChange props. The component synchronizes content with React state and provides editor instance access. ```tsx import React, { useState } from 'react'; import { Editor } from '@tinymce/tinymce-react'; export default function ControlledEditor() { const [content, setContent] = useState('

Edit me

'); return (
{ // newValue: current HTML string // editor: raw TinyMCE Editor instance for advanced access console.log('char count:', editor.getContent({ format: 'text' }).length); setContent(newValue); }} init={{ height: 400 }} /> {/* Mirror the editor in a plain textarea */}