MDX 2 Breaking changes and gatsby-plugin-mdx v4 (Content)
If youâre upgrading to v4 of gatsby-plugin-mdx youâll likely run into errors. Both MDX 2 and v4 of the plugin are major releases and inline with semantic versioning guidelines, breaking changes are to be expected.
Both Gatsby and MDX have documented the changes and you can find more information about the changes on the following links.
Breaking Changes to Content
In this post Iâll only be covering the changes to content that youâll need to make. Stay tuned for a full migration post, itâs on its way!
The Misleading Error
If youâve gone ahead and upgraded the plugin to v4 and started your development server, youâll probably see an error like this.
ERROR
Module build failed (from ./node_modules/gatsby/dist/utils/babel-loader.js):
SyntaxError: /Users/paulscanlon/tests/gatsby-mdx-2-breaking-content-changes/content/posts/2022/01/post-one.mdx:
Invalid left-hand side in prefix operation. (1:2)
> 1 | ---
| ^
2 | title: This is post one
3 | ---
This is slightly misleading. Whilst MDX does indeed surface the file that contains the error, E.g: post-one.mdx
, it
points to the frontmatter, this isnât the actual error.
The Actual Error
The actual error will likely be somewhere in your content. Both the docs linked above explain that MDX will error if
any, left angle brackets "<"
, or left curly braces "{"
are found that are either, unescaped or used without
expressions.
â < left angle bracket unescaped
â
\< left angle bracket escaped
â
"<" left angle bracket with expressions
â { left curly brace unescaped
â
\{ left curly brace escaped
â
"{" left curly brace with expressions
Finding The Characters
Finding the above characters can be a little tricky though. Depending on the size of your project, the length of your
blog posts, and where in your file system youâve saved your .mdx
files, can all make the job of finding and replacing
these characters quite bothersome. Hereâs two approaches you might find helpful.
VS Code Search
Basic Search
It might be tempting to reach for VS Codeâs built in search, however, youâll notice in the diagram below that when I
search for "<"
or "{"
(position 1, and 2), the search matches all instances of both these characters.
This isnât that helpful since the search will match legitimate uses for these characters (position 2, and 3). You may
also notice this basic search matches characters in all file types, not just characters found in .mdx
files.
Advanced Search
You may have never noticed this, I hadnât, but, to the right of the search thereâs a little file icon with a + next to it (position 1), this opens up what Iâll be referring to as Advanced Search.
You can still enter a character to match (position 2) and iâve also added "*.md, mdx"
to the âfiles to includeâ
input (position 3). This helps with getting more specific about where youâre searching.
The Advanced Search view provides a little more context about which files the matches are in, and on what line they occur (position 4).
Iâve found this easier to read and pick out the characters that will need changes, moreover, you can edit the files right there in the search results.
eslint-mdx
ESLint Parser/Plugin for MDX, helps you lint all ES syntaxes
This approach is less visual but itâs a good way to double, double check youâve caught all the changes before starting your development server again.
Install Dependencies
The eslint-mdx install guide doesnât mention youâll also need to install eslint FYI.
npm install es-lint eslint-plugin-mdx --save-dev
.eslintrc
Create a new file at the root of your project called .eslintrc
and add the following code. I lifted this straight from
the usage example in the repository README.
// .eslintrc
{
"extends": ["plugin:mdx/recommended"],
// optional, if you want to lint code blocks at the same time
"settings": {
"mdx/code-blocks": true,
// optional, if you want to disable language mapper, set it to `false`
// if you want to override the default language mapper inside, you can provide your own
"mdx/language-mapper": {}
}
}
scripts
Now add the following script to your package.json
.
// package.json
"scripts": {
...
"lint": "eslint . --ext md,mdx"
}
lint
With both the .eslintrc
file created and the lint
script added to package.json
you can run the following in your
terminal
npm run lint
This should produce an error which you can use to find the problem character in the problem file. The error tells you which line the error occurred but itâs not always overly clear which character caused the error.
One other thing to note about this approach. eslint exits after the first error so you wonât get to see all errors, only one error at a time.
/Users/paulscanlon/tests/gatsby-mdx-2-breaking-content-changes/content/posts/2022/01/post-one.mdx
17:12 error Parsing error: Could not parse expression with acorn: Expecting Unicode escape sequence \uXXXX
â 1 problem (1 error, 0 warnings)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
And thatâs it. Iâve used both of these approaches to upgrade a few sites now and whilst breaking changes of this nature can be quite frustrating, once you get into a groove itâs not so bad.
If you have anu further suggestions for ways to find problem characters please leave a comment below.
Thanks!
Further Reading
Here are the links from both MDX and Gatsby again which detail all the breaking changes.