How to Style Markdown in Next.JS Using React-Markdown and SASS
Tags: react, sass, markdown
Published: 2022-11-09 06:52:56

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](https://contentful.com).

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](https://github.com/remarkjs/react-markdown) | React component to render markdown |
| [react-syntax-highlighter](https://github.com/react-syntax-highlighter/react-syntax-highlighter) | Syntax highlighting component for React using the seriously super amazing lowlight and refractor by wooorm |
| [rehype-raw](https://github.com/rehypejs/rehype-raw) | rehype plugin to parse the tree (and raw nodes) again, keeping positional info okay |
| [remark-gfm](https://github.com/remarkjs/remark-gfm) | remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists) |
| [sass](https://github.com/sass/sass) | Sass is an extension of CSS, adding nested rules, variables, mixins, selector inheritance, and more |

So let's begin by installing our dependencies:

```bash
npm i react-markdown react-syntax-highlighter rehype-raw remark-gfm sass
```

Next, let's create our markdown rendering component:

```js
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:

```css
.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](https://designly.biz/blog).