MDX 2 Breaking changes and gatsby-plugin-mdx v4 (Content)
- Gatsby
- MDX
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.