Prism with Next.js

Using Prism with Next.js

Prism is a popular syntax highlighter commonly used with Markdown. This example shows how to use Prism with Next.js. Use the theme dropdown in the header to switch syntax highlighting themes.

Next.js uses getStaticPaths/getStaticProps to generate static pages. These functions are not bundled client-side, so you can write server-side code directly. For example, you can read Markdown files from the filesystem (fs) – including parsing front matter with gray-matter. For example, let's assume you have a Markdown file located at docs/my-post.js.

We can retrieve that file's contents using getDocBySlug('my-post').

// lib/docs.js

import fs from 'fs'
import { join } from 'path'
import matter from 'gray-matter'

const docsDirectory = join(process.cwd(), 'docs')

export function getDocBySlug(slug) {
  const realSlug = slug.replace(/\.md$/, '')
  const fullPath = join(docsDirectory, `${realSlug}.md`)
  const fileContents = fs.readFileSync(fullPath, 'utf8')
  const { data, content } = matter(fileContents)

  return { slug: realSlug, meta: data, content }
}

Then, we can transform the raw Markdown into HTML using remark plugins.

// lib/markdown.js

import { remark } from 'remark'
import html from 'remark-html'
import prism from 'remark-prism'

export default async function markdownToHtml(markdown) {
  const result = await remark()
    // https://github.com/sergioramos/remark-prism/issues/265
    .use(html, { sanitize: false })
    .use(prism)
    .process(markdown)
  return result.toString()
}

Passing the content returned by getDocBySlug('my-post') into markdownToHtml(content) would convert a Markdown file like this:

---
title: 'My First Post'
description: 'My very first blog post'
---

# My First Post

I **love** using [Next.js](https://nextjs.org/)

```js
const doc = getDocBySlug(params.slug)
```

into this HTML, which includes the proper elements and class names.

<h1>My First Post</h1>
<p>I <strong>love</strong> using <a href="https://nextjs.org/">Next.js</a></p>
<div class="remark-highlight">
  <pre class="language-js">
    <code>
      <span class="token keyword">const</span> doc <span class="token operator">=</span> <span class="token function">getDocBySlug</span><span class="token punctuation">(</span>params<span class="token punctuation">.</span><span class="token property-access">slug</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    </code>
  </pre>
</div>

Deploy Your Own

View the source code and deploy your own. You can add new Markdown files to docs/ and see them live instantly!

Deploy with Vercel