How To Add Syntax Highlighting To Markdown With Next.js And Rehype Prism

Learn how to add syntax highlighting to Markdown with Next.js and Rehype Prism during build time.

If you'd like to add syntax highlighting at runtime, see How to Add Syntax Highlighting to Next.js with PrismJS.

Step 1: Initialize Next.js project

npx create-next-app@latest

Step 2: Install dependencies

npm i @mapbox/rehype-prism rehype-format rehype-raw rehype-stringify remark-parse remark-rehype unified
npm i --save-dev @types/mapbox__rehype-prism

Step 3: Create a markdown helper

/lib/markdown.ts

import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeFormat from "rehype-format";
import rehypeStringify from "rehype-stringify";
import rehypeRaw from "rehype-raw";
import rehypePrism from "@mapbox/rehype-prism";

export async function parseMarkdown(content: string) {
  const processedContent = await unified()
    .use(remarkParse)
    .use(remarkRehype, { allowDangerousHtml: true })
    .use(rehypeRaw)
    .use(rehypeFormat)
    // @ts-ignore
    .use(rehypePrism)
    .use(rehypeStringify)
    .process(content);

  return processedContent.toString();
}

Step 4: Create the mock data

/posts/first-post.md

# hello world

```js
console.log("hello world");
```

```python
print("hello world")
```

Step 5: Use the markdown helper

/lib/data.ts

import fs from "fs";
import { join } from "path";
import { parseMarkdown } from "./markdown";

const postsDirectory = join(process.cwd(), "posts");

function getMarkdown() {
  const fullPath = join(postsDirectory, "first-post.md");
  const fileContents = fs.readFileSync(fullPath, "utf8");
  return fileContents;
}

export async function getHtml() {
  const markdown = getMarkdown();
  const html = await parseMarkdown(markdown);
  return html;
}

Note: The parseMarkdown function can be used with any data source. Not just mock data.

Step 6: Use the html in page

/app/page.tsx

import { getHtml } from "@/lib/data";

export default async function Home() {
  const html = await getHtml();

  return (
    <div>
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </div>
  );
}

Related Courses

Learn how to build A Markdown Powered Static Blog with NextJS App Router.