I’ve played with markdown and react but never really put the two together. When the time finally came, I wanted a solution that didn’t require me to make changes to webpack configuration since create-react-app abstracts the webpack setup and allows the developer to focus on building the app. Unlike the static site generator Gatsby JS1 or the react framework Next.js2, working with markdown in React isn’t very intuitive but it’s also not difficult.

This article will solve for a scenario where the path to a markdown file is known and its contents are loaded into a react component. We’ll use the react hooks useEffect, useState and a Markdown to JSX3 library called, you guessed it, markdown-to-jsx.

Set up react project

npx create-react-app react-markdown-blog-example

Install dependencies

yarn add markdown-to-jsx

Generate some random markdown file

I used this neat markdown generator and pasted the content inside ./src/markdown/2019-09-md-to-jsx-example.md. The name of the file doesn’t matter but you’ll need it in a later step.

Let’s write some code

Inside ./src/App.js:

import './App.css';
import { useEffect, useState } from 'react';
import Markdown from 'markdown-to-jsx';

function App() {
  const postName = '2021-09-md-to-jsx-example.md';
  const [post, setPost] = useState('')
  useEffect(() => {
    import(`./blog/${postName}`)
        .then(res => {
            fetch(res.default)
                .then(res => res.text())
                .then(res => setPost(res))
                .catch(err => console.log(err));
        })
        .catch(err => console.log(err));
});
  return (
    <div className="App">
      <article>
        <Markdown>{post}</Markdown>
      </article>
    </div>
  );
}

export default App;

In the code above, we initiate a postName variable to house the name of our markdown file. In this example, it is hardcoded but you can do many things with it. You can use url params to get the title for example then map through an array of posts from your server. But we aren’t going to be fancy here.

Next, we create a variable to house our post content state as well as a function to update state after fetching the post.

Third, inside the useEffect hook, import the markdown file path, grab its contents it using the javascript fetch method, then update state using our setPost method to store the response.

Lastly, we use the Markdown component to wrap our post content which we stored inside the post variable.

Minimal styling

We wouldn’t want our app to be bare and basic so let’s add a bit of style.

Inside ./src/App.css:

.App {
  padding: 2rem 1rem;
  background-color: #282c34;
  color: rgb(250, 227, 227);
}

Et voila!






  1. Source files from file system with Gatby JS: https://www.gatsbyjs.com/docs/how-to/sourcing-data/sourcing-from-the-filesystem/ 

  2. Fetching data(include markdown files) with NextJS: https://nextjs.org/docs/migrating/from-gatsby#data-fetching 

  3. Markdown to JSX Library: https://github.com/probablyup/markdown-to-jsx