How do I render Markdown from a React component?

I have my documentation written in markdown and I would like to render those files from my JSX (ES6+CommonJS) code into React components. How can I achieve this?

For example I have styles.markdown and I would like to render it into a <p> tag.


Solution 1:

You can use React-Markdown:

const React = require('react')
const ReactDOM = require('react-dom')
const ReactMarkdown = require('react-markdown')

const input = '# This is a header\n\nAnd this is a paragraph'

ReactDOM.render(<ReactMarkdown source={input} />, document.getElementById('container'))

Or... You can just create a simple React component that wraps a call to a Markdown parser. There are two very good ones for JavaScript:

  • Remarkable
  • Marked

Now, you can create a component like this:

var MarkdownViewer = React.createClass({
    render: function() {
        // pseudo code here, depends on the parser
        var markdown = markdown.parse(this.props.markdown);
        return <div dangerouslySetInnerHTML={{__html:markdown}} />;
    }
});

There used to have one already, but it doesn't seem to be maintained anymore: https://github.com/tcoopman/markdown-react

Also, if you need a React Markdown Editor, check out: react-mde. Disclaimer: I am the author.

Solution 2:

The package react-markdown with Markdown component will be good choice:

import React from 'react'
import Markdown from 'react-markdown'
    
var src = "# This is markdown document"
    
React.render(
  <Markdown children={src} />,
  document.getElementById('root')
)

You can write inplace here-docs like this:

<Markdown>
  # Header

  * dotted lists
  * [url](/doc)
</Markdown>

It is possible to specify transformers for link-urls and image-urls and much more.

Solution 3:

Example of Markdown component that renders html from markdown text, the logic of loading data should be implemented in separate store/parent component/whatever. I am using marked package for converting markdown to html.

import React from 'react';
import marked from 'marked';

export default class MarkdownElement extends React.Component {
  constructor(props) {
    super(props);

    marked.setOptions({
      gfm: true,
      tables: true,
      breaks: false,
      pedantic: false,
      sanitize: true,
      smartLists: true,
      smartypants: false
    });
  }
  render() {
    const { text } = this.props,
      html = marked(text || '');

    return (<div>
      <div dangerouslySetInnerHTML={{__html: html}} />
    </div>);
  }
}

MarkdownElement.propTypes = {
  text: React.PropTypes.string.isRequired
};

MarkdownElement.defaultProps = {
  text: ''
};

Solution 4:

I'm a little late to the party, but I wrote a competitor library to the ones mentioned above that has an added benefit of not needing the dangerouslySetInnerHtml hack: https://github.com/probablyup/markdown-to-jsx