How to render Markdown as pure React Components

How to render Markdown as pure React Components

Markdown is the sanest way to write text easily. Many applications where an user is allowed to write and store some text on the database on this format, will someday need to render it somewhere. The problem is that on every platform this behaviour can be handled of different ways, some developers may just convert the markdown into HTML in the server side and others for example frontend developer that doesn't work too much with server side technologies, will just simply convert the markdown into HTML in the client side. This, although it's not the best approach for applications that are used everywhere, from every browser and for a lot of people, it is pretty good when it's only for an enterprise application where the user will always need to use your app without complaining about the performance.

The other problem you need to handle is the debug process when you work with React, using the React Dev Tools you can easily debug which components are failing and where they are, but when you transpile Markdown into HTML, it ain't so easy in React. That's why @rexxars developed an awesome component that allows you to convert markdown into React components (to be rendered in the view) easily.

1. Install React Markdown Component

With the help of a third party component, namely React Markdown, you will be able to convert easily plain markdown into React Components in your view. To install this component on your project, switch to the directory of your project with the terminal and run the following NPM command:

npm install --save react-markdown

You can get more information about this component visiting the official repository at Github here. The component uses under the hood uses the awesome CommonMark, a rationalized version of Markdown syntax, with a spec and BSD-licensed reference implementations in C and JavaScript. For more information, for more information visit the official website or the repository at Githbub here. At the same time, to convert the markdown into React Components, it uses the Common Mark React Renderer module, a Renderer for CommonMark which returns an array of React elements, ready to be used in a React component.

Note

The only disadvantage of React Markdown, is that inline attributes inside HTML doesn't work.

2. Using it as a component

The module/library itself is just a React component that can be easily embedded into any view of React that you want, just import react-markdown and set some options:

import Markdown from 'react-markdown';

<Markdown 
    escapeHtml={true}
    source={this.ContentMarkdown} 
/>

So you can use it inside your app like:

import React from 'react';

// Import the Markdown component
import Markdown from 'react-markdown';
 
export default class App extends React.Component {
    constructor(props, context) {
        super(props, context);

        // Define some Markdown content
        this.ContentMarkdown = `# Your markdown here \n <h1>This won't be translated into HTML</h1>`;
    }

    render() {
        return (
            <div>
                {/* Render the markdown component */}
                <Markdown 
                    escapeHtml={true}
                    source={this.ContentMarkdown} 
                />
            </div>
        );
    }
}

The possible types of elements that can be allowed/disallowed are (and the Reacts components that are translated into):

  • HtmlInline - Inline HTML
  • HtmlBlock - Block of HTML
  • Text - Text nodes (inside of paragraphs, list items etc)
  • Paragraph - Paragraph nodes (<p>)
  • Heading - Headers (<h1>, <h2> etc)
  • Softbreak - Newlines
  • Hardbreak - Hard line breaks (<br>)
  • Link - Link nodes (<a>)
  • Image - Image nodes (<img>)
  • Emph - Emphasis nodes (<em>)
  • Code - Inline code nodes (<code>)
  • CodeBlock - Blocks of code (<code>)
  • BlockQuote - Block quotes (<blockquote>)
  • List - List nodes (<ol>, <ul>)
  • Item - List item nodes (<li>)
  • Strong - Strong/bold nodes (<strong>)
  • ThematicBreak - Horizontal rule nodes (<hr>)

In this case, with the markdown we provided, the generated content was:

React Console Markdown Components

Note

Disallowing a node will also prevent the rendering of any children of that node, unless the unwrapDisallowed option is set to true. Eg, disallowing a paragraph will not render it's children text nodes.

Happy coding !

Become a more social person