- CodeMirror Integration
- Embedly Integration
Contact Support
Third party integration in React Rich text editor component
27 Feb 202524 minutes to read
The Rich Text Editor can be integrated with third-party to suite the application scenario.
CodeMirror Integration
Rich Text Editor comes with a basic HTML source editor through the view-source property. CodeMirror plugin can be used to highlight the syntax of HTML. CodeMirror plugin for Rich Text Editor makes editing of HTML source code with a pleasant experience.
Import necessary CSS and JS files of CodeMirror to the HTML page.
Required JS files of code mirror.
<script src="scripts/CodeMirror/codemirror.js" type="text/javascript"></script>
<script src="scripts/CodeMirror/javascript.js" type="text/javascript"></script>
<script src="scripts/CodeMirror/css.js" type="text/javascript"></script>
<script src="scripts/CodeMirror/htmlmixed.js" type="text/javascript"></script>
Required CSS file of code mirror.
<link href="scripts/CodeMirror/codemirror.min.css" rel="stylesheet" />
Add a custom icon for HTML source editor in the toolbar of Rich Text Editor using the template option of ToolbarSettings, define the code mirror plugins, and then pass the Rich Text Editor content as argument in the actionComplete event.
[Class-component]
import { createElement } from '@syncfusion/ej2-base';
import { Count, HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import CodeMirror from 'codemirror';
import 'codemirror/mode/css/css.js';
import 'codemirror/mode/htmlmixed/htmlmixed.js';
import 'codemirror/mode/javascript/javascript';
import * as React from 'react';
class App extends React.Component {
myCodeMirror;
textArea;
rteObj;
toolbarSettings = {
items: ['SourceCode']
};
value = `
<p>The Rich Text Editor component is WYSIWYG ("what you see is what you get") editor that provides the best user experience to create and update the content.
Users can format their content using standard toolbar commands.</p>
<p><b>Key features:</b></p>
<ul>
<li>
<p>Provides <IFRAME> and <DIV> modes</p>
</li>
<li>
<p>Capable of handling markdown editing.</p>
</li>
<li>
<p>Contains a modular library to load the necessary functionality on demand.</p>
</li>
<li>
<p>Provides a fully customizable toolbar.</p>
</li>
<li>
<p>Provides HTML view to edit the source directly for developers.</p>
</li>
<li>
<p>Supports third-party library integration.</p>
</li>
<li>
<p>Allows preview of modified content before saving it.</p>
</li>
<li>
<p>Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p>
</li>
<li>
<p>Contains undo/redo manager.</p>
</li>
<li>
<p>Creates bulleted and numbered lists.</p>
</li>
</ul>
`;
mirrorConversion(e) {
const id = this.rteObj.getID() + 'mirror-view';
let mirrorView = this.rteObj.element.querySelector('#' + id);
const charCount = this.rteObj.element.querySelector('.e-rte-character-count');
if (e.targetItem === 'Preview') {
this.textArea.style.display = 'block';
mirrorView.style.display = 'none';
this.textArea.innerHTML = this.myCodeMirror.getValue();
charCount.style.display = 'block';
}
else {
if (!mirrorView) {
mirrorView = createElement('div', { className: 'e-content' });
mirrorView.id = id;
this.textArea.parentNode.appendChild(mirrorView);
}
else {
mirrorView.innerHTML = '';
}
this.textArea.style.display = 'none';
mirrorView.style.display = 'block';
this.renderCodeMirror(mirrorView, this.rteObj.value);
charCount.style.display = 'none';
}
}
renderCodeMirror(mirrorView, content) {
this.myCodeMirror = CodeMirror(mirrorView, {
lineNumbers: true,
lineWrapping: true,
mode: 'text/html',
value: content
});
}
actionComplete(e) {
if (e.targetItem && (e.targetItem === 'SourceCode' || e.targetItem === 'Preview')) {
this.rteObj.sourceCodeModule.getPanel().style.display = 'none';
this.mirrorConversion(e);
}
else {
setTimeout(() => {
this.rteObj.toolbarModule.refreshToolbarOverflow();
}, 400);
}
}
created() {
this.textArea = this.rteObj.contentModule.getEditPanel();
}
render() {
return (<RichTextEditorComponent ref={(richtexteditor) => { this.rteObj = richtexteditor; }} height={450} toolbarSettings={this.toolbarSettings} showCharCount={true} actionComplete={this.actionComplete = this.actionComplete.bind(this)} value={this.value} created={this.created = this.created.bind(this)}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar, Count]}/>
</RichTextEditorComponent>);
}
}
export default App;
import { createElement } from '@syncfusion/ej2-base';
import { Count, HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import CodeMirror from 'codemirror';
import 'codemirror/mode/css/css.js';
import 'codemirror/mode/htmlmixed/htmlmixed.js';
import 'codemirror/mode/javascript/javascript';
import * as React from 'react';
class App extends React.Component<{},{}> {
public myCodeMirror: any;
public textArea: HTMLElement;
public rteObj: RichTextEditorComponent;
public toolbarSettings: object = {
items: ['SourceCode']
}
public value: string = `
<p>The Rich Text Editor component is WYSIWYG ("what you see is what you get") editor that provides the best user experience to create and update the content.
Users can format their content using standard toolbar commands.</p>
<p><b>Key features:</b></p>
<ul>
<li>
<p>Provides <IFRAME> and <DIV> modes</p>
</li>
<li>
<p>Capable of handling markdown editing.</p>
</li>
<li>
<p>Contains a modular library to load the necessary functionality on demand.</p>
</li>
<li>
<p>Provides a fully customizable toolbar.</p>
</li>
<li>
<p>Provides HTML view to edit the source directly for developers.</p>
</li>
<li>
<p>Supports third-party library integration.</p>
</li>
<li>
<p>Allows preview of modified content before saving it.</p>
</li>
<li>
<p>Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p>
</li>
<li>
<p>Contains undo/redo manager.</p>
</li>
<li>
<p>Creates bulleted and numbered lists.</p>
</li>
</ul>
`;
public mirrorConversion(e: any): void {
const id: string = this.rteObj.getID() + 'mirror-view';
let mirrorView: HTMLElement = this.rteObj.element.querySelector('#' + id) as HTMLElement;
const charCount: HTMLElement = this.rteObj.element.querySelector('.e-rte-character-count') as HTMLElement;
if (e.targetItem === 'Preview') {
this.textArea.style.display = 'block';
mirrorView.style.display = 'none';
this.textArea.innerHTML = this.myCodeMirror.getValue();
charCount.style.display = 'block';
} else {
if (!mirrorView) {
mirrorView = createElement('div', { className: 'e-content' });
mirrorView.id = id;
(this.textArea as any).parentNode.appendChild(mirrorView);
} else {
mirrorView.innerHTML = '';
}
this.textArea.style.display = 'none';
mirrorView.style.display = 'block';
this.renderCodeMirror(mirrorView, this.rteObj.value);
charCount.style.display = 'none';
}
}
public renderCodeMirror(mirrorView: HTMLElement, content: string): void {
this.myCodeMirror = CodeMirror(mirrorView, {
lineNumbers: true,
lineWrapping: true,
mode: 'text/html',
value: content
});
}
public actionComplete(e: any) {
if (e.targetItem && (e.targetItem === 'SourceCode' || e.targetItem === 'Preview')) {
(this.rteObj as any).sourceCodeModule.getPanel().style.display = 'none';
this.mirrorConversion(e);
} else {
setTimeout(() => {
this.rteObj.toolbarModule.refreshToolbarOverflow();
}, 400);
}
}
public created(): void{
this.textArea = (this.rteObj as any).contentModule.getEditPanel() as HTMLElement;
}
public render() {
return (
<RichTextEditorComponent ref={(richtexteditor) => { this.rteObj = richtexteditor! }} value={this.value} height={450} toolbarSettings={this.toolbarSettings} showCharCount={true} actionComplete={this.actionComplete = this.actionComplete.bind(this)} created={this.created = this.created.bind(this)}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar, Count]} />
</RichTextEditorComponent>
);
}
}
export default App;
[Functional-component]
import { createElement } from '@syncfusion/ej2-base';
import { Count, HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import CodeMirror from 'codemirror';
import 'codemirror/mode/css/css.js';
import 'codemirror/mode/htmlmixed/htmlmixed.js';
import 'codemirror/mode/javascript/javascript';
import * as React from 'react';
function App() {
let myCodeMirror;
let textArea;
let rteObj;
let toolbarSettings = {
items: ['SourceCode']
};
let value = `
<p>The Rich Text Editor component is WYSIWYG ("what you see is what you get") editor that provides the best user experience to create and update the content.
Users can format their content using standard toolbar commands.</p>
<p><b>Key features:</b></p>
<ul>
<li>
<p>Provides <IFRAME> and <DIV> modes</p>
</li>
<li>
<p>Capable of handling markdown editing.</p>
</li>
<li>
<p>Contains a modular library to load the necessary functionality on demand.</p>
</li>
<li>
<p>Provides a fully customizable toolbar.</p>
</li>
<li>
<p>Provides HTML view to edit the source directly for developers.</p>
</li>
<li>
<p>Supports third-party library integration.</p>
</li>
<li>
<p>Allows preview of modified content before saving it.</p>
</li>
<li>
<p>Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p>
</li>
<li>
<p>Contains undo/redo manager.</p>
</li>
<li>
<p>Creates bulleted and numbered lists.</p>
</li>
</ul>
`;
function mirrorConversion(e) {
const id = rteObj.getID() + 'mirror-view';
let mirrorView = rteObj.element.querySelector('#' + id);
const charCount = rteObj.element.querySelector('.e-rte-character-count');
if (e.targetItem === 'Preview') {
textArea.style.display = 'block';
mirrorView.style.display = 'none';
textArea.innerHTML = myCodeMirror.getValue();
charCount.style.display = 'block';
}
else {
if (!mirrorView) {
mirrorView = createElement('div', { className: 'e-content' });
mirrorView.id = id;
textArea.parentNode.appendChild(mirrorView);
}
else {
mirrorView.innerHTML = '';
}
textArea.style.display = 'none';
mirrorView.style.display = 'block';
renderCodeMirror(mirrorView, rteObj.value);
charCount.style.display = 'none';
}
}
function renderCodeMirror(mirrorView, content) {
myCodeMirror = CodeMirror(mirrorView, {
lineNumbers: true,
lineWrapping: true,
mode: 'text/html',
value: content
});
}
function actionComplete(e) {
if (e.targetItem && (e.targetItem === 'SourceCode' || e.targetItem === 'Preview')) {
rteObj.sourceCodeModule.getPanel().style.display = 'none';
mirrorConversion(e);
}
else {
setTimeout(() => {
rteObj.toolbarModule.refreshToolbarOverflow();
}, 400);
}
}
function created() {
textArea = rteObj.contentModule.getEditPanel();
}
return (<RichTextEditorComponent value={value} ref={(richtexteditor) => { rteObj = richtexteditor; }} height={450} toolbarSettings={toolbarSettings} showCharCount={true} actionComplete={actionComplete.bind(this)} created={created.bind(this)}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar, Count]}/>
</RichTextEditorComponent>);
}
export default App;
import { createElement } from '@syncfusion/ej2-base';
import { Count, HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import CodeMirror from 'codemirror';
import 'codemirror/mode/css/css.js';
import 'codemirror/mode/htmlmixed/htmlmixed.js';
import 'codemirror/mode/javascript/javascript';
import * as React from 'react';
function App(){
let myCodeMirror: any;
let textArea: HTMLElement;
let rteObj: RichTextEditorComponent;
let toolbarSettings: object = {
items: ['SourceCode']
}
let value: string = `
<p>The Rich Text Editor component is WYSIWYG ("what you see is what you get") editor that provides the best user experience to create and update the content.
Users can format their content using standard toolbar commands.</p>
<p><b>Key features:</b></p>
<ul>
<li>
<p>Provides <IFRAME> and <DIV> modes</p>
</li>
<li>
<p>Capable of handling markdown editing.</p>
</li>
<li>
<p>Contains a modular library to load the necessary functionality on demand.</p>
</li>
<li>
<p>Provides a fully customizable toolbar.</p>
</li>
<li>
<p>Provides HTML view to edit the source directly for developers.</p>
</li>
<li>
<p>Supports third-party library integration.</p>
</li>
<li>
<p>Allows preview of modified content before saving it.</p>
</li>
<li>
<p>Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p>
</li>
<li>
<p>Contains undo/redo manager.</p>
</li>
<li>
<p>Creates bulleted and numbered lists.</p>
</li>
</ul>
`;
function mirrorConversion(e: any): void {
const id: string = rteObj.getID() + 'mirror-view';
let mirrorView: HTMLElement = rteObj.element.querySelector('#' + id) as HTMLElement;
const charCount: HTMLElement = rteObj.element.querySelector('.e-rte-character-count') as HTMLElement;
if (e.targetItem === 'Preview') {
textArea.style.display = 'block';
mirrorView.style.display = 'none';
textArea.innerHTML = myCodeMirror.getValue();
charCount.style.display = 'block';
} else {
if (!mirrorView) {
mirrorView = createElement('div', { className: 'e-content' });
mirrorView.id = id;
(textArea as any).parentNode.appendChild(mirrorView);
} else {
mirrorView.innerHTML = '';
}
textArea.style.display = 'none';
mirrorView.style.display = 'block';
renderCodeMirror(mirrorView, rteObj.value);
charCount.style.display = 'none';
}
}
function renderCodeMirror(mirrorView: HTMLElement, content: string): void {
myCodeMirror = CodeMirror(mirrorView, {
lineNumbers: true,
lineWrapping: true,
mode: 'text/html',
value: content
});
}
function actionComplete(e: any) {
if (e.targetItem && (e.targetItem === 'SourceCode' || e.targetItem === 'Preview')) {
(rteObj as any).sourceCodeModule.getPanel().style.display = 'none';
mirrorConversion(e);
} else {
setTimeout(() => {
rteObj.toolbarModule.refreshToolbarOverflow();
}, 400);
}
}
function created(): void{
textArea = (rteObj as any).contentModule.getEditPanel() as HTMLElement;
}
return (
<RichTextEditorComponent value={value} ref={(richtexteditor) => { rteObj = richtexteditor! }} height={450} toolbarSettings={toolbarSettings} showCharCount={true} actionComplete={actionComplete.bind(this)} created={created.bind(this)}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar, Count]} />
</RichTextEditorComponent>
);
}
export default App;
Embedly Integration
This can be achieved by binding the actionComplete event to the toolbar items in the toolbarSettings property. In the event handler, create an element and add the appropriate class. The below script is have to add in the sample to embed the content,
Include embedly
javascript.
<script src="https://cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>
The above script is added to the page.
[Class-component]
import { HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
class App extends React.Component {
rteValue = "<p>The Syncfudion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here.</p><p><b>Key features:</b></p><ul><li><p>Provides <IFRAME> and <DIV> modes.</p></li><li><p>Bulleted and numbered lists.</p></li><li><p>Handles images, hyperlinks, videos, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager. </p></li></ul><div style='display: inline-block; width: 60%; vertical-align: top; cursor: auto;'><img alt='Sky with sun' src='https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Overview.png' width='309' style='min-width: 10px; min-height: 10px; width: 309px; height: 174px;' class='e-rte-image e-imginline e-rte-drag-image' height='174' /></div>";
toolbarSettings = {
items: ['CreateLink']
};
actionComplete = (args) => {
if (args.requestType === 'Links') {
if (args.elements[0].parentNode && (args.elements[0].parentNode).tagName === 'A'){
const emberEle = document.createElement('blockquote');
emberEle.setAttribute('class', 'embedly-card');
emberEle.appendChild(args.elements[0].parentElement);
emberEle.appendChild(document.createElement('p'));
args.range.insertNode(emberEle);
}
}
}
render() {
return (<RichTextEditorComponent height={450} actionComplete={this.actionComplete} value={this.rteValue} toolbarSettings={this.toolbarSettings}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar]}/>
</RichTextEditorComponent>);
}
}
export default App;
import { HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
class App extends React.Component<{},{}> {
private toolbarSettings: object = {
items: ['CreateLink']
}
private rteValue:string = "<p>The Syncfudion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here.</p><p><b>Key features:</b></p><ul><li><p>Provides <IFRAME> and <DIV> modes.</p></li><li><p>Bulleted and numbered lists.</p></li><li><p>Handles images, hyperlinks, videos, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager. </p></li></ul><div style='display: inline-block; width: 60%; vertical-align: top; cursor: auto;'><img alt='Sky with sun' src='https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Overview.png' width='309' style='min-width: 10px; min-height: 10px; width: 309px; height: 174px;' class='e-rte-image e-imginline e-rte-drag-image' height='174' /></div>";
private actionComplete = (args:any) => {
if (args.requestType === 'Links') {
if (args.elements[0].parentNode && (args.elements[0].parentNode).tagName === 'A'){
const emberEle: HTMLElement = document.createElement('blockquote');
emberEle.setAttribute('class', 'embedly-card');
emberEle.appendChild(args.elements[0].parentElement);
emberEle.appendChild(document.createElement('p'));
args.range.insertNode(emberEle);
}
}
}
public render() {
return (
<RichTextEditorComponent height={450} actionComplete={this.actionComplete} value={this.rteValue} toolbarSettings={this.toolbarSettings}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar]} />
</RichTextEditorComponent>
);
}
}
export default App;
[Functional-component]
import { HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
function App() {
let rteValue = "<p>The Syncfudion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here.</p><p><b>Key features:</b></p><ul><li><p>Provides <IFRAME> and <DIV> modes.</p></li><li><p>Bulleted and numbered lists.</p></li><li><p>Handles images, hyperlinks, videos, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager. </p></li></ul><div style='display: inline-block; width: 60%; vertical-align: top; cursor: auto;'><img alt='Sky with sun' src='https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Overview.png' width='309' style='min-width: 10px; min-height: 10px; width: 309px; height: 174px;' class='e-rte-image e-imginline e-rte-drag-image' height='174' /></div>";
let toolbarSettings = {
items: ['CreateLink']
};
const actionComplete =(args)=> {
if (args.requestType === 'Links') {
if (args.elements[0].parentNode && (args.elements[0].parentNode).tagName === 'A'){
const emberEle = document.createElement('blockquote');
emberEle.setAttribute('class', 'embedly-card');
emberEle.appendChild(args.elements[0].parentElement);
emberEle.appendChild(document.createElement('p'));
args.range.insertNode(emberEle);
}
}
}
return (<RichTextEditorComponent height={450} actionComplete={actionComplete} value={rteValue} toolbarSettings={toolbarSettings}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar]}/>
</RichTextEditorComponent>);
}
export default App;
import { HtmlEditor, Image, Inject, Link, QuickToolbar, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
function App() {
let toolbarSettings: object = {
items: ['CreateLink']
}
let rteValue:string = "<p>The Syncfudion Rich Text Editor, a WYSIWYG (what you see is what you get) editor, is a user interface that allows you to create, edit, and format rich text content. You can try out a demo of this editor here.</p><p><b>Key features:</b></p><ul><li><p>Provides <IFRAME> and <DIV> modes.</p></li><li><p>Bulleted and numbered lists.</p></li><li><p>Handles images, hyperlinks, videos, hyperlinks, uploads, etc.</p></li><li><p>Contains undo/redo manager. </p></li></ul><div style='display: inline-block; width: 60%; vertical-align: top; cursor: auto;'><img alt='Sky with sun' src='https://cdn.syncfusion.com/ej2/richtexteditor-resources/RTE-Overview.png' width='309' style='min-width: 10px; min-height: 10px; width: 309px; height: 174px;' class='e-rte-image e-imginline e-rte-drag-image' height='174' /></div>";
const actionComplete =(args:any)=> {
if (args.requestType === 'Links') {
if (args.elements[0].parentNode && (args.elements[0].parentNode).tagName === 'A'){
const emberEle: HTMLElement = document.createElement('blockquote');
emberEle.setAttribute('class', 'embedly-card');
emberEle.appendChild(args.elements[0].parentElement);
emberEle.appendChild(document.createElement('p'));
args.range.insertNode(emberEle);
}
}
}
return (
<RichTextEditorComponent height={450} actionComplete={actionComplete} value={rteValue} toolbarSettings={toolbarSettings}>
<Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar]} />
</RichTextEditorComponent>
);
}
export default App;