If you have tried to implement CodeMirror in a NextJS project, you may have seen an error like this everytime you refresh the page:
Instead of hoping that your user would not refresh the page or removing CodeMirror all together, you could try to fix it. Here's how.
Before starting ensure that you do have react-codemirror and codemirror installed. If not, copy and paste the following within your terminal
// if you have npm
npm i codemirror
npm i react-codemirror
//if you have yarn
yarn add codemirror
yarn add react-codemirror
Dynamic Importing
First, you need to make sure that you import react-codemirror
and your desired themes and modes using Dynamic imports. To do this, import the dynamic function from NextJS normally as you would with any other npm/yarn package.
import dynamic from 'next/dynamic'
With this function imported, you can start to dynamically import react-codemirror and it's dependencies. Keep in mind though that you have to dynamically import these outside your exported function. Create a const called CodeMirror and set it equal to the dynamic function. Inside the dynamic function, import the dependencies (e.g. import('codemirror/mode/xml/xml')
) and then return with import('react-codemirror')
. After you have imported all of these, add an object within the function declaring ssr: false
. In the end, it should look something like this:
const CodeMirror = dynamic(() => {
import('codemirror/mode/xml/xml')
import('codemirror/mode/javascript/javascript')
import('codemirror/mode/css/css')
import('codemirror/mode/markdown/markdown')
import('codemirror/theme/material-ocean.css')
return import('react-codemirror')
}, {ssr: false})
Rendering
To include the CodeMirror element within your page/component, you first need to enclose it within brackets. After that, you can include everything else such as the value, options, and the onChange event. E.G.:
{<CodeMirror
className="editor"
value={devLog}
name= "Devlog"
options={{
theme: 'mdn-like',
lineNumbers: true,
mode: 'markdown'
}}
onChange={devLog => setDevLog(devLog)}
/>}
To ensure that it everything looks right and works the way you expect it to work (not having the textarea and editor being in two separate places or a bunch of x's), you should include the following in your _app.js file
import 'codemirror/lib/codemirror.css'
In the end, you and your users should be able to write code or write a markdown blog using CodeMirror without having to worry about refreshing the page only to see an error.
Top comments (1)
Thank you very much for this solution! I think there is something missing: the imports return promises and the function passed to dynamic should make sure the final promise importing react-codemirror doesn't resolve before the other promises do. When I used you code as is, I could sometimes observe inconsistencies (theme not applied, addon not available). The simplest solution is to make the function async, and await each imports.