TinyMCE React integration technical reference
Covered in this section:
Installing the TinyMCE React integration using NPM or Yarn
To install the tinymce-react
package and save it to your package.json
.
npm install --save @tinymce/tinymce-react
or with Yarn
yarn add @tinymce/tinymce-react
Using TinyMCE React integration in a Bootstrap dialog
To use the TinyMCE React integration inside Bootstrap UI dialogs, add the following React effect hook to a component that renders with the editor. This code is required because Bootstrap blocks all focusin
calls from elements outside the dialog.
Bootstrap 5
For Bootstrap 5, the React effect hook contains no JQuery. |
useEffect(() => {
const handler = (e) => {
if (e.target.closest(".tox-tinymce-aux, .moxman-window, .tam-assetmanager-root") !== null) {
e.stopImmediatePropagation();
}
};
document.addEventListener("focusin", handler);
return () => document.removeEventListener("focusin", handler);
}, []);
Bootstrap 4
useEffect(function() {
var handler = function(e) {
if ($(e.target).closest(".tox-tinymce, .tox-tinymce-aux, .moxman-window, .tam-assetmanager-root").length) {
e.stopImmediatePropagation();
}
};
$(document).on('focusin', handler);
return function() {
$(document).off('focusin', handler);
};
}, []);
Configuring the editor
The tinymce-react
component provides props for:
Configuring editor source
The tinymce-react
integration will try to source TinyMCE in the following order:
-
The global
tinymce
will be used, if it is present on the page. -
If the
tinymceScriptSrc
prop is provided, then a script tag will be added to the page to load TinyMCE from the given URL. -
If none of the above conditions apply, then a script tag will be added to the page to load TinyMCE from Tiny Cloud.
These props are used to configure how the editor is sourced:
apiKey
-
The Tiny Cloud API key. When loading from Tiny Cloud, use this prop to remove the "This domain is not registered…" warning message.
cloudChannel
-
The channel of TinyMCE used when loading from Tiny Cloud.
scriptLoading
-
The script loading behavior prop. Allows setting of the
async
anddefer
attributes, as well as adding an additional delay in milliseconds. tinymceScriptSrc
-
The URL to use for sourcing TinyMCE, when loading a self-hosted version of TinyMCE.
Configuring page elements
These props provide some control over the page elements that the integration creates:
id
-
The id attribute of the element that the editor is initialized on.
inline
-
Load the editor as part of the page; sharing the page styles and selection.
tagName
-
The tag used for creating an inline editor. Ignored for a classic (iframe) editor.
textareaName
-
The name attribute on the textarea tag (HTML element). Used for creating the classic (iframe) editor. Ignored for an inline editor.
Configuring editor options
These props are read when the editor is initialized. Changes after the editor has launched are ignored.
Managing the editor
These props can be updated after the editor is initialized. Note that there are other events not mentioned here.
disabled
-
Should the editor be in read-only mode.
initialValue
-
The starting value of the editor. Changing this value after the editor has loaded will reset the editor (including the editor content).
onBeforeAddUndo
-
An event handler for notifying when the editor is about to create an undo level, and preventing it if required. This is important for controlled components that restrict the allowed values of the editor.
onEditorChange
-
An event handler for detecting editor changes. Useful when implementing TinyMCE as a controlled component.
onInit
-
An event handler for notifying when the editor has initialized. Useful for getting the initial value of the editor or obtaining a reference to the editor that can be used for a uncontrolled component.
value
-
Sets and enforces the value of the editor. Only used for a controlled component.
Available props
None of the configuration props are required for the TinyMCE React component; however, if the apiKey
prop is not configured when loading from Tiny Cloud, a warning message will be shown in the editor. For guidance about which props to use, see: Configuring the editor.
apiKey
Tiny Cloud API key.
Required for deployments using the Tiny Cloud to provide the TinyMCE editor without the warning message "This domain is not registered…".
To register for a Tiny Cloud API key, visit the Tiny Account sign-up page. To retrieve the Tiny Cloud API key for an existing Tiny Account, login and visit the Tiny Account Dashboard.
Type: String
Default value: 'no-api-key'
cloudChannel
Changes the TinyMCE build used for the editor to either a specific version or a channel indicating a stability level.
Type: String
Default value: '6'
Possible values: '6'
, '6-testing'
, '6-dev'
, '6.8'
Changes the TinyMCE build used for the editor to one of the following Tiny Cloud channels:
-
6
(Default): The current enterprise release of TinyMCE. -
6-testing
: The current release candidate for the next enterprise release of TinyMCE. -
6-dev
: The nightly-build version of TinyMCE. -
A version number such as
6.8
: The specific enterprise release version of TinyMCE.
Such as:
<Editor
apiKey='your-api-key'
cloudChannel='6-dev'
init={{ /* your other settings */ }}
/>
For information TinyMCE development channels, see: Specifying the TinyMCE editor version deployed from Cloud - dev, testing, and stable releases.
disabled
The disabled
prop can dynamically switch the editor between a "disabled" (read-only) mode (true
) and the standard editable mode (false
).
Type: Boolean
Default value: false
Possible values: true
, false
id
An id for the editor. Used for retrieving the editor instance using the tinymce.get('ID')
method.
Type: String
Default value: Automatically generated UUID
init
Additional settings passed to the tinymce.init({...})
method used to initialize the editor.
For information on the TinyMCE tinymce.init({...})
method, see: Basic setup.
When using tinymce-react
:
-
The
init
prop does not require theselector
ortarget
options -
If the
selector
,target
, orreadonly
options are set using theinit
prop, they will be overridden by the integration.
Type: Object
Default value: { }
initialValue
The initial HTML content of the editor. This will reset the editor undo state and the cursor position when changed.
This may be set either before the editor loads, or soon afterwards by an asynchronous process.
Ensure that this is not updated by onEditorChange or the editor will be unusable.
|
Type: String
Default value: ''
Example: using asynchronous initialValue
const [initialValue, setInitialValue] = useState(undefined);
useEffect(() => {
// a real application might do a fetch request here to get the content
setTimeout(() => setInitialValue('<p>Once upon a time...</p>'), 500);
}, []);
return (
<Editor
initialValue={initialValue}
/>
);
inline
Used to set the editor to inline mode. Using <Editor inline={true} />
is the same as setting {inline: true}
in the TinyMCE tinymce.init({...})
method.
For information on inline mode, see: User interface options - inline
and Setup inline editing mode.
Type: Boolean
Default value: false
Possible values: true
, false
onEditorChange
Used to store the state of the editor outside the TinyMCE React component. This prop is commonly used when using the TinyMCE React component as a controlled component.
It is called with two arguments:
value
-
The current value of the editor. This is HTML.
editor
-
A reference to the editor.
For detailed information on using onEditorChange
, see: Using the TinyMCE React component as a controlled component.
Type: EventHandler
outputFormat
(removed)
This option was removed with the release of the TinyMCE React component 4.0.0. |
This option was used to specify the format of the content produced by the
onEditorChange
event, however as it did not change the
input format it was almost impossible to use correctly.
Example: replacing usage of outputFormat
const [value, setValue] = useState('<p>The quick brown fox jumps over the lazy dog</p>');
const [text, setText] = useState('');
return (
<>
<Editor
value={value}
onInit={(evt, editor) => {
setText(editor.getContent({format: 'text'}));
}}
onEditorChange={(newValue, editor) => {
setValue(newValue);
setText(editor.getContent({format: 'text'}));
}}
/>
<pre>{text}</pre>
</>
);
plugins
Used to include plugins for the editor. Using <Editor plugins='lists' />
is the same as setting {plugins: 'lists'}
in the TinyMCE tinymce.init({...})
method.
For information on adding plugins to TinyMCE, see: Add plugins to TinyMCE.
Type: String
or Array
rollback
Used to configure the rollback timer. This is the milliseconds between an event
being emitted by the onEditorChange
prop and the
value
prop being enforced.
When rollback
is false
the value
prop will not be
enforced unless it changes.
Type: Number
or false
Default value: 200
scriptLoading
Used to configure the script tag created to load TinyMCE.
Type: Object
type ScriptLoading = {
async?: boolean;
defer?: boolean;
delay?: number;
};
Contains 3 settings:
async
-
Sets the
async
attribute on the script tag created to load TinyMCE.For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available.
— https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-asyncType:
Boolean
Default value:
false
defer
-
Sets the
defer
attribute on the script tag created to load TinyMCE.This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.
— https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-deferType:
Boolean
Default value:
false
delay
-
The script tag to load TinyMCE will be added after the specified delay in milliseconds.
Type:
Number
Default value:
0
tagName
Only valid when <Editor inline={true} />
. Used to define the HTML element for the editor in inline mode.
Type: String
Default value: 'div'
textareaName
Only valid when the editor is in classic (iframe) mode. Sets the name
attribute for the textarea
element used for the editor in forms.
Type: String
toolbar
Used to set the toolbar for the editor. Using <Editor toolbar='bold' />
is the same as setting {toolbar: 'bold'}
in the TinyMCE method tinymce.init({...})
.
For information setting the toolbar for TinyMCE, see: User interface options - toolbar.
Type: String
Possible values: See Toolbar Buttons Available for TinyMCE.
tinymceScriptSrc
Use the tinymceScriptSrc
prop to specify an external version of TinyMCE to lazy load.
Type: String
value
Sets the HTML content of the editor when operating as a controlled component.
When this prop is different to the current editor content, the editor content will be changed to match (within 200 milliseconds) and an undo level will be created. When the editor content changes by this mechanism, the editor will attempt to retain the selection, however if the previous selection does not exist in the new content, the cursor returns to the start of the document.
This prop allows the editor to be used as a controlled component by setting the value
prop and using the onEditorChange
event to update the value
.
For detailed information on using the value
prop, see: Using the TinyMCE React component as a controlled component.
Type: String
Using the TinyMCE React component as a uncontrolled component
The TinyMCE React component is designed to be used as an uncontrolled component, which allows the editor to perform well on larger documents.
When using the editor as an uncontrolled component, avoid using the value
and onEditorChange
props. Tiny recommends retrieving the editor content when it is needed. The onInit
event handler can be used to store a editor reference when the editor is loaded to assist with retrieving the content.
To provide visual feedback to the user when the content is ready to be saved, use the onDirty
event handler; combined with clearing the editor’s "dirty" state when saving the editor content.
The editor is "dirty" (or in a "dirty" state) when the user modifies editor content after initialization or the last tinymce.editor.save() call. This includes changes made using undo or redo.
|
Example: functional uncontrolled component with save button and dirty state
function MyComponent({initialValue}) {
const editorRef = useRef(null);
const [dirty, setDirty] = useState(false);
useEffect(() => setDirty(false), [initialValue]);
const save = () => {
if (editorRef.current) {
const content = editorRef.current.getContent();
setDirty(false);
editorRef.current.setDirty(false);
// an application would save the editor content to the server here
console.log(content);
}
};
return (
<>
<Editor
initialValue={initialValue}
onInit={(evt, editor) => editorRef.current = editor}
onDirty={() => setDirty(true)}
/>
<button onClick={save} disabled={!dirty}>Save</button>
{dirty && <p>You have unsaved content!</p>}
</>
);
}
Using the TinyMCE React component as a controlled component
The controlled component can have performance problems on large documents as it requires converting the entire document to a string on each keystroke or modification. |
To use the editor as a controlled component, both the value
and onEditorChange
props are required.
The value
prop is used to set and re-set the editor content. If it is not updated to the latest version of the editor content, the editor will rollback any changes.
The onEditorChange
prop is used to provide an event handler that will be run when any change is made to the editor content. Changes to the editor must be applied to the value
prop within 200 milliseconds to prevent the changes being rolled back.
Example: functional controlled component
function MyComponent({initialValue}) {
const [value, setValue] = useState(initialValue ?? '');
useEffect(() => setValue(initialValue ?? ''), [initialValue]);
return (
<Editor
initialValue={initialValue}
value={value}
onEditorChange={(newValue, editor) => setValue(newValue)}
/>
);
}
Example: class controlled component
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: props.initialValue ?? '' };
this.handleEditorChange = this.handleEditorChange.bind(this);
}
componentDidUpdate(prevProps) {
if (this.props.initialValue !== prevProps.initialValue) {
this.setState({ value: this.props.initialValue ?? '' })
}
}
handleEditorChange(value, editor) {
this.setState({ value });
}
render() {
return (
<Editor
initialValue={this.props.initialValue}
value={this.state.value}
onEditorChange={this.handleEditorChange}
/>
)
}
}
When the editor must be restricted to avoid invalid states, such as exceeding a maximum length, then a handler for onBeforeAddUndo
must be added to avoid those states in the undo history.
Example: limited length controlled component
function MyComponent({initialValue, limit}) {
const sizeLimit = limit ?? 50;
const [ value, setValue ] = React.useState(initialValue ?? '');
const [ length, setLength ] = React.useState(0);
const handleInit = (evt, editor) => {
setLength(editor.getContent({ format: 'text' }).length);
};
const handleUpdate = (value, editor) => {
const length = editor.getContent({ format: 'text' }).length;
if (length <= sizeLimit) {
setValue(value);
setLength(length);
}
};
const handleBeforeAddUndo = (evt, editor) => {
const length = editor.getContent({ format: 'text' }).length;
// note that this is the opposite test as in handleUpdate
// because we are determining when to deny adding an undo level
if (length > sizeLimit) {
evt.preventDefault();
}
};
return (
<>
<Editor
initialValue={initialValue}
value={value}
onInit={handleInit}
onEditorChange={handleUpdate}
onBeforeAddUndo={handleBeforeAddUndo}
/>
<p>Remaining: {sizeLimit - length}</p>
</>
);
};
For information on controlled components in React, see: React Docs - Controlled Components.
Event binding
Functions can be bound to editor events, such as:
<Editor onSelectionChange={this.handlerFunction} />
When the handler is called (handlerFunction in this example), it is called with two arguments:
event
-
The TinyMCE event object.
editor
-
A reference to the editor.
The following events are available:
-
onActivate
-
onAddUndo
-
onBeforeAddUndo
-
onBeforeExecCommand
-
onBeforeGetContent
-
onBeforeRenderUI
-
onBeforeSetContent
-
onBeforePaste
-
onBlur
-
onChange
-
onClearUndos
-
onClick
-
onContextMenu
-
onCopy
-
onCut
-
onDblclick
-
onDeactivate
-
onDirty
-
onDrag
-
onDragDrop
-
onDragEnd
-
onDragGesture
-
onDragOver
-
onDrop
-
onExecCommand
-
onFocus
-
onFocusIn
-
onFocusOut
-
onGetContent
-
onHide
-
onInit
-
onKeyDown
-
onKeyPress
-
onKeyUp
-
onLoadContent
-
onMouseDown
-
onMouseEnter
-
onMouseLeave
-
onMouseMove
-
onMouseOut
-
onMouseOver
-
onMouseUp
-
onNodeChange
-
onObjectResizeStart
-
onObjectResized
-
onObjectSelected
-
onPaste
-
onPostProcess
-
onPostRender
-
onPreProcess
-
onProgressState
-
onRedo
-
onRemove
-
onReset
-
onSaveContent
-
onSelectionChange
-
onSetAttrib
-
onSetContent
-
onShow
-
onSubmit
-
onUndo
-
onVisualAid