Skip to content
Merged
33 changes: 16 additions & 17 deletions src/content/docs/en/guides/integrations-guide/mdx.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -266,22 +266,19 @@ All [`markdown` configuration options](/en/reference/configuration-reference/#ma

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import { satteri } from '@astrojs/markdown-satteri';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
import rehypePresetMinify from 'rehype-preset-minify';
import { myMdastPlugin } from './my-satteri-plugin.mjs';

export default defineConfig({
// ...
integrations: [
mdx({
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
processor: unified({
remarkPlugins: [remarkToc],
rehypePlugins: [rehypePresetMinify],
remarkRehype: { footnoteLabel: 'Footnotes' },
gfm: false
processor: satteri({
mdastPlugins: [myMdastPlugin()],
features: { gfm: false },
}),
}),
],
Expand All @@ -301,16 +298,16 @@ export default defineConfig({

By default, `.mdx` files render through the same [Markdown processor](/en/guides/markdown-content/#choosing-a-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 remark/rehype processor for `.md` files while rendering `.mdx` files with [Sätteri](https://satteri.bruits.org/) using `@astrojs/markdown-satteri`:
For example, to keep the default [Sätteri](https://satteri.bruits.org/) processor for `.md` files while rendering `.mdx` files with remark and rehype using `@astrojs/markdown-remark`:

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';
import { unified } from '@astrojs/markdown-remark';
import mdx from '@astrojs/mdx';

export default defineConfig({
integrations: [
mdx({ processor: satteri() }),
mdx({ processor: unified() }),
],
});
```
Expand All @@ -330,14 +327,14 @@ For example, say you need a different syntax highlighter and a different set of

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import { satteri } from '@astrojs/markdown-satteri';
import mdx from '@astrojs/mdx';

export default defineConfig({
// ...
markdown: {
syntaxHighlight: 'prism',
processor: unified({ remarkPlugins: [remarkPlugin1] }),
processor: satteri({ mdastPlugins: [mdastPlugin1] }),
},
integrations: [
mdx({
Expand All @@ -346,7 +343,7 @@ export default defineConfig({
syntaxHighlight: 'shiki',

// `markdown.processor` gets overridden for `.mdx` files by this option
processor: unified({ remarkPlugins: [remarkPlugin2] }),
processor: satteri({ mdastPlugins: [mdastPlugin2] }),
}),
],
});
Expand All @@ -356,19 +353,19 @@ You may also need to disable `markdown` config extension in MDX. For this, set `

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import { satteri } from '@astrojs/markdown-satteri';
import mdx from '@astrojs/mdx';

export default defineConfig({
// ...
markdown: {
processor: unified({ remarkPlugins: [remarkPlugin] }),
processor: satteri({ mdastPlugins: [mdastPlugin] }),
},
integrations: [
mdx({
// Markdown config now ignored
extendMarkdownConfig: false,
// Default `unified()` processor used
// Default `satteri()` processor used
}),
],
});
Expand All @@ -385,6 +382,8 @@ export default defineConfig({

These are plugins that modify the output [estree](https://github.com/estree/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](/en/guides/markdown-content/#switching-to-the-unified-processor).

We suggest [using AST Explorer](https://astexplorer.net/) to play with estree outputs, and trying [`estree-util-visit`](https://unifiedjs.com/explore/package/estree-util-visit/) for searching across JavaScript nodes.

### `optimize`
Expand Down
132 changes: 83 additions & 49 deletions src/content/docs/en/guides/markdown-content.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FileTree } from '@astrojs/starlight/components';
import RecipeLinks from "~/components/RecipeLinks.astro";
import ReadMore from '~/components/ReadMore.astro';
import { Steps, Tabs, TabItem } from '@astrojs/starlight/components';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';

[Markdown](https://daringfireball.net/projects/markdown/) is commonly used to author text-heavy content like blog posts and documentation. Astro includes built-in support for Markdown files that can also include [frontmatter YAML](https://dev.to/paulasantamaria/introduction-to-yaml-125f) (or [TOML](https://toml.io)) to define custom properties such as a title, description, and tags.

Expand Down Expand Up @@ -72,7 +73,7 @@ const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));

When fetching data from your collections with the helper functions `getCollection()` or `getEntry()`, your Markdown's frontmatter properties are available on a `data` object (e.g. `post.data.title`). Additionally, `body` contains the raw, uncompiled body content as a string.

The [`render()`](/en/reference/modules/astro-content/#render) function returns your Markdown body content, a generated list of headings, as well as a modified frontmatter object after any remark or rehype plugins have been applied.
The [`render()`](/en/reference/modules/astro-content/#render) function returns your Markdown body content, a generated list of headings, as well as a modified frontmatter object after any Markdown plugins have been applied.

<ReadMore>Read more about [using content returned by a collections query](/en/guides/content-collections/#using-content-in-astro-templates).</ReadMore>

Expand Down Expand Up @@ -164,35 +165,35 @@ You can customize these heading IDs with a [Markdown processor](#choosing-a-mark
Astro injects `id` attributes after your custom plugins have run, so any ID set by a plugin is preserved. If one of your custom plugins needs to access the IDs injected by Astro, you can import Astro's heading ids plugin and place it before any plugins that rely on it:

<Tabs syncKey="markdown-processor">
<TabItem label="Unified">
<TabItem label="Sätteri">
```js title="astro.config.mjs" ins={2-3, 9}
import { defineConfig } from 'astro/config';
import { unified, rehypeHeadingIds } from '@astrojs/markdown-remark';
import { satteri, satteriHeadingIdsPlugin } from '@astrojs/markdown-satteri';
import { otherPluginThatReliesOnHeadingIDs } from 'some/plugin/source';

export default defineConfig({
markdown: {
processor: unified({
rehypePlugins: [
rehypeHeadingIds,
processor: satteri({
hastPlugins: [
satteriHeadingIdsPlugin(),
otherPluginThatReliesOnHeadingIDs,
],
}),
},
});
```
</TabItem>
<TabItem label="Sätteri">
<TabItem label="Unified">
```js title="astro.config.mjs" ins={2-3, 9}
import { defineConfig } from 'astro/config';
import { satteri, satteriHeadingIdsPlugin } from '@astrojs/markdown-satteri';
import { unified, rehypeHeadingIds } from '@astrojs/markdown-remark';
import { otherPluginThatReliesOnHeadingIDs } from 'some/plugin/source';

export default defineConfig({
markdown: {
processor: satteri({
hastPlugins: [
satteriHeadingIdsPlugin(),
processor: unified({
rehypePlugins: [
rehypeHeadingIds,
otherPluginThatReliesOnHeadingIDs,
],
}),
Expand All @@ -204,26 +205,82 @@ Astro injects `id` attributes after your custom plugins have run, so any ID set

## Markdown Plugins

Astro renders Markdown using a configurable **Markdown processor**. By default, this is the [unified](https://unifiedjs.com/) pipeline of [remark](https://remark.js.org/) and [rehype](https://github.com/rehypejs/rehype), with an active plugin ecosystem.
Astro renders Markdown using a configurable **Markdown processor**. By default, this is [Sätteri](https://satteri.bruits.org/), Astro's native Markdown and MDX pipeline, included with Astro.

Astro applies [GitHub-Flavored Markdown](https://github.github.com/gfm/) and [SmartyPants](https://daringfireball.net/projects/smartypants/) automatically. This brings some niceties like generating clickable links from text, and formatting for quotations and em-dashes.

You can extend Markdown processing with plugins, enable additional parser features, or [switch to a different processor entirely](#switching-to-the-sätteri-processor). See the full list of [Markdown configuration options](/en/reference/configuration-reference/#markdown-options).
You can extend Markdown processing with plugins, enable additional parser features, or [switch to a different processor entirely](#switching-to-the-unified-processor). See the full list of [Markdown configuration options](/en/reference/configuration-reference/#markdown-options).

### Choosing a Markdown processor

The [`markdown.processor` option](/en/reference/configuration-reference/#markdownprocessor) controls which engine renders your `.md` and `.mdx` files. Astro provides two official options:

- **`unified()`** (default): the [remark](https://remark.js.org/) and [rehype](https://github.com/rehypejs/rehype) pipeline, with its large plugin ecosystem.
- **`satteri()`**: the native [Sätteri](https://satteri.bruits.org/) pipeline, a faster Markdown and MDX compiler with its own plugin model. Provided by `@astrojs/markdown-satteri`, which you install separately.
- **`satteri()`** (default): the native [Sätteri](https://satteri.bruits.org/) pipeline, a fast Markdown and MDX compiler with its own plugin model. Included with Astro, so no extra installation is needed.
- **`unified()`**: the [remark](https://remark.js.org/) and [rehype](https://github.com/rehypejs/rehype) pipeline, with its large plugin ecosystem. Provided by `@astrojs/markdown-remark`, which you install separately.

### Using Sätteri plugins and features

The default `satteri()` processor accepts its own plugins through `mdastPlugins` and `hastPlugins`, and toggles optional parser features through `features`. See the [Sätteri documentation](https://satteri.bruits.org/docs/) for the available plugins and features.

Import `satteri` from `@astrojs/markdown-satteri` and pass your options to it through `markdown.processor`. This example adds an mdast plugin and enables the `directive` parser feature:

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';
import { myMdastPlugin } from './my-satteri-plugin.mjs';

### Using remark and rehype plugins
export default defineConfig({
markdown: {
processor: satteri({
mdastPlugins: [myMdastPlugin()],
features: { directive: true },
}),
},
});
```

The default `unified()` processor accepts third-party [remark](https://github.com/remarkjs/remark) and [rehype](https://github.com/rehypejs/rehype) plugins. These plugins allow you to extend your Markdown with new capabilities, like [auto-generating a table of contents](https://github.com/remarkjs/remark-toc), [applying accessible emoji labels](https://github.com/florianeckerstorfer/remark-a11y-emoji), and [styling your Markdown](/en/guides/styling/#markdown-styling).
### Switching to the unified processor

To use [remark and rehype](https://unifiedjs.com/) instead of Sätteri, install `@astrojs/markdown-remark`, then import `unified` and pass it to `markdown.processor`:

<PackageManagerTabs>
<Fragment slot="npm">
```shell
npm install @astrojs/markdown-remark
```
</Fragment>
<Fragment slot="pnpm">
```shell
pnpm add @astrojs/markdown-remark
```
</Fragment>
<Fragment slot="yarn">
```shell
yarn add @astrojs/markdown-remark
```
</Fragment>
</PackageManagerTabs>

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';

export default defineConfig({
markdown: {
processor: unified(),
},
});
```

Switching processors replaces Sätteri for both `.md` and `.mdx` files. Any Sätteri plugins in your config will not apply. To use remark and rehype only for `.mdx` files, set the [`processor` option on the MDX integration](/en/guides/integrations-guide/mdx/#processor) instead.

#### Using remark and rehype plugins

The `unified()` processor accepts third-party [remark](https://github.com/remarkjs/remark) and [rehype](https://github.com/rehypejs/rehype) plugins. These plugins allow you to extend your Markdown with new capabilities, like [auto-generating a table of contents](https://github.com/remarkjs/remark-toc), [applying accessible emoji labels](https://github.com/florianeckerstorfer/remark-a11y-emoji), and [styling your Markdown](/en/guides/styling/#markdown-styling).

We encourage you to browse [awesome-remark](https://github.com/remarkjs/awesome-remark) and [awesome-rehype](https://github.com/rehypejs/awesome-rehype) for popular plugins! See each plugin's own README for specific installation instructions.

Import `unified` from `@astrojs/markdown-remark` and pass your plugins to it through `markdown.processor`. This example applies [`remark-toc`](https://github.com/remarkjs/remark-toc) and [`rehype-accessible-emojis`](https://www.npmjs.com/package/rehype-accessible-emojis) to Markdown files:
After [switching to the `unified()` processor](#switching-to-the-unified-processor), pass your plugins to it through `markdown.processor`. This example applies [`remark-toc`](https://github.com/remarkjs/remark-toc) and [`rehype-accessible-emojis`](https://www.npmjs.com/package/rehype-accessible-emojis) to Markdown files:

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
Expand All @@ -241,7 +298,7 @@ export default defineConfig({
});
```

### Customizing a remark or rehype plugin
#### Customizing a remark or rehype plugin

In order to customize a plugin, provide an options object after it in a nested array.

Expand All @@ -264,29 +321,6 @@ export default defineConfig({
});
```

### Switching to the Sätteri processor

To use [Sätteri](https://satteri.bruits.org/) instead of remark and rehype, install `@astrojs/markdown-satteri`, then import `satteri` and pass it to `markdown.processor`:

```js title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';
import { myMdastPlugin } from './my-satteri-plugin.mjs';

export default defineConfig({
markdown: {
processor: satteri({
mdastPlugins: [myMdastPlugin()],
features: { directive: true },
}),
},
});
```

The Sätteri processor accepts its own plugins through `mdastPlugins` and `hastPlugins`, and toggles optional parser features through `features`. See the [Sätteri documentation](https://satteri.bruits.org/docs/) for the available plugins and features.

Switching processors replaces remark and rehype for both `.md` and `.mdx` files. Any remark or rehype plugins in your config will not apply. To use Sätteri only for `.mdx` files, set the [`processor` option on the MDX integration](/en/guides/integrations-guide/mdx/#processor) instead.

### Modifying frontmatter programmatically

When using the [remark/rehype processor](#using-remark-and-rehype-plugins), you can add frontmatter properties to all of your Markdown and MDX files with a remark or rehype plugin.
Expand Down Expand Up @@ -353,21 +387,21 @@ The following example uses a different syntax highlighter and a different set of

```ts title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import { satteri } from '@astrojs/markdown-satteri';
import mdx from '@astrojs/mdx';

export default defineConfig({
markdown: {
syntaxHighlight: 'prism',
processor: unified({ remarkPlugins: [remarkPlugin1] }),
processor: satteri({ mdastPlugins: [mdastPlugin1] }),
},
integrations: [
mdx({
// `markdown.syntaxHighlight` gets overridden for `.mdx` files by this option
syntaxHighlight: 'shiki',

// `markdown.processor` gets overridden for `.mdx` files with a different remark plugin
processor: unified({ remarkPlugins: [remarkPlugin2] }),
// `markdown.processor` gets overridden for `.mdx` files with a different plugin
processor: satteri({ mdastPlugins: [mdastPlugin2] }),
})
]
});
Expand All @@ -377,18 +411,18 @@ To avoid extending your Markdown config from MDX, set [the `extendMarkdownConfig

```ts title="astro.config.mjs"
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import { satteri } from '@astrojs/markdown-satteri';
import mdx from '@astrojs/mdx';

export default defineConfig({
markdown: {
processor: unified({ remarkPlugins: [remarkPlugin] }),
processor: satteri({ mdastPlugins: [mdastPlugin] }),
},
integrations: [
mdx({
// Markdown config now ignored
extendMarkdownConfig: false,
// Default `unified()` processor used with no plugins
// Default `satteri()` processor used with no plugins
})
]
});
Expand Down
Loading
Loading