diff --git a/docs/community/sponsor.server.mdx b/docs/community/sponsor.server.mdx
index 78e3fefb8..643c592b5 100644
--- a/docs/community/sponsor.server.mdx
+++ b/docs/community/sponsor.server.mdx
@@ -4,7 +4,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2022-01-25')
+ modified: new Date('2022-02-01')
}
# Sponsor
diff --git a/docs/community/support.server.mdx b/docs/community/support.server.mdx
index 4cce1e2bb..ba4c9b814 100644
--- a/docs/community/support.server.mdx
+++ b/docs/community/support.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2019-07-03'),
- modified: new Date('2022-01-25')
+ modified: new Date('2022-02-01')
}
# Support
diff --git a/docs/docs/extending-mdx.server.mdx b/docs/docs/extending-mdx.server.mdx
index f53b664d3..9a0394d9b 100644
--- a/docs/docs/extending-mdx.server.mdx
+++ b/docs/docs/extending-mdx.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2023-01-18')
+ modified: new Date('2023-01-19')
}
# Extending MDX
diff --git a/docs/docs/getting-started.server.mdx b/docs/docs/getting-started.server.mdx
index e2e22a3c3..1d7fc273d 100644
--- a/docs/docs/getting-started.server.mdx
+++ b/docs/docs/getting-started.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-05'),
- modified: new Date('2022-06-17')
+ modified: new Date('2022-12-14')
}
# Getting started
@@ -193,7 +193,7 @@ You can also import several types about the API of MDX files from `@types/mdx`.
For example:
```js path="example.ts"
-import type {MDXComponents} from 'mdx/types'
+import type {MDXComponents} from 'mdx/types.js'
```
### Security
@@ -514,33 +514,42 @@ Which in turn lets us choose whether to use the `@mdx-js/mdx` or
#### Astro
-[Astro](https://astro.build/) has an [official MDX integration](https://docs.astro.build/guides/integrations-guide/mdx/).
+[Astro](https://astro.build/) has their own MDX integration.
You can add the integration with the Astro CLI (recommended):
```sh
npx astro add mdx
```
-This base setup allows you to import markdown, Astro components,
-and other MDX files as components. To use
-other UI framework components in your MDX files
-(e.g. Preact, Vue, Svelte and more),
-see Astro’s [Framework components](https://docs.astro.build/en/core-concepts/framework-components/) guide.
+This base setup allows you to import markdown, Astro components, and other MDX
+files as components.
+To use components from frameworks in your MDX files, see Astro’s
+[Framework components](https://docs.astro.build/core-concepts/framework-components/)
+guide.
-To learn how to configure layouts, YAML frontmatter, and set up Astro’s
-syntax highlighting, [see their MDX
+For more on how to combine Astro and MDX, see [their MDX
integration docs](https://docs.astro.build/guides/integrations-guide/mdx/).
#### Create React App (CRA)
- **Note**: rewiring with CRACO (see below) is currently required for CRA 5,
- due to a bug in `react-scripts`
+ **Note**: it’s currently probably not a good idea to use CRA.
+
+
+
+ **Note**: rewiring with CRACO is currently required for CRA 5, due to a bug
+ in `react-scripts`
([`facebook/create-react-app#12166`](https://github.com/facebook/create-react-app/issues/12166)),
which is also tracked at
[`mdx-js/mdx#1870`](https://github.com/mdx-js/mdx/discussions/1870).
+
+ **Note**: warnings about CRACO having
+ `incorrect peer dependency "react-scripts@^4.0.0"`
+ can currently be ignored.
+
+
Expand example
@@ -560,11 +569,6 @@ integration docs](https://docs.astro.build/guides/integrations-guide/mdx/).
```
-[CRA](https://github.com/facebook/create-react-app) supports webpack loaders
-through webpack loader syntax in imports.
-
-Install the webpack loader [`@mdx-js/loader`][mdx-loader].
-
Expand CRACO example
@@ -593,16 +597,15 @@ Install the webpack loader [`@mdx-js/loader`][mdx-loader].
```
+[CRA](https://github.com/facebook/create-react-app) supports webpack loaders
+through webpack loader syntax in imports.
+
+Install the webpack loader [`@mdx-js/loader`][mdx-loader].
+
For importing MDX without the `!@mdx-js/loader!` prefix, you can add
the loader to the webpack config, by rewiring `react-scripts` using
[CRACO](http://github.com/gsoft-inc/craco).
-
- **Note**: warnings about CRACO having
- `incorrect peer dependency "react-scripts@^4.0.0"`
- can be ignored for the above to work.
-
-
See also [¶ Webpack][webpack], which is used in CRA, and see [¶ React][react],
which you’re likely using, for more info.
@@ -624,15 +627,15 @@ on how to use MDX with Gatsby.
Expand example
```js path="next.config.js"
- import nextMDX from '@next/mdx'
+ import nextMdx from '@next/mdx'
- const withMDX = nextMDX({
+ const withMdx = nextMdx({
// By default only the .mdx extension is supported.
extension: /\.mdx?$/,
options: {/* providerImportSource: …, otherOptions… */}
})
- export default withMDX({
+ export default withMdx({
// Support MDX files as pages:
pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],
})
@@ -649,18 +652,18 @@ In order to use it, you need to configure the `providerImportSource` as
well.
- Expand example
+ Expand provider example
```js path="next.config.js"
- import nextMDX from '@next/mdx'
+ import nextMdx from '@next/mdx'
- const withMDX = nextMDX({
+ const withMdx = nextMdx({
// By default only the .mdx extension is supported.
extension: /\.mdx?$/,
options: {providerImportSource: '@mdx-js/react', /* otherOptions… */}
})
- export default withMDX({
+ export default withMdx({
// Support MDX files as pages:
pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],
})
diff --git a/docs/docs/troubleshooting-mdx.server.mdx b/docs/docs/troubleshooting-mdx.server.mdx
index 7c5c0803b..68dd4e3da 100644
--- a/docs/docs/troubleshooting-mdx.server.mdx
+++ b/docs/docs/troubleshooting-mdx.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-18'),
- modified: new Date('2021-11-01')
+ modified: new Date('2022-02-01')
}
{/* lint disable maximum-heading-length */}
diff --git a/docs/docs/using-mdx.server.mdx b/docs/docs/using-mdx.server.mdx
index 5deb563cf..2488dd6e7 100644
--- a/docs/docs/using-mdx.server.mdx
+++ b/docs/docs/using-mdx.server.mdx
@@ -112,7 +112,8 @@ import React from 'react'
import ReactDom from 'react-dom'
import Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.
-ReactDom.render(, document.querySelector('#root'))
+const root = ReactDom.createRoot(document.getElementById('root'))
+root.render()
```
The main content is exported as the default export.
@@ -290,7 +291,9 @@ precedence).
## MDX provider
+You probably don’t need a provider.
Passing components is typically fine.
+Providers often only add extra weight.
Take for example this file:
```mdx path="post.mdx"
@@ -311,12 +314,12 @@ const components = {
table: Table
}
-ReactDom.render(
- ,
- document.querySelector('#root')
-)
+const root = ReactDom.createRoot(document.getElementById('root'))
+root.render()
```
+That works, those components are used.
+
But when you’re nesting MDX files (importing them into each other) it can become
cumbersome.
Like so:
@@ -363,13 +366,13 @@ Set it up like so:
table: Table
}
- ReactDom.render(
-- ,
+ const root = ReactDom.createRoot(document.getElementById('root'))
+-root.render()
++root.render(
+
+
-+ ,
- document.querySelector('#root')
- )
++
++)
```
Now you can remove the explicit and verbose component passing:
@@ -423,6 +426,9 @@ In this example the current context components are discarded:
…which results in `h2`s using `Component3` and `h3`s using `Component4`.
No component is used for `h1`.
+If you’re not nesting MDX files, or not nesting them often, don’t use
+providers: pass components explicitly.
+
[context]: https://reactjs.org/docs/context.html
[start]: /docs/getting-started/
diff --git a/docs/docs/what-is-mdx.server.mdx b/docs/docs/what-is-mdx.server.mdx
index a5e0f76aa..c17f46555 100644
--- a/docs/docs/what-is-mdx.server.mdx
+++ b/docs/docs/what-is-mdx.server.mdx
@@ -6,7 +6,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2018-08-11'),
- modified: new Date('2021-11-01')
+ modified: new Date('2023-01-06')
}
# What is MDX?
diff --git a/docs/guides/frontmatter.server.mdx b/docs/guides/frontmatter.server.mdx
index 6c7acb593..6cfb34e75 100644
--- a/docs/guides/frontmatter.server.mdx
+++ b/docs/guides/frontmatter.server.mdx
@@ -4,7 +4,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2022-06-17')
+ modified: new Date('2022-12-14')
}
# Frontmatter
diff --git a/docs/guides/gfm.server.mdx b/docs/guides/gfm.server.mdx
index 1efa6df09..ab169c0cb 100644
--- a/docs/guides/gfm.server.mdx
+++ b/docs/guides/gfm.server.mdx
@@ -4,7 +4,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2022-06-17')
+ modified: new Date('2022-12-14')
}
# GitHub flavored markdown (GFM)
diff --git a/docs/guides/math.server.mdx b/docs/guides/math.server.mdx
index 440389582..df827db89 100644
--- a/docs/guides/math.server.mdx
+++ b/docs/guides/math.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2022-06-17')
+ modified: new Date('2022-12-14')
}
# Math
diff --git a/docs/guides/mdx-on-demand.server.mdx b/docs/guides/mdx-on-demand.server.mdx
index 8749a2ad4..57e2be2b5 100644
--- a/docs/guides/mdx-on-demand.server.mdx
+++ b/docs/guides/mdx-on-demand.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-11-13'),
- modified: new Date('2021-11-13')
+ modified: new Date('2021-11-14')
}
# MDX on demand
@@ -28,7 +28,14 @@ On the server:
```js path="server.js"
import {compile} from '@mdx-js/mdx'
-const code = String(await compile('# hi', {outputFormat: 'function-body' /* …otherOptions */ }))
+const code = String(await compile('# hi', {
+ outputFormat: 'function-body',
+ development: false
+ // ^-- Generate code for production.
+ // `false` if you use `/jsx-runtime` on client, `true` if you use
+ // `/jsx-dev-runtime`.
+ /* …otherOptions */
+}))
// To do: send `code` to the client somehow.
```
@@ -36,7 +43,8 @@ On the client:
```js path="client.js"
import {run} from '@mdx-js/mdx'
-import * as runtime from 'react/jsx-runtime'
+import * as runtime from 'react/jsx-runtime' // Production.
+// import * as runtime from 'react/jsx-dev-runtime' // Development.
const code = '' // To do: get `code` from server somehow.
@@ -64,7 +72,8 @@ Next.
```js path="pages/hello.js"
import {useState, useEffect, Fragment} from 'react'
-import * as runtime from 'react/jsx-runtime'
+import * as runtime from 'react/jsx-runtime' // Production.
+// import * as runtime from 'react/jsx-dev-runtime' // Development.
import {compile, run} from '@mdx-js/mdx'
export default function Page({code}) {
@@ -82,7 +91,14 @@ export default function Page({code}) {
export async function getStaticProps() {
const code = String(
- await compile('# hi', {outputFormat: 'function-body' /* …otherOptions */})
+ await compile('# hi', {
+ outputFormat: 'function-body',
+ development: false,
+ // ^-- Generate code for production.
+ // `false` if you use `/jsx-runtime` on client, `true` if you use
+ // `/jsx-dev-runtime`.
+ /* …otherOptions */
+ })
)
return {props: {code}}
}
diff --git a/docs/guides/syntax-highlighting.server.mdx b/docs/guides/syntax-highlighting.server.mdx
index 7e13f3189..cc774d008 100644
--- a/docs/guides/syntax-highlighting.server.mdx
+++ b/docs/guides/syntax-highlighting.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
],
published: new Date('2021-10-06'),
- modified: new Date('2022-06-17')
+ modified: new Date('2022-08-27')
}
# Syntax highlighting
diff --git a/docs/migrating/v1.server.mdx b/docs/migrating/v1.server.mdx
index 37edac30d..95cdbcbf0 100644
--- a/docs/migrating/v1.server.mdx
+++ b/docs/migrating/v1.server.mdx
@@ -5,7 +5,7 @@ export const info = {
{name: 'John Otander', github: 'johno', twitter: '4lpine'}
],
published: new Date('2019-04-04'),
- modified: new Date('2021-11-01')
+ modified: new Date('2021-10-17')
}
diff --git a/docs/migrating/v2.server.mdx b/docs/migrating/v2.server.mdx
index 87f262a82..29cf70319 100644
--- a/docs/migrating/v2.server.mdx
+++ b/docs/migrating/v2.server.mdx
@@ -387,7 +387,7 @@ You can update your code as follows:
const components = {/* … */}
const value = '# hi'
- const {default: Content} = await evaluate(value, {...provider, ...runtime})
+ const {default: Content} = await evaluate(value, {...provider, ...runtime, development: false})
export default () => (
diff --git a/packages/mdx/readme.md b/packages/mdx/readme.md
index 9ef3b7819..23d98d4be 100644
--- a/packages/mdx/readme.md
+++ b/packages/mdx/readme.md
@@ -130,7 +130,7 @@ MDX document to parse (`string`, [`Buffer`][buffer] in UTF-8, [`vfile`][vfile],
or anything that can be given to `vfile`).
-Example
+Expand example
```js
import {VFile} from 'vfile'
@@ -149,7 +149,7 @@ await compile(new VFile({path: 'path/to/file.mdx', value: '🤭'}))
List of [remark plugins][remark-plugins], presets, and pairs.
-Example
+Expand example
```js
import remarkFrontmatter from 'remark-frontmatter' // YAML and such.
@@ -168,7 +168,7 @@ await compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFr
List of [rehype plugins][rehype-plugins], presets, and pairs.
-Example
+Expand example
```js
import rehypeKatex from 'rehype-katex' // Render math with KaTeX.
@@ -200,7 +200,7 @@ In particular, you might want to pass `clobberPrefix`, `footnoteLabel`, and
`footnoteBackLabel`.
-Example
+Expand example
```js
compile({value: '…'}, {remarkRehypeOptions: {clobberPrefix: 'comment-1'}})
@@ -233,7 +233,7 @@ The format cannot be detected if a file is passed without a path or extension:
So pass a full vfile (with `path`) or an object with a path.
-Example
+Expand example
```js
compile({value: '…'}) // Seen as MDX
@@ -256,7 +256,7 @@ because in those it affects *which* files are “registered”:
###### `options.outputFormat`
-Output format to generate (`'program' | 'function-body'`, default: `'program'`).
+Output format to generate (`'function-body' | 'program'`, default: `'program'`).
In most cases `'program'` should be used, as it results in a whole program.
Internally, [`evaluate`][eval] uses `outputFormat: 'function-body'` to compile
to code that can be `eval`ed with [`run`][run].
@@ -275,7 +275,7 @@ statements, but you can support them by setting
[`options.useDynamicImport`][usedynamicimport].
-Example
+Expand example
A module `example.js`:
@@ -322,7 +322,7 @@ JavaScript modules, whereas `import()` is available inside function bodies.
When you turn `useDynamicImport` on, you should probably set [`options.baseUrl`][baseurl] too.
-Example
+Expand example
Say we have a couple modules:
@@ -371,7 +371,7 @@ imports should run relative the path *b*.
Another example is when evaluating code, whether in Node or a browser.
-Example
+Expand example
Say we have a module `example.js`:
@@ -406,7 +406,7 @@ The default can be set to `true` in Node.js through environment variables: set
`NODE_ENV=development`.
-Example
+Expand example
Say we had some MDX that references a component that can be passed or provided
at runtime:
@@ -476,7 +476,7 @@ When given, the resulting file will have a `map` field set to a source map (in
object form).
-Example
+Expand example
Assuming `example.mdx` from [§ Use][use] exists, then:
@@ -515,7 +515,7 @@ The provider must export a `useMDXComponents`, which is called to access an
object of components.
-Example
+Expand example
If `file` is the contents of `example.mdx` from [§ Use][use], then:
@@ -556,7 +556,7 @@ The default is to compile JSX away so that the resulting file is immediately
runnable.
-Example
+Expand example
If `file` is the contents of `example.mdx` from [§ Use][use], then:
@@ -598,7 +598,7 @@ The classic runtime compiles to calls such as `h('p')`, the automatic runtime
compiles to `import _jsx from '$importSource/jsx-runtime'\n_jsx('p')`.
-Example
+Expand example
If `file` is the contents of `example.mdx` from [§ Use][use], then:
@@ -625,10 +625,10 @@ compile(file, {jsxRuntime: 'classic'})
Place to import automatic JSX runtimes from (`string?`, default: `'react'`).
When in the `automatic` runtime, this is used to define an import for
-`_Fragment`, `_jsx`, and `_jsxs`.
+`Fragment`, `jsx`, `jsxs`, and `jsxDEV`.
-Example
+Expand example
If `file` is the contents of `example.mdx` from [§ Use][use], then:
@@ -657,7 +657,7 @@ You should most probably define `pragmaFrag` and `pragmaImportSource` too when
changing this.
-Example
+Expand example
If `file` is the contents of `example.mdx` from [§ Use][use], then:
@@ -707,7 +707,7 @@ See `options.pragma` for an example.
`Promise` — Promise that resolves to the compiled JS as a [vfile][].
-Example
+Expand example
```js
import remarkPresetLintConsistent from 'remark-preset-lint-consistent' // Lint rules to check for consistent markdown.
@@ -749,6 +749,8 @@ Typically, `import` (or `export … from`) do not work here.
They can be compiled to dynamic `import()` by passing
[`options.useDynamicImport`][usedynamicimport].
+> ☢️ **Danger**: you likely must set `development: boolean`.
+
###### `file`
See [`compile`][compile].
@@ -759,25 +761,33 @@ Most options are the same as [`compile`][compile], with the following
exceptions:
* `providerImportSource` is replaced by `useMDXComponents`
-* `jsx*` and `pragma*` options are replaced by `jsx`, `jsxs`, and `Fragment`
+* `jsx*` and `pragma*` options are replaced by `Fragment`, `jsx`, `jsxs`, and
+ `jsxDEV`
* `outputFormat` is set to `function-body`
###### `options.jsx`
###### `options.jsxs`
+###### `options.jsxDEV`
+
###### `options.Fragment`
-These three options are required.
+These options are required: `Fragment` always, when `development: true`
+then `jsx` and `jsxs`, when `development: false` then `jsxDEV`.
They come from an automatic JSX runtime that you must import yourself.
-Example
+Expand example
```js
import * as runtime from 'react/jsx-runtime'
-const {default: Content} = await evaluate('# hi', {...runtime, ...otherOptions})
+const {default: Content} = await evaluate('# hi', {
+ ...runtime,
+ ...otherOptions,
+ development: false
+})
```
@@ -787,25 +797,30 @@ const {default: Content} = await evaluate('# hi', {...runtime, ...otherOptions})
Needed if you want to support a provider.
-Example
+Expand example
```js
import * as provider from '@mdx-js/react'
import * as runtime from 'react/jsx-runtime'
-const {default: Content} = await evaluate('# hi', {...provider, ...runtime, ...otherOptions})
+const {default: Content} = await evaluate('# hi', {
+ ...provider,
+ ...runtime,
+ ...otherOptions,
+ development: false
+})
```
###### Returns
-`Promise` — Promise that resolves to something that looks a bit like
+`Promise` — Promise that resolves to something that looks a bit like
a module: an object with a `default` field set to the component and anything
else that was exported from the MDX file available too.
-Example
+Expand example
Assuming the contents of `example.mdx` from [§ Use][use] was in `file`, then:
@@ -813,7 +828,7 @@ Assuming the contents of `example.mdx` from [§ Use][use] was in `file`, then:
import * as runtime from 'react/jsx-runtime'
import {evaluate} from '@mdx-js/mdx'
-console.log(await evaluate(file, {...runtime}))
+console.log(await evaluate(file, {...runtime, development: false}))
```
…yields:
@@ -856,8 +871,8 @@ Run MDX compiled as [`options.outputFormat: 'function-body'`][outputformat].
###### `options`
-You can pass `jsx`, `jsxs`, and `Fragment` from an automatic JSX runtime as
-`options`.
+You can pass `Fragment`, `jsx`, `jsxs`, and `jsxDEV`, from an automatic JSX
+runtime as `options`.
You can also pass `useMDXComponents` from a provider in options if the MDX is
compiled with `options.providerImportSource: '#'` (the exact value of this
compile option doesn’t matter).
@@ -868,14 +883,17 @@ All other options have to be passed to `compile` instead.
`Promise` — See `evaluate`
-Example
+Expand example
On the server:
```js
import {compile} from '@mdx-js/mdx'
-const code = String(await compile('# hi', {outputFormat: 'function-body'}))
+const code = String(await compile('# hi', {
+ outputFormat: 'function-body',
+ development: false
+}))
// To do: send `code` to the client somehow.
```
@@ -934,15 +952,15 @@ what unified does: please read through the [`unifiedjs/unified`][unified] readme
know about unified: [`core.js#L65`][core].
The processor goes through these steps:
-1. Parse MDX (serialized markdown with embedded JSX, ESM, and expressions)
+1. parse MDX (serialized markdown with embedded JSX, ESM, and expressions)
to mdast (markdown syntax tree)
-2. Transform through remark (markdown ecosystem)
-3. Transform mdast to hast (HTML syntax tree)
-4. Transform through rehype (HTML ecosystem)
-5. Transform hast to esast (JS syntax tree)
-6. Do the work needed to get a component
-7. Transform through recma (JS ecosystem)
-8. Serialize esast as JavaScript
+2. transform through remark (markdown ecosystem)
+3. transform mdast to hast (HTML syntax tree)
+4. transform through rehype (HTML ecosystem)
+5. transform hast to esast (JS syntax tree)
+6. do the work needed to get a component
+7. transform through recma (JS ecosystem)
+8. serialize esast as JavaScript
The *input* is MDX (serialized markdown with embedded JSX, ESM, and
expressions).