Designly Blog

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

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

Posted in Full-Stack Development by Jay Simons
Published on November 8, 2022

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 NameDescription
react-markdownReact component to render markdown
react-syntax-highlighterSyntax highlighting component for React using the seriously super amazing lowlight and refractor by wooorm
rehype-rawrehype plugin to parse the tree (and raw nodes) again, keeping positional info okay
remark-gfmremark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists)
sassSass 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.


Loading comments...