Skip to content

Commit a9c2920

Browse files
Markdown and MDX configuration rework (#5684)
* feat: change extendDefaults -> gfm * deps: remove smartypants from md/remark * tests: update markdown plugin tests * fix: borked lockfile * feat: allow all Markdown options in MDX config, with extend * deps: remove smartypants from MDX * chore: remove unused `mode` property * chore: remark rehype types * chore: dead code * fix: order of default config properties * refactor: move md defaults to remark * fix: RemarkRehype type * fix: apply defaults based on MD defaults * chore: update plugin tests * chore: add syntaxHighlight test * refactor: remove drafts from config defaults * docs: new MDX config options * chore: add changeset * edit: test both extends for syntax highlight * refactor: remove MDX config deep merge * docs: update README and changeset * edit: avoid -> disable Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * edit: `drafts` clarification Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * edit: remove "scare quotes" Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca> * docs: MDX config options redraft * docs: add migration * chore: changeset heading levels * refactor: githubFlavoredMarkdown -> gfm * chore: remove unused imports Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
1 parent 163a9a9 commit a9c2920

14 files changed

Lines changed: 2194 additions & 1671 deletions

File tree

.changeset/shaggy-keys-turn.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
'astro': major
3+
'@astrojs/markdown-remark': major
4+
'@astrojs/mdx': minor
5+
---
6+
7+
Refine Markdown and MDX configuration options for ease-of-use.
8+
9+
#### Markdown
10+
11+
- **Remove `remark-smartypants`** from Astro's default Markdown plugins.
12+
- **Replace the `extendDefaultPlugins` option** with a simplified `gfm` boolean. This is enabled by default, and can be disabled to remove GitHub-Flavored Markdown.
13+
- Ensure GitHub-Flavored Markdown is applied whether or not custom `remarkPlugins` or `rehypePlugins` are configured. If you want to apply custom plugins _and_ remove GFM, manually set `gfm: false` in your config.
14+
15+
#### MDX
16+
17+
- Support _all_ Markdown configuration options (except `drafts`) from your MDX integration config. This includes `syntaxHighlighting` and `shikiConfig` options to further customize the MDX renderer.
18+
- Simplify `extendDefaults` to an `extendMarkdownConfig` option. MDX options will default to their equivalent in your Markdown config. By setting `extendMarkdownConfig` to false, you can "eject" to set your own syntax highlighting, plugins, and more.
19+
20+
#### Migration
21+
22+
To preserve your existing Markdown and MDX setup, you may need some configuration changes:
23+
24+
##### Smartypants manual installation
25+
26+
[Smartypants](https://github.com/silvenon/remark-smartypants) has been removed from Astro's default setup. If you rely on this plugin, [install `remark-smartypants`](https://github.com/silvenon/remark-smartypants#installing) and apply to your `astro.config.*`:
27+
28+
```diff
29+
// astro.config.mjs
30+
import { defineConfig } from 'astro/config';
31+
+ import smartypants from 'remark-smartypants';
32+
33+
export default defineConfig({
34+
markdown: {
35+
+ remarkPlugins: [smartypants],
36+
}
37+
});
38+
```
39+
40+
##### Migrate `extendDefaultPlugins` to `gfm`
41+
42+
You may have disabled Astro's built-in plugins (GitHub-Flavored Markdown and Smartypants) with the `extendDefaultPlugins` option. Since Smartypants has been removed, this has been renamed to `gfm`.
43+
44+
```diff
45+
// astro.config.mjs
46+
import { defineConfig } from 'astro/config';
47+
48+
export default defineConfig({
49+
markdown: {
50+
- extendDefaultPlugins: false,
51+
+ gfm: false,
52+
}
53+
});
54+
```
55+
56+
57+
Additionally, applying remark and rehype plugins **no longer disables** `gfm`. You will need to opt-out manually by setting `gfm` to `false`.
58+
59+
##### Migrate MDX's `extendPlugins` to `extendMarkdownConfig`
60+
61+
You may have used the `extendPlugins` option to manage plugin defaults in MDX. This has been replaced by 2 flags:
62+
- `extendMarkdownConfig` (`true` by default) to toggle Markdown config inheritance. This replaces the `extendPlugins: 'markdown'` option.
63+
- `gfm` (`true` by default) to toggle GitHub-Flavored Markdown in MDX. This replaces the `extendPlugins: 'defaults'` option.

packages/astro/src/@types/astro.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -734,10 +734,6 @@ export interface AstroUserConfig {
734734
* @description
735735
* Pass [remark plugins](https://github.com/remarkjs/remark) to customize how your Markdown is built. You can import and apply the plugin function (recommended), or pass the plugin name as a string.
736736
*
737-
* :::caution
738-
* Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the [`extendDefaultPlugins`](#markdownextenddefaultplugins) flag.
739-
* :::
740-
*
741737
* ```js
742738
* import remarkToc from 'remark-toc';
743739
* {
@@ -755,10 +751,6 @@ export interface AstroUserConfig {
755751
* @description
756752
* Pass [rehype plugins](https://github.com/remarkjs/remark-rehype) to customize how your Markdown's output HTML is processed. You can import and apply the plugin function (recommended), or pass the plugin name as a string.
757753
*
758-
* :::caution
759-
* Providing a list of plugins will **remove** our default plugins. To preserve these defaults, see the [`extendDefaultPlugins`](#markdownextenddefaultplugins) flag.
760-
* :::
761-
*
762754
* ```js
763755
* import rehypeMinifyHtml from 'rehype-minify';
764756
* {
@@ -771,23 +763,21 @@ export interface AstroUserConfig {
771763
rehypePlugins?: RehypePlugins;
772764
/**
773765
* @docs
774-
* @name markdown.extendDefaultPlugins
766+
* @name markdown.gfm
775767
* @type {boolean}
776-
* @default `false`
768+
* @default `true`
777769
* @description
778-
* Astro applies the [GitHub-flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins by default. When adding your own remark or rehype plugins, you can preserve these defaults by setting the `extendDefaultPlugins` flag to `true`:
770+
* Astro uses [GitHub-flavored Markdown](https://github.com/remarkjs/remark-gfm) by default. To disable this, set the `gfm` flag to `false`:
779771
*
780772
* ```js
781773
* {
782774
* markdown: {
783-
* extendDefaultPlugins: true,
784-
* remarkPlugins: [exampleRemarkPlugin],
785-
* rehypePlugins: [exampleRehypePlugin],
775+
* gfm: false,
786776
* }
787777
* }
788778
* ```
789779
*/
790-
extendDefaultPlugins?: boolean;
780+
gfm?: boolean;
791781
/**
792782
* @docs
793783
* @name markdown.remarkRehype

packages/astro/src/core/config/schema.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { RehypePlugin, RemarkPlugin, RemarkRehype } from '@astrojs/markdown-remark';
2+
import { markdownConfigDefaults } from '@astrojs/markdown-remark';
23
import type * as Postcss from 'postcss';
34
import type { ILanguageRegistration, IThemeRegistration, Theme } from 'shiki';
45
import type { AstroUserConfig, ViteUserConfig } from '../../@types/astro';
@@ -33,15 +34,7 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
3334
integrations: [],
3435
markdown: {
3536
drafts: false,
36-
syntaxHighlight: 'shiki',
37-
shikiConfig: {
38-
langs: [],
39-
theme: 'github-dark',
40-
wrap: false,
41-
},
42-
remarkPlugins: [],
43-
rehypePlugins: [],
44-
remarkRehype: {},
37+
...markdownConfigDefaults,
4538
},
4639
vite: {},
4740
legacy: {
@@ -184,7 +177,7 @@ export const AstroConfigSchema = z.object({
184177
.custom<RemarkRehype>((data) => data instanceof Object && !Array.isArray(data))
185178
.optional()
186179
.default(ASTRO_CONFIG_DEFAULTS.markdown.remarkRehype),
187-
extendDefaultPlugins: z.boolean().default(false),
180+
gfm: z.boolean().default(ASTRO_CONFIG_DEFAULTS.markdown.gfm),
188181
})
189182
.default({}),
190183
vite: z

packages/astro/test/astro-markdown-plugins.test.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,29 +46,51 @@ describe('Astro Markdown plugins', () => {
4646
expect($('#hello-world').hasClass('title')).to.equal(true);
4747
});
4848

49-
for (const extendDefaultPlugins of [true, false]) {
50-
it(`Handles default plugins when extendDefaultPlugins = ${extendDefaultPlugins}`, async () => {
49+
// Asserts Astro 1.0 behavior is removed. Test can be removed in Astro 3.0.
50+
it('Still applies GFM when user plugins are provided', async () => {
51+
const fixture = await buildFixture({
52+
markdown: {
53+
remarkPlugins: [remarkExamplePlugin],
54+
rehypePlugins: [[addClasses, { 'h1,h2,h3': 'title' }]],
55+
},
56+
});
57+
const html = await fixture.readFile('/with-gfm/index.html');
58+
const $ = cheerio.load(html);
59+
60+
// test 1: GFM autolink applied correctly
61+
expect($('a[href="https://example.com"]')).to.have.lengthOf(1);
62+
63+
// test 2: remark plugins still applied
64+
expect(html).to.include('Remark plugin applied!');
65+
66+
// test 3: rehype plugins still applied
67+
expect($('#github-flavored-markdown-test')).to.have.lengthOf(1);
68+
expect($('#github-flavored-markdown-test').hasClass('title')).to.equal(true);
69+
});
70+
71+
for (const gfm of [true, false]) {
72+
it(`Handles GFM when gfm = ${gfm}`, async () => {
5173
const fixture = await buildFixture({
5274
markdown: {
5375
remarkPlugins: [remarkExamplePlugin],
5476
rehypePlugins: [[addClasses, { 'h1,h2,h3': 'title' }]],
55-
extendDefaultPlugins,
77+
gfm,
5678
},
5779
});
5880
const html = await fixture.readFile('/with-gfm/index.html');
5981
const $ = cheerio.load(html);
6082

6183
// test 1: GFM autolink applied correctly
62-
if (extendDefaultPlugins === true) {
84+
if (gfm === true) {
6385
expect($('a[href="https://example.com"]')).to.have.lengthOf(1);
6486
} else {
6587
expect($('a[href="https://example.com"]')).to.have.lengthOf(0);
6688
}
6789

68-
// test 2: (sanity check) remark plugins still applied
90+
// test 2: remark plugins still applied
6991
expect(html).to.include('Remark plugin applied!');
7092

71-
// test 3: (sanity check) rehype plugins still applied
93+
// test 3: rehype plugins still applied
7294
expect($('#github-flavored-markdown-test')).to.have.lengthOf(1);
7395
expect($('#github-flavored-markdown-test').hasClass('title')).to.equal(true);
7496
});

packages/integrations/mdx/README.md

Lines changed: 70 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -78,116 +78,100 @@ Visit the [MDX docs](https://mdxjs.com/docs/what-is-mdx/) to learn about using s
7878

7979
Once the MDX integration is installed, no configuration is necessary to use `.mdx` files in your Astro project.
8080

81-
You can extend how your MDX is rendered by adding remark, rehype and recma plugins.
81+
You can configure how your MDX is rendered with the following options:
8282

83-
- [`extendPlugins`](#extendplugins)
84-
- [`remarkRehype`](#remarkrehype)
85-
- [`remarkPlugins`](#remarkplugins)
86-
- [`rehypePlugins`](#rehypeplugins)
83+
- [Options inherited from Markdown config](#options-inherited-from-markdown-config)
84+
- [`extendMarkdownConfig`](#extendmarkdownconfig)
8785
- [`recmaPlugins`](#recmaplugins)
8886

89-
### `extendPlugins`
87+
### Options inherited from Markdown config
9088

91-
You can customize how MDX files inherit your project’s existing Markdown configuration using the `extendPlugins` option.
89+
All [`markdown` configuration options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) except `drafts` can be configured separately in the MDX integration. This includes remark and rehype plugins, syntax highlighting, and more. Options will default to those in your Markdown config ([see the `extendMarkdownConfig` option](#extendmarkdownconfig) to modify this).
9290

93-
#### `markdown` (default)
91+
:::note
92+
There is no separate MDX configuration for [including pages marked as draft in the build](https://docs.astro.build/en/reference/configuration-reference/#markdowndrafts). This Markdown setting will be respected by both Markdown and MDX files and cannot be overriden for MDX files specifically.
93+
:::
9494

95-
Astro's MDX files will inherit all [`markdown` options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) in your Astro configuration file, which includes the [GitHub-Flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins by default.
96-
97-
Any additional plugins you apply in your MDX config will be applied *after* your configured Markdown plugins.
98-
99-
#### `astroDefaults`
100-
101-
Astro's MDX files will apply only [Astro's default plugins](/en/reference/configuration-reference/#markdownextenddefaultplugins), without inheriting the rest of your Markdown config.
102-
103-
This example will apply the default [GitHub-Flavored Markdown](https://github.com/remarkjs/remark-gfm) and [Smartypants](https://github.com/silvenon/remark-smartypants) plugins alongside [`remark-toc`](https://github.com/remarkjs/remark-toc) to your MDX files, while ignoring any `markdown.remarkPlugins` configuration:
104-
105-
```js "extendPlugins: 'astroDefaults'"
95+
```ts
10696
// astro.config.mjs
97+
import { defineConfig } from 'astro/config';
98+
import mdx from '@astrojs/mdx';
10799
import remarkToc from 'remark-toc';
100+
import rehypeMinifyHtml from 'rehype-minify-html';
108101

109-
export default {
110-
markdown: {
111-
remarkPlugins: [/** ignored */]
112-
},
113-
integrations: [mdx({
114-
remarkPlugins: [remarkToc],
115-
// Astro defaults applied
116-
extendPlugins: 'astroDefaults',
117-
})],
118-
}
102+
export default defineConfig({
103+
integrations: [
104+
mdx({
105+
syntaxHighlight: 'shiki',
106+
shikiConfig: { theme: 'dracula' },
107+
remarkPlugins: [remarkToc],
108+
rehypePlugins: [rehypeMinifyHtml],
109+
remarkRehype: { footnoteLabel: 'Footnotes' },
110+
gfm: false,
111+
})
112+
]
113+
})
119114
```
120115

121-
#### `false`
116+
:::caution
117+
MDX does not support passing remark and rehype plugins as a string. You should install, import, and apply the plugin function instead.
118+
:::
122119

123-
Astro's MDX files will not inherit any [`markdown` options](https://docs.astro.build/en/reference/configuration-reference/#markdown-options), nor will any Astro Markdown defaults be applied:
120+
📚 See the [Markdown Options reference](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) for a complete list of options.
124121

125-
```js "extendPlugins: false"
126-
// astro.config.mjs
127-
import remarkToc from 'remark-toc';
128-
129-
export default {
130-
integrations: [mdx({
131-
remarkPlugins: [remarkToc],
132-
// Astro defaults not applied
133-
extendPlugins: false,
134-
})],
135-
}
136-
```
122+
### `extendMarkdownConfig`
137123

138-
### `remarkRehype`
124+
- **Type:** `boolean`
125+
- **Default:** `true`
139126

140-
Markdown content is transformed into HTML through remark-rehype which has [a number of options](https://github.com/remarkjs/remark-rehype#options).
127+
MDX will extend [your project's existing Markdown configuration](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) by default. To override individual options, you can specify their equivalent in your MDX configuration.
141128

142-
You can set remark-rehype options in your config file:
129+
For example, say you need to disable GitHub-Flavored Markdown and apply a different set of remark plugins for MDX files. You can apply these options like so, with `extendMarkdownConfig` enabled by default:
143130

144-
```js
131+
```ts
145132
// astro.config.mjs
146-
export default {
147-
integrations: [mdx({
148-
remarkRehype: {
149-
footnoteLabel: 'Catatan kaki',
150-
footnoteBackLabel: 'Kembali ke konten',
151-
},
152-
})],
153-
};
154-
```
155-
This inherits the configuration of [`markdown.remarkRehype`](https://docs.astro.build/en/reference/configuration-reference/#markdownremarkrehype). This behavior can be changed by configuring `extendPlugins`.
156-
157-
### `remarkPlugins`
158-
159-
Browse [awesome-remark](https://github.com/remarkjs/awesome-remark) for a full curated list of [remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) to extend your Markdown's capabilities.
160-
161-
This example applies the [`remark-toc`](https://github.com/remarkjs/remark-toc) plugin to `.mdx` files. To customize plugin inheritance from your Markdown config or Astro's defaults, [see the `extendPlugins` option](#extendplugins).
162-
163-
```js
164-
// astro.config.mjs
165-
import remarkToc from 'remark-toc';
133+
import { defineConfig } from 'astro/config';
134+
import mdx from '@astrojs/mdx';
166135

167-
export default {
168-
integrations: [mdx({
169-
remarkPlugins: [remarkToc],
170-
})],
171-
}
136+
export default defineConfig({
137+
markdown: {
138+
syntaxHighlight: 'prism',
139+
remarkPlugins: [remarkPlugin1],
140+
gfm: true,
141+
},
142+
integrations: [
143+
mdx({
144+
// `syntaxHighlight` inherited from Markdown
145+
146+
// Markdown `remarkPlugins` ignored,
147+
// only `remarkPlugin2` applied.
148+
remarkPlugins: [remarkPlugin2],
149+
// `gfm` overridden to `false`
150+
gfm: false,
151+
})
152+
]
153+
});
172154
```
173155

174-
### `rehypePlugins`
175-
176-
Browse [awesome-rehype](https://github.com/rehypejs/awesome-rehype) for a full curated list of [Rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md) to transform the HTML that your Markdown generates.
156+
You may also need to disable `markdown` config extension in MDX. For this, set `extendMarkdownConfig` to `false`:
177157

178-
We apply our own (non-removable) [`collect-headings`](https://github.com/withastro/astro/blob/main/packages/integrations/mdx/src/rehype-collect-headings.ts) plugin. This applies IDs to all headings (i.e. `h1 -> h6`) in your MDX files to [link to headings via anchor tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#linking_to_an_element_on_the_same_page).
179-
180-
This example applies the [`rehype-accessible-emojis`](https://www.npmjs.com/package/rehype-accessible-emojis) plugin to `.mdx` files. To customize plugin inheritance from your Markdown config or Astro's defaults, [see the `extendPlugins` option](#extendplugins).
181-
182-
```js
158+
```ts
183159
// astro.config.mjs
184-
import rehypeAccessibleEmojis from 'rehype-accessible-emojis';
160+
import { defineConfig } from 'astro/config';
161+
import mdx from '@astrojs/mdx';
185162

186-
export default {
187-
integrations: [mdx({
188-
rehypePlugins: [rehypeAccessibleEmojis],
189-
})],
190-
}
163+
export default defineConfig({
164+
markdown: {
165+
remarkPlugins: [remarkPlugin1],
166+
},
167+
integrations: [
168+
mdx({
169+
// Markdown config now ignored
170+
extendMarkdownConfig: false,
171+
// No `remarkPlugins` applied
172+
})
173+
]
174+
});
191175
```
192176

193177
### `recmaPlugins`

packages/integrations/mdx/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
"rehype-raw": "^6.1.1",
4444
"remark-frontmatter": "^4.0.1",
4545
"remark-gfm": "^3.0.1",
46-
"remark-smartypants": "^2.0.0",
4746
"shiki": "^0.11.1",
4847
"unist-util-visit": "^4.1.0",
4948
"vfile": "^5.3.2"

0 commit comments

Comments
 (0)