Markdown to HTML preview in React Markdown Editor Component

18 Mar 202524 minutes to read

The Markdown Editor provides an instant preview of Markdown changes, allowing users to see the formatted output while typing or editing text. This enhances the editing experience by enabling real-time visualization of Markdown formatting.

Enable Markdown Preview in React Markdown Editor

To enable the Markdown preview feature, integrate the third-party Marked library, which converts Markdown content into HTML format. The following example demonstrates how to enable Markdown to HTML preview in the Syncfusion React Markdown Editor.example demonstrates how to enable and preview Markdown changes within the Rich Text Editor.

[Class-component]

import { Browser } from '@syncfusion/ej2-base';
import {
  Image,
  Inject,
  Link,
  MarkdownEditor,
  RichTextEditorComponent,
  Table,
  Toolbar,
  ToolbarType
} from '@syncfusion/ej2-react-richtexteditor';
import {
  PaneDirective,
  PanesDirective,
  SplitterComponent,
} from '@syncfusion/ej2-react-layouts';
import * as Marked from 'marked';
import * as React from 'react';

class App extends React.Component {
    rteObj;
    splitterInstance;
    // set the value to Rich Text Editor
    value = `In Rich Text Editor , you click the toolbar buttons to format the words and the changes are visible immediately. 
Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words 
and phrases should look different from each other
    
Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text.
    
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`;
    // Rich Text Editor items list
    items = ['Bold', 'Italic', 'StrikeThrough', '|', 'Formats', 'OrderedList', 'UnorderedList', '|',
            'CreateLink', 'Image', 'Undo', 'Redo', 'CreateTable'];
    textArea;
    srcArea;
    placeholder = 'Enter your text here...';
    //Rich Text Editor ToolbarSettings
    toolbarSettings = {
        items: this.items,
        type: ToolbarType.Expand,
        enableFloating: false
    };
    onCreate() {
        this.textArea = this.rteObj.contentModule.getEditPanel();
        this.srcArea = document.querySelector('.source-code');
        this.updateValue();
    }
    onChange() {
        this.updateValue();
    }
    onResizing() {
        this.rteObj.refreshUI();
    }
    updateValue() {
        this.srcArea.innerHTML = Marked(this.rteObj.contentModule.getEditPanel().value);
    }
    updateOrientation() {
        if (Browser.isDevice) {
            this.splitterInstance.orientation = 'Vertical';
            document.body.querySelector('.heading').style.width = 'auto';
        }
    }
    content1() {
        return (<div className="content">
            <RichTextEditorComponent id='defaultRTE' ref={(richtexteditor) => { this.rteObj = richtexteditor; }} editorMode='Markdown' toolbarSettings={this.toolbarSettings} height='447px' saveInterval={1} created={this.onCreate.bind(this)} change={this.onChange.bind(this)} actionComplete={this.updateValue.bind(this)} value={this.value}>
                 <Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
            </RichTextEditorComponent>
        </div>);
    }
    ;
    content2() {
        return (<div className="heading right">
            <h6 className="title"><b>Markdown Preview</b></h6>
            <div className="splitter-default-content source-code pane2" style=></div>
        </div>);
    }
    ;
    render() {
        return (<div id="rte-default" className='control-pane'>
                    <div className='control-section markdown-preview' id="rtePreview">
                        <div className="content-wrapper">
                        <SplitterComponent id='splitter-rte-markdown-preview' ref={splitter => (this.splitterInstance = splitter)} height='450px' width='100%' resizing={this.onResizing.bind(this)} created={this.updateOrientation.bind(this)}>
                            <PanesDirective>
                                <PaneDirective resizable={true} size='50%' min="40%" cssClass='pane1' content={this.content1.bind(this)}></PaneDirective>
                                <PaneDirective min="40%" cssClass='pane2' content={this.content2.bind(this)}></PaneDirective>
                            </PanesDirective>
                        </SplitterComponent>
                        </div>
                    </div>
                </div>);
        }
}
export default App;
import { Browser } from '@syncfusion/ej2-base';
import {
  Image,
  Inject,
  Link,
  MarkdownEditor,
  RichTextEditorComponent,
  Table,
  Toolbar,
  ToolbarType,ToolbarSettingsModel, IToolbarItems
} from '@syncfusion/ej2-react-richtexteditor';
import {
  PaneDirective,
  PanesDirective,
  SplitterComponent,
} from '@syncfusion/ej2-react-layouts';
import * as Marked from 'marked';
import * as React from 'react';

class App extends React.Component<{},{}> {
  private rteObj: RichTextEditorComponent;
  private splitterInstance;
  // set the value to Rich Text Editor
  private value: string = `In Rich Text Editor , you click the toolbar buttons to format the words and the changes are visible immediately. 
Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words 
and phrases should look different from each other
  
Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text.
  
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`;

  // Rich Text Editor items list
  public items: (string | IToolbarItems)[] = ['Bold', 'Italic', 'StrikeThrough', '|',
                            'Formats', 'OrderedList', 'UnorderedList', '|',
                            'CreateLink', 'Image', 'Undo', 'Redo', 'CreateTable'];
  public textArea: HTMLElement;
  public srcArea: HTMLElement;
  public placeholder: string = 'Enter your text here...';
  //Rich Text Editor ToolbarSettings
  public toolbarSettings: ToolbarSettingsModel = {
      items: this.items,
      type: ToolbarType.Expand,
      enableFloating: false
  };
  public onCreate() {
      this.textArea = this.rteObj.contentModule.getEditPanel() as HTMLElement;
      this.srcArea = document.querySelector('.source-code') as HTMLElement;
      this.updateValue();
  }
  public onChange() {
      this.updateValue();
  }
  public onResizing() {
      this.rteObj.refreshUI();
  }
  public updateValue() {
      this.srcArea.innerHTML = Marked((this.rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
  }
  public updateOrientation() { 
      if (Browser.isDevice) {
          this.splitterInstance.orientation = 'Vertical';
          (document.body.querySelector('.heading') as any).style.width = 'auto';
      }
  }
  public content1() {
      return (<div className="content">
          <RichTextEditorComponent id="markdown-editor" editorMode='Markdown' ref={richtexteditor => (this.rteObj = richtexteditor)} toolbarSettings={this.toolbarSettings} height='447px' saveInterval={1} 
                      created={this.onCreate.bind(this)} 
                      change={this.onChange.bind(this)} 
                      actionComplete={this.updateValue.bind(this)} 
                      value={this.value}>
               <Inject services={[Toolbar, MarkdownEditor, Link, Image, Table]} />
          </RichTextEditorComponent>
      </div>);
  };
  public content2() {
      return (<div className="heading right">
          <h6 className="title"><b>Markdown Preview</b></h6>
          <div className="splitter-default-content source-code pane2" style=></div>
      </div>);
  };

  public render() {
    return (
      <div id="rte-default" className='control-pane'>
         <div className='control-section markdown-preview' id="rtePreview">
                    <div className="content-wrapper">
                    <SplitterComponent id='splitter-rte-markdown-preview' ref={splitter => (this.splitterInstance = splitter)} height='450px' width='100%' resizing={this.onResizing.bind(this)} created={this.updateOrientation.bind(this)}>
                        <PanesDirective>
                            <PaneDirective resizable={true} size='50%' min="40%" cssClass='pane1' content={this.content1.bind(this)}></PaneDirective>
                            <PaneDirective min="40%" cssClass='pane2' content={this.content2.bind(this)}></PaneDirective>
                        </PanesDirective>
                    </SplitterComponent>
                    </div>
                </div>
      </div>
    );
  }
}

export default App;

[Functional-component]

import { Browser } from '@syncfusion/ej2-base';
import {
  Image,
  Inject,
  Link,
  MarkdownEditor,
  RichTextEditorComponent,
  Table,
  Toolbar,
  ToolbarType,
} from '@syncfusion/ej2-react-richtexteditor';
import {
  PaneDirective,
  PanesDirective,
  SplitterComponent,
} from '@syncfusion/ej2-react-layouts';
import * as Marked from 'marked';
import * as React from 'react';

function App() {
  let rteObj;
  let splitterInstance;
  // set the value to Rich Text Editor
  const value = `In Rich Text Editor , you click the toolbar buttons to format the words and the changes are visible immediately. 
   Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words 
   and phrases should look different from each other
       
   Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text.
       
   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`;
  // Rich Text Editor items list
  const items = [
    'Bold', 'Italic', 'StrikeThrough', '|', 'Formats', 'OrderedList', 'UnorderedList', '|',
    'CreateLink', 'Image', 'Undo', 'Redo', 'CreateTable'
  ];
  let textArea;
  let srcArea;
  //Rich Text Editor ToolbarSettings
  const toolbarSettings = {
    items: items,
    type: ToolbarType.Expand,
    enableFloating: false,
  };
  function onCreate() {
    textArea = rteObj.contentModule.getEditPanel();
    srcArea = document.querySelector('.source-code');
    updateValue();
  }
  function onChange() {
    updateValue();
  }
  function onResizing() {
    rteObj.refreshUI();
  }
  function updateValue() {
    srcArea.innerHTML = Marked(
      rteObj.contentModule.getEditPanel().value
    );
  }
  function updateOrientation() {
    if (Browser.isDevice) {
      splitterInstance.orientation = 'Vertical';
      document.body.querySelector('.heading').style.width = 'auto';
    }
  }
  function content1() {
    return (
      <div className="content">
        <RichTextEditorComponent
          id="markdown-editor"
          ref={(richtexteditor) => {
            rteObj = richtexteditor;
          }}
          editorMode="Markdown"
          toolbarSettings={toolbarSettings}
          height="447px"
          saveInterval={1}
          created={onCreate.bind(this)}
          change={onChange.bind(this)}
          actionComplete={updateValue.bind(this)}
          value={value}
        >
          <Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
        </RichTextEditorComponent>
      </div>
    );
  }
  function content2() {
    return (
      <div className="heading right">
        <h6 className="title">
          <b>Markdown Preview</b>
        </h6>
        <div
          className="splitter-default-content source-code pane2"
          style=
        ></div>
      </div>
    );
  }
  return (
    <div className="control-pane">
      <div className="control-section markdown-preview" id="rtePreview">
        <div className="content-wrapper">
          <SplitterComponent
            id="splitter-rte-markdown-preview"
            ref={(splitter) => (splitterInstance = splitter)}
            height="450px"
            width="100%"
            resizing={onResizing.bind(this)}
            created={updateOrientation.bind(this)}
          >
            <PanesDirective>
              <PaneDirective
                resizable={true}
                size="50%"
                min="40%"
                cssClass="pane1"
                content={content1.bind(this)}
              ></PaneDirective>
              <PaneDirective
                min="40%"
                cssClass="pane2"
                content={content2.bind(this)}
              ></PaneDirective>
            </PanesDirective>
          </SplitterComponent>
        </div>
      </div>
    </div>
  );
}
export default App;
import { Browser } from '@syncfusion/ej2-base';
import {
  Image,
  Inject,
  Link,
  MarkdownEditor,
  RichTextEditorComponent,
  Table,
  Toolbar,
  ToolbarType,ToolbarSettingsModel, IToolbarItems
} from '@syncfusion/ej2-react-richtexteditor';
import {
  PaneDirective,
  PanesDirective,
  SplitterComponent,
} from '@syncfusion/ej2-react-layouts';
import * as Marked from 'marked';
import * as React from 'react';

function App() {
  let rteObj: RichTextEditorComponent;
  let splitterInstance;
  // set the value to Rich Text Editor
  const value: string = `In Rich Text Editor , you click the toolbar buttons to format the words and the changes are visible immediately. 
Markdown is not like that. When you format the word in Markdown format, you need to add Markdown syntax to the word to indicate which words 
and phrases should look different from each other
    
Rich Text Editor supports markdown editing when the editorMode set as **markdown** and using both *keyboard interaction* and *toolbar action*, you can apply the formatting to text.
    
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`;
  // Rich Text Editor items list
  const items: (string | IToolbarItems)[] = ['Bold', 'Italic', 'StrikeThrough', '|',
                            'Formats', 'OrderedList', 'UnorderedList', '|',
                            'CreateLink', 'Image', 'Undo', 'Redo', 'CreateTable'];
  let textArea: HTMLElement;
  let srcArea: Element;
  //Rich Text Editor ToolbarSettings
  const toolbarSettings: ToolbarSettingsModel = {
      items: items,
      type: ToolbarType.Expand,
      enableFloating: false
  };
  function onCreate() {
      textArea = rteObj.contentModule.getEditPanel() as HTMLElement;
      srcArea = document.querySelector('.source-code') as HTMLElement;
      updateValue();
  }
  function onChange() {
      updateValue();
  }
  function onResizing() {
      rteObj.refreshUI();
  }
  function updateValue() {
      srcArea.innerHTML =  Marked((rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
  }
  function updateOrientation() { 
      if (Browser.isDevice) {
          splitterInstance.orientation = 'Vertical';
          (document.body.querySelector('.heading') as any).style.width = 'auto';
      }
  }
  function content1() {
      return (<div className="content">
          <RichTextEditorComponent id='markdown-editor' ref={(richtexteditor) => { rteObj = richtexteditor; }} editorMode='Markdown'  toolbarSettings={toolbarSettings} height='447px' saveInterval={1} created={onCreate.bind(this)} change={onChange.bind(this)} actionComplete={updateValue.bind(this)} value={value}>
              <Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
          </RichTextEditorComponent>
      </div>);
  };
  function content2() {
      return (<div className="heading right">
          <h6 className="title"><b>Markdown Preview</b></h6>
          <div className="splitter-default-content source-code pane2" style=></div>
      </div>);
  };
  return (
      <div className='control-pane'>
          <div className='control-section markdown-preview' id="rtePreview">
              <div className="content-wrapper">
              <SplitterComponent id='splitter-rte-markdown-preview' ref={splitter => (splitterInstance = splitter)} height='450px' width='100%' resizing={onResizing.bind(this)} created={updateOrientation.bind(this)}>
                      <PanesDirective>
                          <PaneDirective resizable={true} size='50%' min="40%" cssClass='pane1' content={content1.bind(this)}></PaneDirective>
                          <PaneDirective min="40%" cssClass='pane2' content={content2.bind(this)}></PaneDirective>
                      </PanesDirective>
                  </SplitterComponent>
              </div>
          </div>
      </div>
  );
}
export default App;