By Titus Wormer
Extending MDX
This article explains how to extend MDX content—specifically, how to transform content with plugins. See § Using MDX for how to pass components, props, and the layout. See § Getting started for how to integrate MDX into your project.
Contents
Components & plugins
There are three extension points when using @mdx-js/mdx or one of its integrations:
- Options passed to the compiler (see ¶ API in
@mdx-js/mdx) - Plugins that hook into several stages of compilation (see remark plugins, rehype plugins, and recma plugins)
- Components passed, defined, or imported at runtime (see § Using MDX)
Most of the time, these components and plugins are not coupled to MDX. For example, if you’re using React, then you can use <ReactConfetti /> with MDX. Or, you can use the plugin remark-gfm to turn on GFM features in MDX. Sometimes, we need specific components or specific plugins to work with MDX. We’re compiling those here on this page.
List of components
mdx-embed— React components for embedding 3rd party content, integrates w/ MDX providertheme-ui— React components for building consistent apps, integrates w/ MDX provider
Note: have another component that specifically works with MDX? Please send a PR to add it here!
List of plugins
MDX-specific remark plugins
remark-directive-mdx— transform Markdown directives (:directive[]) to JSX elementsremark-mdx-chartjs— replace fenced code blocks with charts usingreact-chartjs-2.remark-mdx-frontmatter— change frontmatter (YAML) metadata to exportsremark-mdx-math-enhanced— enhance math with JavaScript inside itremark-mdx-remove-esm— remove import and/or export statements (mdxjsEsm)remark-mdx-remove-expressions— remove MDX expressions within curlybraces in MDX content
See also the list of remark plugins.
MDX-specific rehype plugins
rehype-mdx-code-props— interpret the codemetafield as JSX propsrehype-mdx-import-media— change media sources to JavaScript importsrehype-mdx-title— expose the page title as a stringrehype-mdx-toc— export the table of contents data into MDX module
See also the list of rehype plugins.
MDX-specific recma plugins
recma-export-filepath— export the filepathrecma-mdx-change-props— changes the param as_propsin the_createMdxContentfunctionrecma-mdx-displayname— add adisplayNametoMDXContentcomponents, to enable switching on them in productionrecma-mdx-escape-missing-components— set a default value of() => nullfor missing components instead of throwing an errorrecma-mdx-is-mdx-component— add anisMdxComponentfield on MDX componentsrecma-nextjs-static-props— generategetStaticPropsexposing top level identifiers in Next.jsrecma-module-to-function— convert a module into a function body
See also the list of recma plugins.
Note: have another unified plugin that specifically works with MDX? Please send a PR to add it here!
Using plugins
Where to pass plugins is encoded in their name: remark plugins go in remarkPlugins, rehype plugins go in rehypePlugins, and recma plugins go in recmaPlugins of ProcessorOptions. Those fields expect lists of plugins and/or of [plugin, options]:
import {compile} from '@mdx-js/mdx'
import rehypeKatex from 'rehype-katex' // Render math with KaTeX.
import remarkFrontmatter from 'remark-frontmatter' // YAML and such.
import remarkGfm from 'remark-gfm' // Tables, footnotes, strikethrough, task lists, literal URLs.
import remarkMath from 'remark-math' // Support math like `$so$`.
const file = '# hi'
// One plugin:
await compile(file, {remarkPlugins: [remarkGfm]})
// A plugin with options:
await compile(file, {remarkPlugins: [[remarkFrontmatter, 'toml']]})
// Two plugins:
await compile(file, {remarkPlugins: [remarkGfm, remarkFrontmatter]})
// Two plugins, first w/ options:
await compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFrontmatter]})
// remark and rehype plugins:
await compile(file, {rehypePlugins: [rehypeKatex], remarkPlugins: [remarkMath]})
// remark and rehype plugins, last w/ options:
await compile(file, {
// A plugin with options:
rehypePlugins: [[rehypeKatex, {strict: true, throwOnError: true}]],
remarkPlugins: [remarkMath]
})
(alias) function compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
(alias) function rehypeKatex(options?: Readonly<Options> | null | undefined): (tree: Root, file: VFile) => undefined
import rehypeKatexRender elements with a language-math (or math-display, math-inline) class with KaTeX.
- @param options Configuration (optional).
- @returns Transform.
(alias) function remarkFrontmatter(options?: Options | null | undefined): undefined
import remarkFrontmatterAdd support for frontmatter.
Notes
Doesn’t parse the data inside them: create your own plugin to do that.
- @param options Configuration (default:
'yaml'). - @returns Nothing.
(alias) function remarkGfm(options?: Options | null | undefined): undefined
import remarkGfmAdd support GFM (autolink literals, footnotes, strikethrough, tables, tasklists).
- @param options Configuration (optional).
- @returns Nothing.
(alias) function remarkMath(options?: Readonly<Options> | null | undefined): undefined
import remarkMathAdd support for math.
- @param options Configuration (optional).
- @returns Nothing.
const file: "# hi"(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkGfm(options?: Options | null | undefined): undefined
import remarkGfmAdd support GFM (autolink literals, footnotes, strikethrough, tables, tasklists).
- @param options Configuration (optional).
- @returns Nothing.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkFrontmatter(options?: Options | null | undefined): undefined
import remarkFrontmatterAdd support for frontmatter.
Notes
Doesn’t parse the data inside them: create your own plugin to do that.
- @param options Configuration (default:
'yaml'). - @returns Nothing.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkGfm(options?: Options | null | undefined): undefined
import remarkGfmAdd support GFM (autolink literals, footnotes, strikethrough, tables, tasklists).
- @param options Configuration (optional).
- @returns Nothing.
(alias) function remarkFrontmatter(options?: Options | null | undefined): undefined
import remarkFrontmatterAdd support for frontmatter.
Notes
Doesn’t parse the data inside them: create your own plugin to do that.
- @param options Configuration (default:
'yaml'). - @returns Nothing.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkGfm(options?: Options | null | undefined): undefined
import remarkGfmAdd support GFM (autolink literals, footnotes, strikethrough, tables, tasklists).
- @param options Configuration (optional).
- @returns Nothing.
(property) singleTilde: boolean(alias) function remarkFrontmatter(options?: Options | null | undefined): undefined
import remarkFrontmatterAdd support for frontmatter.
Notes
Doesn’t parse the data inside them: create your own plugin to do that.
- @param options Configuration (default:
'yaml'). - @returns Nothing.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) rehypePlugins?: PluggableList | null | undefinedList of rehype plugins (optional).
(alias) function rehypeKatex(options?: Readonly<Options> | null | undefined): (tree: Root, file: VFile) => undefined
import rehypeKatexRender elements with a language-math (or math-display, math-inline) class with KaTeX.
- @param options Configuration (optional).
- @returns Transform.
(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkMath(options?: Readonly<Options> | null | undefined): undefined
import remarkMathAdd support for math.
- @param options Configuration (optional).
- @returns Nothing.
(alias) compile(vfileCompatible: Readonly<Compatible>, compileOptions?: Readonly<CompileOptions> | null | undefined): Promise<VFile>
import compileCompile MDX to JS.
- @param vfileCompatible MDX document to parse.
- @param compileOptions Compile configuration (optional).
- @return Promise to compiled file.
const file: "# hi"(property) rehypePlugins?: PluggableList | null | undefinedList of rehype plugins (optional).
(alias) function rehypeKatex(options?: Readonly<Options> | null | undefined): (tree: Root, file: VFile) => undefined
import rehypeKatexRender elements with a language-math (or math-display, math-inline) class with KaTeX.
- @param options Configuration (optional).
- @returns Transform.
(property) strict: boolean(property) throwOnError: boolean(property) remarkPlugins?: PluggableList | null | undefinedList of remark plugins (optional).
(alias) function remarkMath(options?: Readonly<Options> | null | undefined): undefined
import remarkMathAdd support for math.
- @param options Configuration (optional).
- @returns Nothing.
Creating plugins
Creating a plugin for MDX is mostly the same as creating a plugin for remark, rehype, or recma. There are several guides and recipes on that in § Learn on unifiedjs.com.
For the MDX specific parts of plugins, it’s recommended to read ¶ Architecture to learn how @mdx-js/mdx works. For info on the node types that represent MDX specific features, see ¶ Syntax tree in remark-mdx and use our interactive § Playground.