Using CodeMirror in Gatsby
Our website DevToolsDaily is implemented on Gatsby and hosted in Netlify; and it has multiple pages that use CodeMirror for in-browser coding practices.
We use it for GraphViz Playground or Markdown Editor (as well as JSON/YAML converters)
If you try to simply import CodeMirror (or most of the other code editor) they will fail because navigator
or window
or something else doesn't exist.
Gatsby website has a guide for that which mentions 3 options:
- use different library
- load from CDN using
<Helmet>
- use loadable-components
- use react-lazy
I went through all 4 options for that project, and the simplest and most elegant was "3. use loadable-components".
How we do that
We depend on the following open source libraries.
- loadable-components allows you to defer importing until the client side rendering, but you still can use it as if it was a normal component.
- react-codemirror2 is a react wrapper around CodeMirror
Usually if you need to use CodeMirror for a given language you need:
CodeMirror
itself- language mode (like
yaml
orjavascript
orhtml
)
loadable-components
doesn't have a solution for multiple imports, so they recommend to wrap multiple imports into another module and import that one via loadable-components.
Here is how we did that:
import {Controlled} from 'react-codemirror2';
import 'codemirror/mode/markdown/markdown'
export default Controlled;
Then to use it:
import 'codemirror/lib/codemirror.css';
const CodeMirror = loadable(() => import('../components/code_markdown'));
<CodeMirror
className="code-mirror"
value={this.state.source}
options={{
mode: "markdown",
theme: 'default',
lineNumbers: true
}}
onBeforeChange={(editor, data, value) => {
this.onSourceChanged(value);
}}
onChange={(editor, data, value) => {
}}
/>
This article was originally published in DevToolsDaily blog