If you have a blog or website with articles or long text documents, markdown is your friend. It makes authoring documents so much easier and more intuitive than straight HTML. Markdown has a far smaller learning curve than HTML and can easily be taught to non-tech-savvy writers. Markdown editors are also built-in to headless CMSs like Contentful.
In this tutorial I will show you how to take a markdown document, convert it to HTML and then style it using React JS, React-Markdown and SASS.
We will need the following packages for this tutorial:
Package Name | Description |
---|---|
react-markdown | React component to render markdown |
react-syntax-highlighter | Syntax highlighting component for React using the seriously super amazing lowlight and refractor by wooorm |
rehype-raw | rehype plugin to parse the tree (and raw nodes) again, keeping positional info okay |
remark-gfm | remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists) |
sass | Sass is an extension of CSS, adding nested rules, variables, mixins, selector inheritance, and more |
So let's begin by installing our dependencies:
npm i react-markdown react-syntax-highlighter rehype-raw remark-gfm sass
Next, let's create our markdown rendering component:
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { a11yDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
export default function MdPage({ markdown }) {
// Override react-markdown elements to add class names
const P = ({ children }) => <p className="md-post-p">{children}</p>
const Li = ({ children }) => <li className="md-post-li">{children}</li>
const H4 = ({ children }) => <h4 className="md-post-h4">{children}</h4>
const Hr = () => <hr className="md-post-hr" />
const mdBody = <ReactMarkdown
remarkPlugins={[remarkGfm]} // Allows us to have embedded HTML tags in our markdown
linkTarget='_blank' // Append target _blank to links so they open in new tab/window
components={{
p: P,
li: Li,
h4: H4,
hr: Hr,
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
style={a11yDark}
language={match[1]}
PreTag="div"
{...props}
>{String(children).replace(/\n$/, '')}</SyntaxHighlighter>
) : (
<code className="md-post-code" {...props}>
{children}
</code>
)
},
}}
>
{markdown}
</ReactMarkdown>
return mdBody;
}
Now let's create our SASS styles:
.md-post {
&-p {
font-size: 1.1em;
}
&-li {
list-style-type: none;
}
&-h4 {
font-size: 1.5em;
color: red;
}
&-hr {
width: 200px;
height: 20px;
margin: 60px auto;
background: radial-gradient(circle closest-side, #d4d4d4 98%, #0000) 0/calc(100%/5) 100%;
border: none;
}
}
That's it! It's that simple. You can override any of the HTML elements converted by react-markdown
to apply any CSS styles you wish.
I hope you enjoyed this article. For more great information, please visit our Blog.