Editor Modes in React Rich Text Editor Component

4 Sep 202524 minutes to read

The Rich Text Editor component allows you to create and edit content, returning it as either valid HTML or Markdown (MD). It supports the following two editing formats:

  • HTML editor
  • Markdown editor

HTML editor

Rich Text Editor is a WYSIWYG editing control for formatting the word content as HTML.

HTML editing is the default mode of the Rich Text Editor. In this mode, you can format content using the available toolbar commands, and the editor will return valid HTML markup. To explicitly set this mode, set the editorMode property as HTML.

To create Rich Text Editor with HTML editing feature, inject the HtmlEditor module to the RTE using the RichTextEditor.Inject(HtmlEditor) method.

[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 Syncfusion 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 &lt;IFRAME&gt; and &lt;DIV&gt; 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>";
    render() {
        return (<RichTextEditorComponent height={450} value={this.rteValue}>
        <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 rteValue:string = "<p>The Syncfusion 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 &lt;IFRAME&gt; and &lt;DIV&gt; 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>";
  public render() {
    return (
      <RichTextEditorComponent height={450} value={this.rteValue}>
        <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 Syncfusion 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 &lt;IFRAME&gt; and &lt;DIV&gt; 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>";
    return (<RichTextEditorComponent height={450} value={rteValue}>
        <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 rteValue:string = "<p>The Syncfusion 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 &lt;IFRAME&gt; and &lt;DIV&gt; 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>";
    return (
      <RichTextEditorComponent height={450} value={rteValue}>
        <Inject services={[Toolbar, Image, Link, HtmlEditor, QuickToolbar]} />
      </RichTextEditorComponent>
    );
}

export default App;

IFrame editor

The IFrame editor mode enables content editing within an iframe, isolating styles from the main page.

For more details, refer to the Iframe Editor documentation.

Markdown editor

To create or edit content in Markdown format, set the editorMode property as Markdown, to create or edit the content and apply formatting to view markdown formatted content.

The third-party library such as Marked or any other library is used to convert markdown into HTML content.

  • The Supported Tags are h6, h5, h4, h3, h2, h1, blockquote, pre, p, ol, ul.
  • Supported selection tags are Bold, Italic, StrikeThrough, InlineCode, SubScript, SuperScript, UpperCase, and LowerCase.

To create Rich Text Editor with Markdown editing feature, inject the MarkdownEditor module to the Rich Text Editor using the RichTextEditor.Inject(MarkdownEditor) method.

[Class-component]

import { createElement } from '@syncfusion/ej2-base';
import { Image, Inject, Link, MarkdownEditor, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as Marked from 'marked';
import * as React from 'react';
class App extends React.Component {
    rteObj;
    // Rich Text Editor items list
    items = ['Bold', 'Italic', 'StrikeThrough', '|',
        'Formats', 'OrderedList', 'UnorderedList', '|',
        'CreateLink', 'Image', '|',
        {
            template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
                '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
            tooltipText: 'Preview',
        }, '|', 'Undo', 'Redo'];
    textArea;
    mdsource;
    mdPreview;
    // Rich Text Editor ToolbarSettings
    toolbarSettings = {
        items: this.items
    };
    
    // set the value to Rich Text Editor
    value = "The sample is added to showcase **markdown editing**. Type or edit the content and apply formatting to view markdown formatted content. We can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/). The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.";

    markDownConversion() {
        if (this.mdsource.classList.contains('e-active')) {
            const id = this.rteObj.getID() + 'html-view';
            const htmlPreview = this.rteObj.element.querySelector('#' + id);
            htmlPreview.innerHTML = Marked(this.rteObj.contentModule.getEditPanel().value);
        }
    }
    fullPreview() {
        const id = this.rteObj.getID() + 'html-preview';
        let htmlPreview = this.rteObj.element.querySelector('#' + id);
        if (this.mdsource.classList.contains('e-active')) {
            this.mdsource.classList.remove('e-active');
            this.mdsource.parentElement.title = 'Preview';
            this.textArea.style.display = 'block';
            htmlPreview.style.display = 'none';
        }
        else {
            this.mdsource.classList.add('e-active');
            if (!htmlPreview) {
                htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
                htmlPreview.id = id;
                this.textArea.parentNode.appendChild(htmlPreview);
            }
            this.textArea.style.display = 'none';
            htmlPreview.style.display = 'block';
            htmlPreview.innerHTML = Marked(this.rteObj.contentModule.getEditPanel().value);
            this.mdsource.parentElement.title = 'Code View';
        }
    }
    rendereComplete() {
        this.textArea = this.rteObj.contentModule.getEditPanel();
        this.textArea.addEventListener('keyup', (e) => {
            this.markDownConversion();
        });
        this.mdsource = document.getElementById('preview-code');
        this.mdsource.addEventListener('click', (e) => {
            this.fullPreview();
            if (e.currentTarget.classList.contains('e-active')) {
                this.rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                    'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            }
            else {
                this.rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                    'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            }
        });
    }
    render() {
        return (<RichTextEditorComponent id="markdownRTE" ref={(richtexteditor) => { this.rteObj = richtexteditor; }} editorMode='Markdown' height='250px' value={this.value} toolbarSettings={this.toolbarSettings} created={this.rendereComplete.bind(this)}>
              <Inject services={[MarkdownEditor, Toolbar, Image, Link]}/>
              </RichTextEditorComponent>);
    }
}
export default App;
import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import { Image, Inject, Link, MarkdownEditor, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';

class App extends React.Component<{},{}> {
  public rteObj: RichTextEditorComponent;

    // Rich Text Editor items list
    public items: object = ['Bold', 'Italic', 'StrikeThrough', '|',
    'Formats', 'OrderedList', 'UnorderedList', '|',
    'CreateLink', 'Image', '|',
    {
        template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
        '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
        tooltipText: 'Preview',
    }, '|', 'Undo', 'Redo'];

  public textArea: HTMLTextAreaElement;
  public mdsource: any;
  public mdPreview: HTMLElement;

  // Rich Text Editor ToolbarSettings
  public toolbarSettings: object = {
      items: this.items
  };
    // set the value to Rich Text Editor
    public value: string = " The sample is added to showcase **markdown editing**. Type or edit the content and apply formatting to view markdown formatted content. We can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/). The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.";

    public markDownConversion(): void {
        if (this.mdsource.classList.contains('e-active')) {
            const id: string = this.rteObj.getID() + 'html-view';
            const htmlPreview: HTMLElement = this.rteObj.element.querySelector('#' + id) as any;
            htmlPreview.innerHTML = Marked(((this.rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement).value);
        }
    }
    public fullPreview(): void {
        const id: string = this.rteObj.getID() + 'html-preview';
        let htmlPreview: HTMLElement = (this.rteObj as any).element.querySelector('#' + id);
        if (this.mdsource.classList.contains('e-active')) {
            this.mdsource.classList.remove('e-active');
            this.mdsource.parentElement.title = 'Preview';
            this.textArea.style.display = 'block';
            htmlPreview.style.display = 'none';
        } else {
            this.mdsource.classList.add('e-active');
            if (!htmlPreview) {
                htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
                htmlPreview.id = id;
                (this.textArea as any).parentNode.appendChild(htmlPreview);
            }
            this.textArea.style.display = 'none';
            htmlPreview.style.display = 'block';
            htmlPreview.innerHTML = Marked(((this.rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement).value);
            this.mdsource.parentElement.title = 'Code View';
        }
    }
    public rendereComplete(): void {
        this.textArea = (this.rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement;
        this.textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
            this.markDownConversion();
        });
        this.mdsource = document.getElementById('preview-code');
        this.mdsource.addEventListener('click', (e: MouseEvent) => {
            this.fullPreview();
            if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
                this.rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            } else {
                this.rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            }
        });
    }
    public render() {
        return (
          <RichTextEditorComponent id="markdownRTE" ref={(richtexteditor) => { this.rteObj = richtexteditor! }} editorMode='Markdown'
              height='250px' value={this.value} toolbarSettings={this.toolbarSettings} created={this.rendereComplete.bind(this)}>
              <Inject services={[MarkdownEditor, Toolbar, Image, Link]} />
              </RichTextEditorComponent>
        );
    }
}

export default App;

[Functional-component]

import { createElement } from '@syncfusion/ej2-base';
import { Image, Inject, Link, MarkdownEditor, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as Marked from 'marked';
import * as React from 'react';

function App() {
    let rteObj;
    // Rich Text Editor items list
    let items = ['Bold', 'Italic', 'StrikeThrough', '|',
        'Formats', 'OrderedList', 'UnorderedList', '|',
        'CreateLink', 'Image', '|',
        {
            template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
                '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
            tooltipText: 'Preview',
        }, '|', 'Undo', 'Redo'];
    let textArea;
    let mdsource;
    let mdPreview;
    // Rich Text Editor ToolbarSettings
    let toolbarSettings = {
        items: items
    };
    // set the value to Rich Text Editor
    function template() {
        return (<div>
        The sample is added to showcase **markdown editing**. Type or edit the content and apply formatting to view markdown formatted content. We can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/).
        The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.
      </div>);
    }
    ;
    function markDownConversion() {
        if (mdsource.classList.contains('e-active')) {
            const id = rteObj.getID() + 'html-view';
            const htmlPreview = rteObj.element.querySelector('#' + id);
            htmlPreview.innerHTML = Marked(rteObj.contentModule.getEditPanel().value);
        }
    }
    function fullPreview() {
        const id = rteObj.getID() + 'html-preview';
        let htmlPreview = rteObj.element.querySelector('#' + id);
        if (mdsource.classList.contains('e-active')) {
            mdsource.classList.remove('e-active');
            mdsource.parentElement.title = 'Preview';
            textArea.style.display = 'block';
            htmlPreview.style.display = 'none';
        }
        else {
            mdsource.classList.add('e-active');
            if (!htmlPreview) {
                htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
                htmlPreview.id = id;
                textArea.parentNode.appendChild(htmlPreview);
            }
            textArea.style.display = 'none';
            htmlPreview.style.display = 'block';
            htmlPreview.innerHTML = Marked(rteObj.contentModule.getEditPanel().value);
            mdsource.parentElement.title = 'Code View';
        }
    }
    function rendereComplete() {
        textArea = rteObj.contentModule.getEditPanel();
        textArea.addEventListener('keyup', (e) => {
            markDownConversion();
        });
        mdsource = document.getElementById('preview-code');
        mdsource.addEventListener('click', (e) => {
            fullPreview();
            if (e.currentTarget.classList.contains('e-active')) {
                rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                    'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            }
            else {
                rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
                    'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
            }
        });
    }
    return (<RichTextEditorComponent id="markdownRTE" ref={(richtexteditor) => { rteObj = richtexteditor; }} editorMode='Markdown' height='250px' valueTemplate={template} created={rendereComplete} toolbarSettings={toolbarSettings}>
        <Inject services={[MarkdownEditor, Toolbar, Image, Link, QuickToolbar]}/>
        </RichTextEditorComponent>);
}
export default App;
import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import { Image, Inject, Link, MarkdownEditor, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';

function App() {
  let rteObj: RichTextEditorComponent;
  // Rich Text Editor items list
  let items: object = ['Bold', 'Italic', 'StrikeThrough', '|',
  'Formats', 'OrderedList', 'UnorderedList', '|',
  'CreateLink', 'Image', '|',
  {
      template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn">' +
      '<span class="e-btn-icon e-md-preview e-icons"></span></button>',
      tooltipText: 'Preview',
  }, '|', 'Undo', 'Redo'];

  let textArea: HTMLTextAreaElement;
  let mdsource: any;
  let mdPreview: HTMLElement;

  // Rich Text Editor ToolbarSettings
  let toolbarSettings: object = {
      items: items
  };

  // set the value to Rich Text Editor
  let value: string = " The sample is added to showcase **markdown editing**. Type or edit the content and apply formatting to view markdown formatted content. We can add our own custom formation syntax for the Markdown formation, [sample link](https://ej2.syncfusion.com/home/). The third-party library <b>Marked</b> is used in this sample to convert markdown into HTML content.";

  function markDownConversion(): void {
      if (mdsource.classList.contains('e-active')) {
          const id: string = rteObj.getID() + 'html-view';
          const htmlPreview: HTMLElement = rteObj.element.querySelector('#' + id) as any;
          htmlPreview.innerHTML = Marked(((rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement).value);
      }
  }
  function fullPreview(): void {
      const id: string = rteObj.getID() + 'html-preview';
      let htmlPreview: HTMLElement = (rteObj as any).element.querySelector('#' + id);
      if (mdsource.classList.contains('e-active')) {
          mdsource.classList.remove('e-active');
          mdsource.parentElement.title = 'Preview';
          textArea.style.display = 'block';
          htmlPreview.style.display = 'none';
      } else {
          mdsource.classList.add('e-active');
          if (!htmlPreview) {
              htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
              htmlPreview.id = id;
              (textArea as any).parentNode.appendChild(htmlPreview);
          }
          textArea.style.display = 'none';
          htmlPreview.style.display = 'block';
          htmlPreview.innerHTML = Marked(((rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement).value);
          mdsource.parentElement.title = 'Code View';
      }
  }
  
  function rendereComplete(): void {
      textArea = (rteObj as any).contentModule.getEditPanel() as HTMLTextAreaElement;
      textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
          markDownConversion();
      });
      mdsource = document.getElementById('preview-code');
      mdsource.addEventListener('click', (e: MouseEvent) => {
          fullPreview();
          if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
              rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
              'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
          } else {
              rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
              'UnorderedList', 'CreateLink', 'Image', 'Formats', 'Undo', 'Redo']);
          }
      });
  }

  return (
    <RichTextEditorComponent id="markdownRTE" ref={(richtexteditor) => {rteObj = richtexteditor! }} editorMode='Markdown'
        height='250px' value={value} created={rendereComplete} toolbarSettings={toolbarSettings} >
        <Inject services={[MarkdownEditor, Toolbar, Image, Link]} />
        </RichTextEditorComponent>
  );
}

export default App;

For further details on Markdown editing, refer to the Markdown section.

See also