The source code for this blog is available on GitHub

Beautify your markdown Nextjs blog with Highlightjs

Cover Image for Beautify your markdown Nextjs blog with Highlightjs
Per Sunde
Per Sunde
5 min read
Next.js, markdown, beautify code, code highlighter

Do you want your tech blog to have code highlighting features and make it look just like on Github? You too can easily get your markdown code segments color coded just like you see here on this blog. By following these simple steps you can add code beautifier / syntax highlighter to your own Nextjs markdown blog and your tech blog will look much nicer, easier to read and more professional.

This is the code before we apply the code beautifier. This function takes inn the body, or the main text, of the blog as markdown text, and returns a HTML version of the markdown text using the library react-markdown.

Just want to copy/paste a solution?

If you just want to find a solution to copy/paste, install the packages and go down to Final Result to see the end result code.

Install the Needed packages

Now we want to add the beautifier to our code. First install react-highlight

npm install react-highlight --save
npm install highlight.js
npm install react-markdown --save

Before markdown highlighting

I have a file called post-body.tsx where I put this code.

import  ReactMarkdown  from  'react-markdown'

export  default  function  PostBody({ content }) {
	return (
		<div  className="markdown-body">
			<ReactMarkdown  source={content}  />
		</div>
	)
}

Choose your CSS styling

Now you need to select a CSS styling of your choice. I chose the standard GitHub styling, but you can choose whichever style suites you the most. Import this statement in your _app.tsx or _app.js file, or change the filename to the styling of your choice:

import  '../node_modules/highlight.js/styles/github.css';

take a look at the highlight.js demo page for an easy and fast way to check out all the styling options you have: https://highlightjs.org/static/demo/

Add Code Beautifier / Highlighter

Now we can start to add the beautifier to our code. In the post-body.tsx file import the Highlight component. It is needed to wrap around the text we want to highlight, also import NextPage from the Nextjs library as it is needed by the ReactMarkdown component later on.

The new function HighlightCode wraps the input element in a Highlight component, this is needed for the last step.

import  ReactMarkdown  from  'react-markdown'
import  Highlight  from  'react-highlight';
import { NextPage } from  'next';

interface  HighlightCodeProps {
	markdown: any;
}

const  HighlightCode: NextPage<HighlightCodeProps> = ({ markdown }) => {
	return (
		<div>
			<Highlight>
				{markdown}
			</Highlight>
			<br  />
		</div>
	)
}

If you dont use TypeScript, do it like this instead

const  HighlightCode = ({ value }) => {
	return (
		<div>
			<Highlight>
				{value}
			</Highlight>
			<br  />
		</div>
	)
}

The <Hightlight /> component will parse the text and organize it into HTML elements and give each a class name that can be styled.

Now we need to modify the original function and add the new HighlightCode function we wrote to the ReactMarkdown renderer. Whenever the ReactMarkdown component identifies a "code" block in the markdown text, it calls the HighlightCode function with the text inside that markdown-block, so you can customize it however you want. You can also add any other type of markdown-blocks you want the ReactMarkdown to specially render, by adding it under code with a corresponding function, just like we did for the markdown-code block here.

export  default  function  PostBody({ content }) {
	return (
		<div  className="markdown-body">
			<ReactMarkdown  source={content}
			renderers={{
				code:  HighlightCode
			}}
		/>
		</div>
	)
}

The code parameter of renderers in requires a component with a <code> element that is inside a <pre> element to work. The <Hightlight /> component does this for us.

Final Result

Here you see the final result, if you want a quick copy / paste solution for your website.

import  ReactMarkdown  from  'react-markdown'
import  Highlight  from  'react-highlight';
import { NextPage } from  'next';

export  default  function  PostBody({ content }) {
	return (
		<div  className="markdown-body">
			<ReactMarkdown  source={content}
			renderers={{
				code:  HighlightCode
			}}
		/>
		</div>
	)
}

interface  HighlightCodeProps {
	value: any;
}

const  HighlightCode: NextPage<HighlightCodeProps> = ({ value }) => {
	return (
		<div>
			<Highlight>
				{value}
			</Highlight>
			<br  />
		</div>
	)
}

Now you should have a code beautifier. You can also create new functions that will custom render any other markdown-blocks you can think of.

Style other markdown blocks

For example here is a quick and dirty way to style your ordered or unordered lists, but this code assumes there are no subsists inside the list. You can add classes and style your lists as you wish:

export  default  function  PostBody({ content }) {
	return (
		<div  className="markdown-body max-w-5xl ">
			<ReactMarkdown  source={content}
				renderers={{
					list:  OrderedListBlock,
				}}
			/>
		</div>
	)
}

interface  ListBlockProps {
	ordered: boolean,
	children: any,
}
  
const  OrderedListBlock: NextPage<ListBlockProps> = ({ordered, children}: OrderedListBlockProps) => {
	const  list = children.map(val  => {
		return  <li>{val}</li>
	})
	  
	if (ordered) {
		return  <ol  className="markdown-ol">{list}</ol>
	} else {
		return  <ul  className="markdown-ul">{list}</ul>
	}
}

Checkout here for all the different types you can use react-markdown to style however you like: https://www.npmjs.com/package/react-markdown#node-types

If you like this blog, checkout my blog about creating your own personal website with Github Pages,

Find more blogs about tech and Nextjs here https://sunde.dev/blog