* deps: add rehype-prism, shiki, rehype-pretty-code
* wip: apply rehype plugins depending on config
* wip: cherry-pick jsx-runtime fix?
* deps: rehype-pretty-code -> shiki-twoslash, add rehype-raw
* wip: add jsx-runtime fix
* feat: get shiki working!
* deps: add @astrojs/prism, prismjs, unist-util-visit
* feat: add prism support
* example: add small syntax highlight demo to with-mdx
* deps: remove rehype-prism
* chore: remove unused async
* chore: add .test.js to all mdx tests
* test: shiki, shikiConfig, prism
* fix: remove "is:raw" from prism output
* docs: add syntax highlighting section
* chore: add changeset
* nit: "Shiki config" -> Shiki config
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
* Revert "wip: add jsx-runtime fix"
This reverts commit 07f4528f44
.
* docs: link to integration README from example
Co-authored-by: Nate Moore <nate@astro.build>
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
10 KiB
@astrojs/mdx 📝
This Astro integration enables the usage of MDX components and allows you to create pages as .mdx
files.
Why MDX?
MDX is the defacto solution for embedding components, such as interactive charts or alerts, within Markdown content. If you have existing content authored in MDX, this integration makes migrating to Astro a breeze.
Want to learn more about MDX before using this integration?
Check out “What is MDX?”, a deep-dive on the MDX format.
Installation
Quick Install
The astro add
command-line tool automates the installation for you. Run one of the following commands in a new terminal window. (If you aren't sure which package manager you're using, run the first command.) Then, follow the prompts, and type "y" in the terminal (meaning "yes") for each one.
# Using NPM
npx astro add mdx
# Using Yarn
yarn astro add mdx
# Using PNPM
pnpx astro add mdx
Then, restart the dev server by typing CTRL-C
and then npm run astro dev
in the terminal window that was running Astro.
Because this command is new, it might not properly set things up. If that happens, feel free to log an issue on our GitHub and try the manual installation steps below.
Manual Install
First, install the @astrojs/mdx
package using your package manager. If you're using npm or aren't sure, run this in the terminal:
npm install @astrojs/mdx
Then, apply this integration to your astro.config.*
file using the integrations
property:
astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [mdx()],
});
Finally, restart the dev server.
Usage
To write your first MDX page in Astro, head to our UI framework documentation. You'll explore:
- 📦 how framework components are loaded,
- 💧 client-side hydration options, and
- 🪆 opportunities to mix and nest frameworks together
Client Directives are still required in .mdx
files.
Note
:
.mdx
files adhere to strict JSX syntax rather than Astro's HTML-like syntax.
Also check our Astro Integration Documentation for more on integrations.
Variables
MDX supports export
statements to add variables to your templates. These variables are accessible both from the template itself and as named properties when importing the template somewhere else.
For instance, you can export a title
field from an MDX page or component to use as a heading with {JSX expressions}
:
export const title = 'My first MDX post'
# {title}
This title
will be accessible from import
and glob statements as well:
---
// src/pages/index.astro
const posts = await Astro.glob('./*.mdx');
---
{posts.map(post => <p>{post.title}</p>)}
See the official "how MDX works" guide for more on MDX variables.
Frontmatter
Astro also supports YAML-based frontmatter out-of-the-box using the remark-mdx-frontmatter plugin. By default, all variables declared in a frontmatter fence (---
) will be accessible via the frontmatter
export. See the frontmatterOptions
configuration to customize this behavior.
For example, we can add a title
and publishDate
to an MDX page or component like so:
---
title: 'My first MDX post'
publishDate: '21 September 2022'
---
# {frontmatter.title}
Now, this title
and publishDate
will be accessible from import
and glob statements via the frontmatter
property. This matches the behavior of plain markdown in Astro as well!
---
// src/pages/index.astro
const posts = await Astro.glob('./*.mdx');
---
{posts.map(post => (
<Fragment>
<h2>{post.frontmatter.title}</h2>
<time>{post.frontmatter.publishDate}</time>
</Fragment>
))}
Syntax highlighting
The MDX integration respects your project's markdown.syntaxHighlight
configuration.
We will highlight your code blocks with Shiki by default using Shiki twoslash. You can customize this remark plugin using the markdown.shikiConfig
option in your astro.config
. For example, you can apply a different built-in theme like so:
// astro.config.mjs
export default {
markdown: {
shikiConfig: {
theme: 'dracula',
},
},
integrations: [mdx()],
}
Visit our Shiki configuration docs for more on using Shiki with Astro.
Switch to Prism
You can also use the Prism syntax highlighter by setting markdown.syntaxHighlight
to 'prism'
in your astro.config
like so:
// astro.config.mjs
export default {
markdown: {
syntaxHighlight: 'prism',
},
integrations: [mdx()],
}
This applies a minimal Prism renderer with added support for astro
code blocks. Visit our "Prism configuration" docs for more on using Prism with Astro.
Configuration
remarkPlugins
Default plugins: remark-gfm, remark-smartypants
Remark plugins allow you to extend your Markdown with new capabilities. This includes auto-generating a table of contents, applying accessible emoji labels, and more. We encourage you to browse awesome-remark for a full curated list!
We apply GitHub-flavored Markdown and Smartypants by default. This brings some niceties like auto-generating clickable links from text (ex. https://example.com
) and formatting quotes for readability. When applying your own plugins, you can choose to preserve or remove these defaults.
To apply plugins while preserving Astro's default plugins, use a nested extends
object like so:
// astro.config.mjs
import remarkToc from 'remark-toc';
export default {
integrations: [mdx({
// apply remark-toc alongside GitHub-flavored markdown and Smartypants
remarkPlugins: { extends: [remarkToc] },
})],
}
To apply plugins without Astro's defaults, you can apply a plain array:
// astro.config.mjs
import remarkToc from 'remark-toc';
export default {
integrations: [mdx({
// apply remark-toc alone, removing other defaults
remarkPlugins: [remarkToc],
})],
}
rehypePlugins
Default plugins: none
Rehype plugins allow you to transform the HTML that your Markdown generates. We recommend checking the Remark plugin catalog first before considering rehype plugins, since most users want to transform their Markdown syntax instead. If HTML transforms are what you need, we encourage you to browse awesome-rehype for a full curated list of plugins!
To apply rehype plugins, use the rehypePlugins
configuration option like so:
// astro.config.mjs
import rehypeMinifyHtml from 'rehype-minify';
export default {
integrations: [mdx({
rehypePlugins: [rehypeMinifyHtml],
})],
}
frontmatterOptions
Default: { name: 'frontmatter' }
We use remark-mdx-frontmatter to parse YAML-based frontmatter in your MDX files. If you want to override our default configuration or extend remark-mdx-frontmatter (ex. to apply a custom frontmatter parser), you can supply a frontmatterOptions
configuration.
For example, say you want to access frontmatter as root-level variables without a nested frontmatter
object. You can override the name
configuration option like so:
// astro.config.mjs
export default {
integrations: [mdx({
frontmatterOptions: {
name: '',
}
})],
}
---
title: I'm just a variable now!
---
# {title}
See the remark-mdx-frontmatter README for a complete list of options.
Examples
- The Astro MDX example shows how to use MDX files in your Astro project.
Troubleshooting
For help, check out the #support-threads
channel on Discord. Our friendly Support Squad members are here to help!
You can also check our Astro Integration Documentation for more on integrations.
Contributing
This package is maintained by Astro's Core team. You're welcome to submit an issue or PR!
Changelog
See CHANGELOG.md for a history of changes to this integration.