Astro
@astrojs/mdx
@astrojs/mdx
### Editor Integration
For editor support in [VS Code](https://code.visualstudio.com/), install the [official MDX extension](https://marketplace.visualstudio.com/items?itemName=unifiedjs.vscode-mdx).
For other editors, use the [MDX language server](https://github.com/mdx-js/mdx-analyzer/tree/main/packages/language-server).
## Usage
Visit the [MDX docs](https://mdxjs.com/docs/what-is-mdx/) to learn about using standard MDX features.
## MDX in Astro
Adding the MDX integration enhances your Markdown authoring with JSX variables, expressions and components.
It also adds extra features to standard MDX, including support for Markdown-style frontmatter in MDX. This allows you to use most of [Astro's built-in Markdown features](/en/guides/markdown-content/).
`.mdx` files must be written in [MDX syntax](https://mdxjs.com/docs/what-is-mdx/#mdx-syntax) rather than Astro’s HTML-like syntax.
### Using local MDX with content collections
To include your local MDX files in a content collection, make sure that your [collection loader](/en/guides/content-collections/#build-time-collection-loaders) is configured to load content from `.mdx` files:
```js title="src/content.config.ts" ins="mdx"
const blog = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
})
});
Using Exported Variables in MDX
MDX supports using export statements to add variables to your MDX content or to export data to a component that imports it.
For example, you can export a title field from an MDX page or component to use as a heading with {JSX expressions}:
const posts = Object.values(matches);
---
{posts.map(post => <p>{post.title}</p>)}
Exported Properties
The following properties are available to a .astro component when using an import statement or import.meta.glob():
file- The absolute file path (e.g./home/user/projects/.../file.mdx).url- The URL of the page (e.g./en/guides/markdown-content).frontmatter- Contains any data specified in the file’s YAML/TOML frontmatter.getHeadings()- An async function that returns an array of all headings (<h1>to<h6>) in the file with the type:{ depth: number; slug: string; text: string }[]. Each heading’sslugcorresponds to the generated ID for a given heading and can be used for anchor links. Headings from imported files are not included.<Content />- A component that returns the full, rendered contents of the file.- (any
exportvalue) - MDX files can also export data with anexportstatement.
Using Frontmatter Variables in MDX
The Astro MDX integration includes support for using frontmatter in MDX by default. Add frontmatter properties just as you would in Markdown files, and these variables are available to use in the template, and as named properties when importing the file somewhere else.
---
title: 'My first MDX post'
author: 'Houston'
---
# {frontmatter.title}
Written by: {frontmatter.author}
Using Components in MDX
After installing the MDX integration, you can import and use both Astro components and UI framework components in MDX (.mdx) files just as you would use them in any other Astro component.
Don't forget to include a client:directive on your UI framework components, if necessary!
See more examples of using import and export statements in the MDX docs.
---
title: My first post
---
I just started my new Astro blog!
Here is my counter component, working in MDX:
<ReactCounter client:load />
Assigning Custom Components to HTML elements
With MDX, you can map Markdown syntax to custom components instead of their standard HTML elements. This allows you to write in standard Markdown syntax, but apply special component styling to selected elements.
For example, you can create a Blockquote.astro component to provide custom styling for <blockquote> content:
---
const props = Astro.props;
---
<blockquote {...props} class="bg-blue-50 p-4">
<span class="text-4xl text-blue-600 mb-2">“</span>
<slot /> <!-- Be sure to add a `<slot/>` for child content! -->
</blockquote>
Import your custom component into your .mdx file, then export a components object that maps the standard HTML element to your custom component:
const { Content } = await render(entry);
---
<Content components={{ h1: CustomHeading }} />
Configuration
Once the MDX integration is installed, no configuration is necessary to use .mdx files in your Astro project.
You can configure how your MDX is rendered with the following options:
Options inherited from Markdown config
All markdown configuration options can be configured separately in the MDX integration, including the Markdown processor, syntax highlighting, and more. Options will default to those in your Markdown config (see the extendMarkdownConfig option to modify this).
processor
Type: MarkdownProcessor
Default: inherited from markdown.processor
By default, .mdx files render through the same Markdown processor as your .md files. Set processor to use a different processor, or the same processor with different options, for .mdx files only.
For example, to keep the default Sätteri processor for .md files while rendering .mdx files with remark and rehype using @astrojs/markdown-remark:
extendMarkdownConfig
Type: boolean
Default: true
MDX will extend your project's existing Markdown configuration by default. To override individual options, you can specify their equivalent in your MDX configuration.
For example, say you need a different syntax highlighter and a different set of plugins for .mdx files. You can apply these options like so, with extendMarkdownConfig enabled by default:
You may also need to disable markdown config extension in MDX. For this, set extendMarkdownConfig to false:
recmaPlugins
Type: PluggableList
Default: []
These are plugins that modify the output estree directly. This is useful for modifying or injecting JavaScript variables in your MDX files.
Since Astro v7, the default Markdown processor does not support Recma plugins. If your project depends on them, you can use the unified() processor.
We suggest using AST Explorer to play with estree outputs, and trying estree-util-visit for searching across JavaScript nodes.
optimize
Type: boolean | { ignoreElementNames?: string[] }
Default: false
This is an optional configuration setting to optimize the MDX output for faster builds and rendering via an internal rehype plugin. This may be useful if you have many MDX files and notice slow builds. However, this option may generate some unescaped HTML, so make sure your site's interactive parts still work correctly after enabling it.
This is disabled by default. To enable MDX optimization, add the following to your MDX integration configuration:
ignoreElementNames
Type: string[]
Previously known as customComponentNames.
An optional property of optimize to prevent the MDX optimizer from handling certain element names, like custom components passed to imported MDX content via the components prop.
You will need to exclude these components from optimization as the optimizer eagerly converts content into a static string, which will break custom components that needs to be dynamically rendered.
For example, the intended MDX output of the following is <Heading>...</Heading> in place of every "<h1>...</h1>":
---
---
<Content components={{ ...components, h1: Heading }} />
To configure optimization for this using the ignoreElementNames property, specify an array of HTML element names that should be treated as custom components:
Note that if your MDX file configures custom components using export const components = { ... }, then you do not need to manually configure this option. The optimizer will automatically detect them.
Examples
- The Astro MDX starter template shows how to use MDX files in your Astro project.