import {Note} from '../_component/note.jsx'
export const info = { author: [ {github: 'wooorm', name: 'Titus Wormer', twitter: 'wooorm'} ], modified: new Date('2023-10-24'), published: new Date('2021-10-18') } export const navSortSelf = 5
{/* lint disable maximum-heading-length */}
**Note**: Had trouble with something that wasn’t explained here but should be? Please let us know. See [§ Contribute][contribute] for how to help.This article goes through several common problems and errors that might occur when using MDX. {/* more */} To understand how the MDX format works, we recommend that you start with § What is MDX. How to use our packages is documented in their readmes. To migrate to the latest MDX, see § Migrating from v1 to v2.
- Problems integrating MDX
- Problems using MDX
`options.renderer` is no longer supported
Incorrect `format: 'detect'`
Unexpected `format: 'detect'`
Missing `pragma` in classic runtime with `pragmaImportSource`
Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource`
Expected `Fragment` given to `evaluate`
Expected `jsx` given to `evaluate`
Expected `jsxs` given to `evaluate`
Unexpected missing `options.baseUrl` needed…
- Problems writing MDX
Could not parse import/exports with acorn: $error
Unexpected `$type` in code: only import/exports are supported
Unexpected end of file in expression, expected a corresponding closing brace for `{`
Unexpected lazy line in expression in container
Could not parse expression with acorn: $error
Could not parse expression with acorn: Unexpected content after expression
Unexpected extra content in spread: only a single spread is supported
Unexpected `$type` in code: only spread elements are supported
Unexpected empty expression
Unexpected end of file $at, expected $expect
Unexpected character $at, expected $expect
Unexpected closing slash `/` in tag, expected an open tag first
Unexpected lazy line in container, expected line to be…
Unexpected attribute in closing tag, expected the end of the tag
Unexpected self-closing slash `/` in closing tag, expected the end of the tag
Unexpected closing tag `</$tag>`, expected corresponding closing tag for `<$tag>` ($at)
Cannot close `$type` ($at): a different token (`$type`, $at) is open
Cannot close document, a token (`$type`, $at) is still open
If you’re having problems integrating MDX with different tools, that’s likely due to ESM: ECMAScript modules. They’ve been in the works since 2015, we’ve supported them in MDX files from the start, and in MDX version 2 we completely switched to them. Many tools support ESM already. Most other tools are working hard to support them. Some still require extra configuration.
There’s a great Gist by @sindresorhus which explains in detail how to use ESM with many different tools. If you’re having trouble with MDX, some other tool, and ESM, you’ll likely find what you’re looking for there. Please give it a thorough read. If you’re still having problems, the issue tracker of the tools you’re integrating MDX with might provide the answer.
If you’re having trouble with tools that don’t support ESM, such as Electron, one short-term solution is to use a bundler to make a CJS version.
Expand example of making a CJS bundle
With esbuild, this bundles the ESM package
@mdx-js/mdx
as CJS in vendor/mdx.js
:
npx esbuild @mdx-js/mdx --bundle --platform=node --outfile=vendor/mdx.js
Problems that occur when using MDX typically relate to the APIs of our packages and how to use them. Please see the documentation of the packages, functions, and options you are using for more info and examples.
This error is thrown by @mdx-js/loader
, our webpack
loader.
It was introduced in version 2 to help with migration.
The renderer
option allowed arbitrary text to be injected before each compiled
MDX file.
This was typically used to support frameworks other than React such as Preact.
We now have options such as jsxImportSource
for that and arbitrary JavaScript
can be added with recmaPlugins
.
Because version 2 uses an AST based approach, it is no longer feasible to
support a renderer
, so it was removed.
Please see ¶ Preact in § Getting started for how to support Preact. See ¶ Creating plugins in § Extending MDX for how to create plugins.
The full error message in MDX 2 is as follows:
Incorrect `format: 'detect'`: `createProcessor` can support either `md` or `mdx`; it does not support detecting the format
The full error message in MDX 3 is:
Unexpected `format: 'detect'`, which is not supported by `createProcessor`, expected `'mdx'` or `'md'`
This error is thrown by @mdx-js/mdx
, our core compiler.
It was introduced in version 2 when the format
option was introduced.
The format
option, when configured with 'detect'
, allows inferring whether a
file is MDX or plain markdown.
Based on that information, plugins are configured differently, and with
different options.
This is impossible with createProcessor
and unified
.
To detect the format of passed files, please either use compile
from
@mdx-js/mdx
or one of the integrations.
This error is thrown by @mdx-js/mdx
, our core compiler.
It was introduced in version 2 when the jsxRuntime
, pragma
, and
pragmaImportSource
options were introduced.
This error is thrown when jsxRuntime
is configured with 'classic'
(the
default is 'automatic'
), pragmaImportSource
is defined (the default is
'react'
), but pragma
is defined as a falsey value (the default is
React.createElement
).
If you are using the classic runtime, you have to define a pragma
.
Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource`
This is a warning. It is not an error. You can keep on using these options, but expect them to be removed in the future.
All major frameworks currently support the automatic JSX runtime. The classic runtime, from MDX perspective, comes with several potential problems.
Because of that, we strongly recommend using an automatic JSX runtime and are considering removing support for the classic JSX runtime.
These errors are thrown by @mdx-js/mdx
, our core
compiler.
They were introduced in version 2 when evaluate
(and evaluateSync
) were
introduced.
evaluate
supports React and other frameworks.
But these frameworks must support an automatic JSX runtime that exposes these
three exports.
If you’re getting this error, that means that either a) the framework does not
support the automatic JSX runtime, or b) that you’re not passing them correctly
to evaluate
.
Please see evaluate
in @mdx-js/mdx
for examples on how to pass these values.
The full error message in MDX is as follows:
Unexpected missing `options.baseUrl` needed to support `export … from`, `import`, or `import.meta.url` when generating `function-body`
This error is thrown when MDX runs that is specifically compiled with
evaluate
, or with the outputFormat: 'function-body'
option to evluate
somewhere later, and import.meta.url
, import
, or export … from
is used.
These JavaScript features depend on a particular URL to run from, which is not
available or not correct when running a function body.
To solve this, pass a baseUrl
option.
Likely set to import.meta.url
(or window.location.href
).
Problems that occur when writing MDX typically have relate to how to combine JS(X) and markdown. It’s an odd mix of two languages: markdown is whitespace sensitive and forgiving (what you type may not exactly work but it won’t crash) whereas JavaScript is whitespace insensitive and unforgiving (it does crash on typos).
Errors typically fall in these three categories:
- Not escaping
<
and{
— Escape these (\<
,\{
) if you mean them as plain text instead of JS(X) - Incorrect interleaving — See the rules in ¶ Interleaving in § What is MDX?
- Broken JavaScript — Make sure the JavaScript you write is valid
This error is thrown by our MDX parser.
It was introduced in version 2.
It occurs when the keywords import
or export
are found at the start of a
line but they are not followed by valid JavaScript.
An example is:
import 1/1
The reason for this error is that the parser is expecting a JavaScript import or export statement. If you want the word import or export, make sure it’s not at the start of a paragraph. If you do want an import or export statement, please make sure that it’s valid JavaScript.
This error is thrown by our MDX parser.
It was introduced in version 2.
It occurs when, after an import
or export
statement, more JavaScript is
found.
An example is:
export const a = 1
const b = 2
The reason for this error is that we only allow import
and export
to define
data.
If you want to define a variable or function, please export it.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there is an opening curly brace not followed by a closing brace. An example is:
a { b
The reason for this error is that the parser is expecting another curly brace.
If you just want a brace but not an expression, escape it: \{
.
If you do want an expression, please make sure to close it with a closing brace
}
.
If there is a closing brace somewhere, make sure that the braces are each on
their own lines with no text before the opening brace and no text after the
closing brace, or that there are no blank lines between the braces.
This error is thrown by our MDX parser. It was introduced in version 3. It occurs when containers with lazy lines are combined with expressions An example is:
* {1 +
2}
> {1 +
2}
The reason for this error is that the parser it likely points to a bug. Be explicit with your list items and block quotes:
* {1 +
2}
> {1 +
> 2}
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are matching curly braces that, when interpreting what’s inside them as JavaScript, results in a syntax error. An example is:
a {const b = 'c'} d
Another example:
a {!} d
The reason for this error is that the parser is expecting a JavaScript
expression.
If you just want braces instead of an expression, escape the opening: \{
.
If you do want an expression, make sure that it’s valid JavaScript and that it
is an expression.
That means statements (such as if
and else
and for
loops) do not work.
If you need complex logic, you can wrap statements and whole programs into an
IIFE, or move it out to a different file, export it from there, and import it in
MDX.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are matching curly braces that, and valid JavaScript is inside them, but there’s too much JavaScript. An example is:
a {'b' 'c'} d
The reason for this error is that the parser is expecting a single JavaScript
expression yielding one value.
If you just want braces instead of an expression, escape the opening: \{
.
If you do want an expression, make sure that it yields a single value.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when there are multiple values spread into a JSX tag. An example is:
<div {...a, ...b} />
The reason for this error is that JSX only allows spreading a single value at a time:
<div {...a} {...b} />
These errors are thrown by our MDX parser. They were introduced in version 2. They occur when something other than a spread is used in braces. An example is:
<div {values} {/* comment */} {} />
The reason for this error is that JSX only allows spreading values:
<div {...a} />
These errors are thrown by our MDX parser. They were introduced in MDX version 2. They occur when something unexpected was found in a JSX tag. Some examples are:
<
<.>
</
</.>
<a
<a?>
<a:
<a:+>
<a.
<a./>
<a b
<a b!>
<a b:
<a b:1>
<a b=
<a b=>
<a b="
<a b='
<a b={
<a/
<a/->
The reason for these errors is that JSX has a very strict grammar and expects tags to be valid. There are different solutions depending on what was expected. Please read the error message carefully as it indicates where the problem occurred and what was expected instead.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is found but there are no open tags. An example is:
</div>
The reason for this error is that only open tags can be closed. You probably forgot an opening tag somewhere.
This error is thrown by our MDX parser. It was introduced in version 3. It occurs when containers with lazy lines are combined with JSX. An example is:
* <x
y />
> <x
y />
The reason for this error is that the parser it likely points to a bug. Be explicit with your list items and block quotes:
* <x
y />
> <x
> y />
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when attributes are placed on closing tags. An example is:
<h1>Text</h1 id="text">
The reason for this error is that only open tags can have attributes. Move these attributes to the corresponding opening tag.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is also marked as self-closing. An example is:
<h1>Text</h1/>
The reason for this error is that only opening tags can be marked as
self-closing.
Remove the slash after the tag name and before >
.
This error is thrown by our MDX parser. It was introduced in version 2. It occurs when a closing tag is seen that does not match the expected opening tag. An example is:
<a>Text</b>
The reason for this error is that tags must match in JSX. You likely forgot to open or close one of the two correctly.
This error is thrown by our MDX parser. It was introduced in version 2. It typically occurs when markdown and JSX are not interleaved correctly. An example is:
> <div>
The reason for this error is that a markdown construct ends while there are still tags open. See the rules on ¶ Interleaving in § What is MDX?