import {Note} from '../_component/note.server.js'
export const navSortSelf = 4
export const info = {
  author: [
    {name: 'Titus Wormer', github: 'wooorm', twitter: 'wooorm'}
  ],
  published: new Date('2021-10-06'),
  modified: new Date('2021-11-01')
}

# Extending MDX

This article explains how to extend MDX content—specifically, how to *transform*
content with plugins. {/* more */}
See [§ Using MDX][use] for how to pass components, props, and the layout.
See [§ Getting started][start] for how to integrate MDX into your project.

## Contents

*   [Components & plugins](#components--plugins)
    *   [List of components](#list-of-components)
    *   [List of plugins](#list-of-plugins)
*   [Using plugins](#using-plugins)
*   [Creating plugins](#creating-plugins)

## 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`][api])
*   Plugins that hook into several stages of compilation (see [remark
    plugins][remark-plugins], [rehype plugins][rehype-plugins], and the new
    recma plugins)
*   Components passed, defined, or imported at runtime (see [§ Using MDX][use])

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 />`][react-confetti] with MDX.
Or, you can use the plugin [`remark-gfm`][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`](https://github.com/PaulieScanlon/mdx-embed)
    — React components for embedding 3rd party content, integrates w/
    MDX provider
*   [`system-ui/theme-ui`](https://github.com/system-ui/theme-ui)
    — React components for building consistent apps, integrates w/ MDX provider

{/*
please use alpha sorting on **project** name!
You can use this template:

*   [`user/project`](https://github.com/user/project)
    — A somewhat short description of the project
*/}

<Note type="info">
  **Note**: have another component that *specifically* works with MDX?
  Please send a PR to add it here!
</Note>

### List of plugins

See also the [list of remark plugins][remark-plugins] and
[list of rehype plugins][rehype-plugins].

*   [`remcohaszing/rehype-mdx-title`](https://github.com/remcohaszing/rehype-mdx-title)
    — expose the page title as a string
*   [`remcohaszing/remark-mdx-code-meta`](https://github.com/remcohaszing/remark-mdx-code-meta)
    — interpret the code `meta` field as JSX props
*   [`remcohaszing/remark-mdx-images`](https://github.com/remcohaszing/remark-mdx-images)
    — change image sources to JavaScript imports
*   [`remcohaszing/remark-mdx-frontmatter`](https://github.com/remcohaszing/remark-mdx-frontmatter)
    — change frontmatter (YAML) metadata to exports

{/*
please use alpha sorting on **project** name!
You can use this template:

*   [`user/project`](https://github.com/user/project)
    — A somewhat short description of the project
*/}

<Note type="info">
  **Note**: have another unified plugin that *specifically* works with MDX?
  Please send a PR to add it here!
</Note>

## Using plugins

Where to pass plugins is encoded in their name: remark plugins go in
[`options.remarkPlugins`][options-remark-plugins], rehype plugins
in [`options.rehypePlugins`][options-rehype-plugins].
Those fields expect lists of plugins and/or of `[plugin, options]`:

```js
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, {remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex]})

// remark and rehype plugins, last w/ options:
await compile(file, {
  remarkPlugins: [remarkMath],
  // A plugin with options:
  rehypePlugins: [[rehypeKatex, {throwOnError: true, strict: true}]]
})
```

## Creating plugins

Creating a plugin for MDX is mostly the same as creating a plugin for remark
or rehype.
There are several guides and recipes on that in [§ Learn on
`unifiedjs.com`][learn].

For the MDX specific parts of plugins, it’s recommended to read
[¶ Architecture][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`][syntax-tree] and use our interactive
[§ Playground][playground].

[remark-plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins

[rehype-plugins]: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins

[use]: /docs/using-mdx/

[api]: /packages/mdx/#api

[react-confetti]: https://github.com/alampros/react-confetti

[remark-gfm]: https://github.com/remarkjs/remark-gfm

[learn]: https://unifiedjs.com/learn/

[start]: /docs/getting-started/

[options-remark-plugins]: /packages/mdx/#optionsremarkplugins

[options-rehype-plugins]: /packages/mdx/#optionsrehypeplugins

[architecture]: /packages/mdx/#architecture

[syntax-tree]: /packages/remark-mdx/#syntax-tree

[playground]: /playground/
