Codemirror with NextJS using Dynamic Import

Codemirror is a library used to style the code of web applications. It supports various languages with different styling and themes. But it can get a little tricky when working with server-side rendering and NextJS. The most common error I got was `ReferenceError: navigator is not defined`. This is because navigator is a browser API and is not available on server-side rendering. To solve this problem NextJS has an alternate solution of dynamically importing the library.

Dynamic Import

0heading

Unlike static import, dynamic import can be placed anywhere in the code. It loads the module and returns a promise that resolves into a module object that contains all its exports. Dynamic import in NextJS can be used in three ways - 1. With named exports, 2. With custom loading component and 3. No SSR.

1paragraph

2paragraph
//codeFormat.jsx import React from 'react' import { Controlled as CodeMirror } from 'react-codemirror2' const CodeFormat = ({data}) => { return (<CodeMirror //onChange={code => setCode(code)} value={data} options={{ mode: 'python', theme: 'material', lineNumbers: true, readOnly: true, //lineWrapping: true, viewportMargin: Infinity } } />) }; export default CodeFormat;
3code
//style.jsx import dynamic from 'next/dynamic'; const CodeFormat = dynamic(() => { import('codemirror/mode/python/python') import('codemirror/theme/material.css') return import('./codeFormat') }, { ssr: false }) export default function style() { value = 'def welcome():\n\tprint("hello world")' return <div> <CodeFormat data={value} /></div>; }
4code
.CodeMirror { border: 1px solid #eee; height: auto; }
5code

This would showcase as following

7paragraph
def welcome(): print("hello world")
8code

Codemirror is used in the CodeFormat function which is default exported. In the style.jsx file we import codeFormat dynamically. Since we also want to use themes for javascript language we load javascript mode. The actual content is set with the value option. The mode option is for the language of the content. In case you want to set the height codemirror according to your content you can set viewportMargin to Infinity and setting the height to auto in CSS for class Codemirror.

9paragraph

Because this is not rendered on the server-side, SEO might not be able to read the data. In that case, we code showcase it in <code> tag and then hide that element once codemirror is rendered.

10paragraph