React / Markdown Documentation Site Pt. 1

In this series, I will be showing how you can quickly build a documentation website for your React app or library based on Markdown templates.
I had the pleasure of building a UI component library for Riipen recently and had need to generate a documentation site on how to use it. My requirements for this documentation site were:
- I can display the formal props of all components in the UI including a description, type, name, and any other options.
- I can show what components look like while in use
- I can show code examples of how to use components
Luckily I found that Material-UI had similar requirements and was able to browse their code base for inspiration around my own project.
I hope that by writing this series would I can formalize my knowledge but also help others who are looking at the same list of requirements.
Note: this series is largely based off of Material-UI and how they have configured their documentation site. All credit goes to their team for the architecture and decision making to make this post possible.
Technologies.
Since we are looking to document a React app or package, it seems to make sense to build our documentation site using React as well.
We will be building components which interpret other React components, can read Markdown files and parse them to HTML, and running the whole stack on top of NextJS.
Setup.
Start by creating your new repository and installing the essentials.
$ mkdir docs
$ cd docs
$ npm init -y
$ npm install --save react react-dom next
$ mkdir pagesThis post won’t go into detail about all the goodies surrounding NextJS and it’s architecture, but what you really need to know is that it’s a server side rendering react framework that can get us up and running quickly. Behind the scenes it uses things like Webpack and Babel, but it also abstracts most of that away to let us focus on our application logic.
After initial repository creation, following the NextJS getting started documentation, place the following scripts in your package.json file.
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}Finally, run $ npm run dev and visit localhost:3000 to make sure you have your server running correctly.
Markdown to React.
Let’s now focus on building some tools that can take a basic markdown file and render it using React to our NextJS app.
Markdown is amazing but it leaves a lot to be desired for what we really need functionality wise in a documentation site. Being able to display code demos, custom syntax highlighting, having dynamic tables of content, etc are just a few of the things we are going to need on top of what Markdown can provide.
So to cover our formal requirements, let’s build two foundational components (these will be filled in more in later posts in this series to fulfill our requirements).
The first will be a page “wrapper” component which will serve as our page layout allowing us to add items like headers, footers, menus, etc later which we will use to render all of our pages. The second will take a Markdown file and render it by converting the markdown to HTML.
There’s a lot going on here so let’s break it down.
MarkdownElement is our component for translating Markdown into HTML DOM elements. We are using the package marked to do the heavy lifting here and then simply inserting the results into the DOM. There are a lot of configuration options as part of marked and this post won’t go into detail on them. If you are interested you can read the marked specs here.
The MarkdownPage component is our base layout to a page in our NextJS app. It takes a single prop called req which is a request context. This object will provide us with information on all files within a directory (which we will use in later parts of this series). We simply scan the request context looking for our markdown file and then use that file in combination with MarkdownElement to render it on the page.
The First Page.
Back to your NextJS app, we can insert our first page as pages/index.jsx in the repository. This will act as our home page.
Inside of that index.jsx file, we will simply make use of the new MarkdownPage component we created.
import React from "react";import MarkdownPage from "src/modules/components/MarkdownPage";const req = require.context(
"src/pages/home",
false,
.md
);export default function Page() {
return (
<MarkdownPage
req={req}
/>
);
}
From this file, you can see how we have chosen to structure out app, by placing the actual Markdown files that represent our pages in src/pages/.
We are simply requesting the context of the src/pages/home directory here, and passing that into our page component.
Now you can write whatever Markdown you want in src/pages/home/home.md and if you visit localhost:3000 you should see that markdown document converted to a web page!
Simple!
What’s Next?
In part 2 of this series, we are going to look into how you can get some sample React code showing up inside of your new Markdown page, and how you can have that code executed as well.
In part 3 I will show how you can generate classic API style documentation for your react app / components using JSDocs and how to insert that into your Markdown pages.
In part 4 we will look at some nice quality of life improvements with this project with items such as: multi-language syntax highlighting with prismjs, dynamic creation of table of contents per page based on markdown, and how to make everything look nice with styled-jsx.
Stay tuned for more!

