Next.js is a React.js framework for server side rendering and static projects. It's easy to use and works extremely well when building a website which stores its content in Markdown. A feature called dynamic routes, which generates routes at build time, provides functionality to read a directory full of Markdown files and generate separate webpages for each file.
Remark-react is a package that converts Markdown into React and it works with a Next.js application. It differs from remark-html as it doesn't force the developer to use dangerouslySetInnerHTML
.
Honestly, if you're wanting to use Markdown with Next.js I'd recommend you try out remark-react. If you do, you should also be aware of the following:
Remark-react will create all links using the
<a>
component whereas in Next.js you should be using the<Link>
component fromnext/link
.
Using the proper <Link>
component in a Next.js project is important as it changes the content of the page and the URL without a full redirect, whereas when an anchor (<a>
) tag is used the page will be reloaded and React will need to do a full render - this can cause your application to perform badly and appear slow.
Configuring a Next.js application to use remark-react, properly
The example is taken from GitHub
Adding Markdown to React conversion
You'll need three NPM packages:
npm i -s unified remark-parse remark-react
Once you've added them, import them all into your React app:
import unified from 'unified';
import parse from 'remark-parse';
import remark2react from 'remark-react';
Next, add the following code to convert Markdown into React components:
const content = unified()
.use(parse)
.use(remark2react)
.processSync(markdown).result;
From the code blocks above, your Next.js application should now be rendering Markdown into React.
Adding a CustomLink
to handle local and external linking
Now we can add a custom link component to the remark-react configuration to instruct it to use the <Link>
component for local links and the <a>
component for external links.
Add a new component called customLink.js
to your project with the contents:
import Link from 'next/link';
export default function CustomLink({ children, href }) {
// If the link is local it will start with a "/"
// Otherwise it'll be something like "https://"
return href.startsWith('/') || href === '' ? (
<Link href={href}>
<a>
{children}
</a>
</Link>
) : (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
>
{children}
</a>
);
}
The CustomLink
component will render a <Link>
if the href
passed in has a local target such as /about
but will render an <a>
if it has an external target such as https://dev.to
.
Updating the Markdown converter to use the CustomLink
component
Finally, we need to update the Markdown to React code to use the CustomLink
component when rendering links. This can be done by adding a configuration object to the remark-react .use
line:
const content = unified()
.use(parse)
.use(remark2react, {
remarkReactComponents: {
// Use CustomLink instead of <a>
a: CustomLink,
},
})
.processSync(markdown).result;
Summary
That's all you need to do to use React-remark in your Next.js project. Using the configuration object, you can add a custom component for more than just an anchor HTML tag, incase you want to swap the img
tag for something more intelligent (image compression?) for example.
Drop me a reaction or comment if this has helped you.
Thanks for reading!
Top comments (9)
Hello :)
For info about Remark-react :
🚨 Stability: Legacy. This package is no longer recommended for use. It’s still covered by semantic-versioning guarantees and not yet deprecated, but use of this package should be avoided. Please use remark-rehype to move from remark (markdown) to rehype (HTML) and then replace remark-react with rehype-react.
Dude I can't thank you enough for this article and the attached repo.
My guesstimate is that you saved me 20 hours at least... especially using the CustomLink method.
Cheers
Buzzing that the article helped, thanks!
Man, this helped a ton !!!
Been scurrying around for last few hours just to figure this out.
On point solution, thanks !!!
Thank you!
Hey James, could you help me out with syntax highlighting with remark markdown.
It is failing to highlight the code.
Hi Sanjib, did you add the CSS stylesheet to your
_app.js
?github.com/james-wallis/wallis.dev...
Hey James, I tried that as well.
I followed up your recent blog update. Could see you've dropped remark-to-react.
Any way to workaround it ? That external link target config was quite easy with that library.
Here's my repo: github.com/sanjibdey104/webdevref/...
Would be great if you can check the code once.
(on the main branch I've user react-markdown and react-syntax-highlighter, though there's one small glitch - nothing breaking)
Hi, oh yeah sorry. I can't remember getting syntax highlighting working with React Remark, can't even recall trying.
I'd check that the CSS classnames are being added on the client side, that'll narrow down whether it's the CSS that isn't working or the converter. Do you want to send me a link to your site with some content that should be highlighted?