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
PaulieScanlon/mdx-embed— React components for embedding 3rd party content, integrates w/ MDX providersystem-ui/theme-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
See also the list of remark plugins, list of rehype plugins, and list of recma plugins.
remcohaszing/recma-export-filepath— export the filepathipikuka/recma-mdx-change-props— changes the param as_propsin the_createMdxContentfunctiondomdomegg/recma-mdx-displayname— add adisplayNametoMDXContentcomponents, to enable switching on them in productionipikuka/recma-mdx-escape-missing-components— set a default value of() => nullfor missing components instead of throwing an errorremcohaszing/recma-mdx-is-mdx-component— add anisMdxComponentfield on MDX componentsremcohaszing/recma-nextjs-static-props— generategetStaticPropsexposing top level identifiers in Next.jsremcohaszing/recma-module-to-function— convert a module into a function bodyremcohaszing/rehype-mdx-code-props— interpret the codemetafield as JSX propsremcohaszing/rehype-mdx-import-media— change media sources to JavaScript importsremcohaszing/rehype-mdx-title— expose the page title as a stringboning-w/rehype-mdx-toc— export the table of contents data into MDX modulepangelani/remark-mdx-chartjs— replace fenced code blocks with charts usingreact-chartjs-2.remcohaszing/remark-mdx-frontmatter— change frontmatter (YAML) metadata to exportsgoodproblems/remark-mdx-math-enhanced— enhance math with JavaScript inside it
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.