Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert MDX README changes #6062

Merged
merged 22 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cuddly-donkeys-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/mdx': patch
---

Update MDX README
304 changes: 34 additions & 270 deletions packages/integrations/mdx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ npm install @astrojs/mdx

Then, apply this integration to your `astro.config.*` file using the `integrations` property:

__`astro.config.mjs`__
**`astro.config.mjs`**

```js ins={2} "mdx()"
```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

Expand Down Expand Up @@ -92,9 +92,8 @@ All [`markdown` configuration options](https://docs.astro.build/en/reference/con
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 overridden for MDX files specifically.
:::

__`astro.config.mjs`__

```js
```ts
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
Expand All @@ -103,47 +102,19 @@ import rehypeMinifyHtml from 'rehype-minify-html';
export default defineConfig({
integrations: [
mdx({
remarkPlugins: [exampleRemarkPlugin],
}),
],
});
```

…every MDX file will have `customProperty` in its frontmatter! See [our Markdown documentation](https://docs.astro.build/en/guides/markdown-content/#example-injecting-frontmatter) for more usage instructions and a [reading time plugin example](https://docs.astro.build/en/guides/markdown-content/#example-calculate-reading-time).

### Layouts
Layouts can be applied [in the same way as standard Astro Markdown](https://docs.astro.build/en/guides/markdown-content/#frontmatter-layout). You can add a `layout` to [your frontmatter](#frontmatter) like so:

```yaml
---
layout: '../layouts/BaseLayout.astro'
title: 'My Blog Post'
---
```

Then, you can retrieve all other frontmatter properties from your layout via the `frontmatter` property, and render your MDX using the default [`<slot />`](https://docs.astro.build/en/core-concepts/astro-components/#slots). See [layout props](#layout-props) for a complete list of props available.

```astro title="src/layouts/BaseLayout.astro"
---
const { frontmatter, url } = Astro.props;
---
<html>
<head>
<meta rel="canonical" href={new URL(url, Astro.site).pathname}>
<title>{frontmatter.title}</title>
</head>
<body>
<h1>{frontmatter.title}</h1>
<!-- Rendered MDX will be passed into the default slot. -->
<slot />
</body>
</html>
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeMinifyHtml],
remarkRehype: { footnoteLabel: 'Footnotes' },
gfm: false,
})
]
})
```

You can set a layout’s [`Props` type](/en/guides/typescript/#component-props) with the `MDXLayoutProps` helper.

:::note
`MDXLayoutProps` is the same as the `MarkdownLayoutProps` utility type with `rawContent()` and `compiledContent()` removed (since these are not available for `.mdx` files). Feel free to **use `MarkdownLayoutProps` instead** when sharing a layout across `.md` and `.mdx` files.
:::caution
MDX does not support passing remark and rehype plugins as a string. You should install, import, and apply the plugin function instead.
:::

📚 See the [Markdown Options reference](https://docs.astro.build/en/reference/configuration-reference/#markdown-options) for a complete list of options.
Expand All @@ -157,80 +128,8 @@ MDX will extend [your project's existing Markdown configuration](https://docs.as

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:

```html
<blockquote>
<p>A blockquote with <em>some</em> emphasis.</p>
</blockquote>
```

But what if you want to specify your own markup for these blockquotes? In the above example, you could create a custom `<Blockquote />` component (in any language) that either has a `<slot />` component or accepts a `children` prop.

```astro title="src/components/Blockquote.astro"
---
const props = Astro.props;
---

<blockquote {...props} class="bg-blue-50 p-4">
<span class="text-4xl text-blue-600 mb-2">“</span>
<slot />
</blockquote>
```

Then in the MDX file you import the component and export it to the `components` export.

```mdx title="src/pages/posts/post-1.mdx" {2}
import Blockquote from '../components/Blockquote.astro';
export const components = { blockquote: Blockquote };
```

Now, writing the standard Markdown blockquote syntax (`>`) will use your custom `<Blockquote />` component instead. No need to use a component in Markdown, or write a remark/rehype plugin! Visit the [MDX website](https://mdxjs.com/table-of-components/) for a full list of HTML elements that can be overwritten as custom components.

#### Custom components with imported `mdx`

When rendering imported MDX content, custom components can be passed via the `components` prop.

Note: An MDX file's exported components will _not_ be used unless you manually import and pass them via the `components` property. See the example below:

```astro title="src/pages/page.astro" "components={{...components, h1: Heading }}"
---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---

<Content components={{...components, h1: Heading }} />
```

### Syntax highlighting

The MDX integration respects [your project's `markdown.syntaxHighlight` configuration](https://docs.astro.build/en/guides/markdown-content/#syntax-highlighting).

We will highlight your code blocks with [Shiki](https://github.com/shikijs/shiki) by default. You can customize this highlighter using the `markdown.shikiConfig` option in your `astro.config`. For example, you can apply a different built-in theme like so:

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default defineConfig({
markdown: {
shikiConfig: {
theme: 'dracula',
},
},
integrations: [mdx()],
});
```

Visit [our Shiki configuration docs](https://docs.astro.build/en/guides/markdown-content/#shiki-configuration) for more on using Shiki with Astro.

#### Switch to Prism

You can also use the [Prism](https://prismjs.com/) syntax highlighter by setting `markdown.syntaxHighlight` to `'prism'` in your `astro.config` like so:

__`astro.config.mjs`__

```js
```ts
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

Expand All @@ -240,149 +139,38 @@ export default defineConfig({
remarkPlugins: [remarkPlugin1],
gfm: true,
},
integrations: [mdx()],
});
```

This applies a minimal Prism renderer with added support for `astro` code blocks. Visit [our "Prism configuration" docs](https://docs.astro.build/en/guides/markdown-content/#prism-configuration) for more on using Prism with Astro.

#### Switch to a custom syntax highlighter

You may want to apply your own syntax highlighter too. If your highlighter offers a remark or rehype plugin, you can flip off our syntax highlighting by setting `markdown.syntaxHighlight: false` and wiring up your plugin. For example, say you want to apply [Shiki Twoslash's remark plugin](https://www.npmjs.com/package/remark-shiki-twoslash):

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import shikiTwoslash from 'remark-shiki-twoslash';

export default defineConfig({
markdown: {
syntaxHighlight: false,
},
integrations: [
mdx({
remarkPlugins: [shikiTwoslash, { /* Shiki Twoslash config */ }],
})
],
});
```

## Configuration

### remarkPlugins
// `syntaxHighlight` inherited from Markdown

[Remark plugins](https://github.com/remarkjs/remark/blob/main/doc/plugins.md) allow you to extend your Markdown with new capabilities. This includes [auto-generating a table of contents](https://github.com/remarkjs/remark-toc), [applying accessible emoji labels](https://github.com/florianeckerstorfer/remark-a11y-emoji), and more. We encourage you to browse [awesome-remark](https://github.com/remarkjs/awesome-remark) for a full curated list!

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).

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';

export default defineConfig({
integrations: [mdx({
remarkPlugins: [remarkToc],
})],
});
```

### rehypePlugins

[Rehype plugins](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md) allow you to transform the HTML that your Markdown generates. We encourage you to browse [awesome-rehype](https://github.com/rehypejs/awesome-rehype) for a full curated list of plugins!

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).

This example applies the [`rehype-minify`](https://github.com/rehypejs/rehype-minify) plugin to `.mdx` files. To customize plugin inheritance from your Markdown config or Astro's defaults, [see the `extendPlugins` option](#extendplugins).

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import rehypeMinifyHtml from 'rehype-minify';

export default defineConfig({
integrations: [mdx({
rehypePlugins: [rehypeMinifyHtml],
})],
});
```

### extendPlugins

**Type:** `'markdown' | 'astroDefaults' | false`

**Default:** `'markdown'`

#### `markdown` (default)

By default, Astro inherits all [remark](#remarkplugins) and [rehype](#rehypeplugins) plugins from [the `markdown` option in your Astro config](https://docs.astro.build/en/guides/markdown-content/#markdown-plugins). This also respects the [`markdown.extendDefaultPlugins`](https://docs.astro.build/en/reference/configuration-reference/#markdownextenddefaultplugins) option to extend Astro's defaults. Any additional plugins you apply in your MDX config will be applied _after_ your configured Markdown plugins.

This example applies [`remark-toc`](https://github.com/remarkjs/remark-toc) to Markdown _and_ MDX, and [`rehype-minify`](https://github.com/rehypejs/rehype-minify) to MDX alone:

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
import rehypeMinify from 'rehype-minify';

export default defineConfig({
markdown: {
// Applied to .md and .mdx files
remarkPlugins: [remarkToc],
},
integrations: [mdx({
// Applied to .mdx files only
rehypePlugins: [rehypeMinify],
})],
// Markdown `remarkPlugins` ignored,
// only `remarkPlugin2` applied.
remarkPlugins: [remarkPlugin2],
// `gfm` overridden to `false`
gfm: false,
})
]
});
```

You may also need to disable `markdown` config extension in MDX. For this, set `extendMarkdownConfig` to `false`:

__`astro.config.mjs`__

```js "extendPlugins: 'astroDefaults'"
```ts
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';

export default defineConfig({
markdown: {
remarkPlugins: [remarkPlugin1],
},
integrations: [mdx({
remarkPlugins: [remarkToc],
// Astro defaults applied
extendPlugins: 'astroDefaults',
})],
});
```

#### `false`

If you don't want to extend any plugins, set `extendPlugins` to `false`:

__`astro.config.mjs`__

```js "extendPlugins: false"
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';

export default defineConfig({
integrations: [mdx({
remarkPlugins: [remarkToc],
// Astro defaults not applied
extendPlugins: false,
})],
integrations: [
mdx({
// Markdown config now ignored
extendMarkdownConfig: false,
// No `remarkPlugins` applied
})
]
});
```

Expand All @@ -392,30 +180,6 @@ These are plugins that modify the output [estree](https://github.com/estree/estr

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.

### remarkRehype

Markdown content is transformed into HTML through remark-rehype which has [a number of options](https://github.com/remarkjs/remark-rehype#options).

You can use remark-rehype options in your MDX integration config file like so:

__`astro.config.mjs`__

```js
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';

export default defineConfig({
integrations: [mdx({
remarkRehype: {
footnoteLabel: 'Catatan kaki',
footnoteBackLabel: 'Kembali ke konten',
},
})],
});
```

This inherits the configuration of `markdown.remarkRehype`. This behavior can be changed by configuring `extendPlugins`.

## Examples

* The [Astro MDX starter template](https://github.com/withastro/astro/tree/latest/examples/with-mdx) shows how to use MDX files in your Astro project.
Expand Down