Developing this site is always new knowledge for me in the programming field. I recently tried to implement a new small feature that fetches from Strapi.

There were a lot of issues that come up. One of the issues I am curious about is; what is the right way for parsing markdown in NextJS?

I see that there is an example in NextJs with Strapi official repository. By using remark and remark-HTML to parse markdown to HTML. But then I read many articles says about security issues when using innerHTML or dangerouslySetInnerHTML.

I know this general issue if the application accepting content from other users opens the possibility to inject script tags that can compromise the users.

So I wondering how to solve this issue.

This site was supposed to use a site builder like Webflow(aff).

I see it because of its speed of building without touching a lot of code.

This strategy I am hoping will allow me to put more effort into focusing on adding new and developing content.

I like Webflow designer and collection builder, but I think I don't like the editor. So here I finally decided to build on my own using NextJS and Ghost CMS.

As the experiment for adding a small feature to this site, I think Strapi was my first choice. Because I have the freedom about how I build the content type to structure the data.

Not much different with Webflow collections, Strapi has complete field data types too. The one that I like most from Strapi is the components content type that has repeatable options.

I shouldn't worry about innerHTML security issues because it is only me who creates and modifies the content on this site.

The Alternative, How To Parse Markdown In A Secure NextJS/React

If you search markdown parser on Github, you will find many libraries you can try.

I found a few methods by using the function as a component, then passing the content in a Markdown format to it and process the parsing.

Previously on this post, I was using remark-react as the library to convert markdown to react element. If you see its repository page, you will see in the description that it is suggesting to use remark-rehype and rehype-react instead.

So, you can start by installing the required dependencies,

# for npm
npm install unified remark-parse remark-rehype rehype-react

#for yarn
yarn add unified remark-parse remark-rehype rehype-react

Then we create the function file and import the dependencies,

import React from 'react';
import ReactDOM from 'react-dom';
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeReact from "rehype-react";

export default function PrintMarkdown({markdown}) {
  const content = unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeReact, { createElement: React.createElement })
    .processSync(markdown).result;

  return (
      <div>
          {content}
      </div>
  )
}

Or simpler with just react-markdown library on the react page.

import React from 'react'
import ReactDom from 'react-dom'
import ReactMarkdown from 'react-markdown';

export default function ThePage() {
  const markdown = `
      ## _The Last Markdown Editor, Ever_
      `;

  return ( 
    <div >
    	<ReactMarkdown source = { markdown } />
    </div>
  )
}

This library will transform Markdown to React, so we don't need to use innerHTML or dangerouslySetInnerHTML anymore.

Which one to use is depend on your source content and its purpose. Hope this finds you helpful.

Let me know your thought or you find a mistake/outdated content for this post.

Get the latest update of tutorials, inspirations and useful resources for website design and development to your email box.