Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Add Line Numbers to Prismjs Syntax Highlighting Code Blocks in a Next.js project

### NOTE - This may not be the best way to do this

I'm having problems with line highlighting with errors like:

Code

Warning: Prop `className` did not match. Server: "line-numbers language-jsx" Client: "line-numbers"

I'm now looking at this:

https://github.com/FormidableLabs/prism-react-renderer

(_An important note I often forget is that addind

In the spirit of sharing so others don't have to hack around like I did, here's how to do it:

## 1. The Install

Assuming you already have your Next.js project setup and ready, install Prism with:

Code

npm install prismjs

## 2. The Full Code Example

Next up, the code. Here's a fully functional example you can use in a file (e.g. 'pages/prism-example.js'). It includes a theme (okaidia), a language (jsx), and line numbering. (Details further below.)

Code

import { useEffect } from 'react'

import Prism from 'prismjs'

import 'prismjs/themes/prism-okaidia.css'
import 'prismjs/components/prism-jsx.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'

export default function Page() {
  useEffect(() => {
    Prism.highlightAll()
  }, [])

  const codeSample = `<div className="example">
  {Math.random()}
</div>`

  return (
    <main>
      <pre className="line-numbers">
        <code className="language-jsx">{codeSample}</code>
      </pre>
    </main>
  )
}

Using that will output a highlighted and numbered code snippet that looks like this.

## 3. The Details

Here's how it all works:

Prism is made available with:

Code

import Prism from 'prismjs'

The theme comes from:

Code

import 'prismjs/themes/prism-okaidia.css'

This is one of the default themes Prism ships with. The others are located in the project's 'node_modules/prismjs/themes' directory. They are:

Switch out the `import` call to point to whichever one you prefer.

There are also ways to make and use custom themes as well. That's left as an exercise for the reader.

Be default, Prism loads syntax highlighting for "markup, css, clike, and javascript". Other languages need to be imported explicitly. In the example, I'm adding JSX with:

Code

import 'prismjs/components/prism-jsx.js'

This is what lets us call the

(Look in your project's 'node_modules/prismjs/components' directory for all the available languages.)

Prepping to use the line numbers is done with these two import statements:

Code

import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'

There's a bunch of other plugins available in the project's 'node_modules/prismjs/plugins' like

Actually getting Prism to do its thing is done with

Code

useEffect(() => {
    Prism.highlightAll()
}, [])

The last two parts that turn on the line numbers and set the language go hand in hand. They're done with

Code

<pre className="line-numbers">
    <code className="language-jsx">{codeSample}</code>
</pre>
<MDXRemote
  {...source}
  components={{
    pre: (props) => (
      <pre className="line-numbers">{props.children}</pre>
    ),
  }}
/>
import { useEffect } from 'react'

import Prism from 'prismjs'

import 'prismjs/themes/prism-okaidia.css'
import 'prismjs/components/prism-jsx.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.js'
import 'prismjs/plugins/line-numbers/prism-line-numbers.css'

export default function Page() {
  useEffect(() => {
    Prism.highlightAll()
  }, [])

  const codeSample = `<div className="example">
  {Math.random()}
</div>`

  return (
    <main>
      <pre className="line-numbers">
        <code className="language-jsx">{codeSample}</code>
      </pre>
    </main>
  )
}