How to Style Markdown in Next.JS Using React-Markdown and SASS

Jay @ Designly - Nov 9 '22 - - Dev Community

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
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player