Next.js and Prism.js integration

How to use Prism.js in Next.js application

There is exist an issue if you want to use Prism.js in your Next.js application like:

Warning: Prop 'dangerouslySetInnerHTML' did not match. Server: ... Client: ...

So, the solution is to preprocess the code in the component:

// Returns a highlighted HTML string.
const highlightedCode = Prism.highlight(code, Prism.language['php'], 'php');

The prismjs component:

npm install prismjs

And final the solution looks like this:

import Prism from 'prismjs';
// Import the theme style.
import 'prismjs/themes/prism-tomorrow.min.css'

const Code = ({ content, lang }) => {
  require('prismjs/plugins/line-numbers/prism-line-numbers')
  require('prismjs/components/prism-markup-templating')
  require(`prismjs/components/prism-${lang}`)
  // But, there are a few exceptions:
  // For "HTML" instead of 
  // require(`prismjs/components/prism-${lang}`)
  // Use this
  // require('prismjs/components/prism-markup')
  // For "PHP" add one more record like this
  // require('prismjs/components/prism-php-extras')

  const highlightedCode = Prism.highlight(code, Prism.languages.[lang], lang);

  return <div dangerouslySetInnerHTML={{__html: `<pre class="language-${lang}" tabIndex="0"><code class="language-${lang}">${highlightedCode}</code></pre>`}} />
}

export default Code;

Also, if you use babel compiler you need to add the next prism.js preferences in .babelrc like this:

{
  "plugins": [
    ["prismjs", {
      "languages": ["javascript", "css", "markup", "php", "yaml", "twig"],
      "plugins": ["line-numbers"],
      "theme": "tomorrow",
      "css": true
    }]
  ]
}

And the component code should looks like this:

import Prism from 'prismjs';
// Import the theme style.
import 'prismjs/themes/prism-tomorrow.min.css'

const Code = ({ content, lang }) => {
  const highlightedCode = Prism.highlight(code, Prism.languages.[lang], lang);

  return <div dangerouslySetInnerHTML={{__html: `<pre class="language-${lang}" tabIndex="0"><code class="language-${lang}">${highlightedCode}</code></pre>`}} />
}

export default Code;