Skip to content

Commit

Permalink
[mdx] Adds usage information, taken out of the Markdown guide (#9337)
Browse files Browse the repository at this point in the history
Co-authored-by: Armand Philippot <[email protected]>
  • Loading branch information
sarah11918 and ArmandPhilippot authored Sep 7, 2024
1 parent 1296f8f commit 582c0ee
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 5 deletions.
125 changes: 120 additions & 5 deletions src/content/docs/en/guides/integrations-guide/mdx.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This **[Astro integration][astro-integration]** enables the usage of [MDX](https

## Why MDX?

MDX allows you to [use variables, JSX expressions and components within Markdown content](/en/guides/markdown-content/#mdx-only-features) in Astro. If you have existing content authored in MDX, this integration allows you to bring those files to your Astro project.
MDX allows you to use variables, JSX expressions and components within Markdown content in Astro. If you have existing content authored in MDX, this integration allows you to bring those files to your Astro project.

## Installation

Expand Down Expand Up @@ -84,13 +84,128 @@ For other editors, use the [MDX language server](https://github.com/mdx-js/mdx-a

## Usage

With the Astro MDX integration, you can [add MDX pages to your project](/en/guides/markdown-content/#markdown-and-mdx-pages) by adding `.mdx` files within your `src/pages/` directory. You can also [import `.mdx` files](/en/guides/markdown-content/#importing-markdown) into `.astro` files.
Visit the [MDX docs](https://mdxjs.com/docs/what-is-mdx/) to learn about using standard MDX features.

Astro's MDX integration adds extra features to standard MDX, including Markdown-style frontmatter. This allows you to use most of Astro's built-in Markdown features like a [special frontmatter `layout` property](/en/guides/markdown-content/#frontmatter-layout).
## MDX in Astro

See how MDX works in Astro with examples in our [Markdown & MDX guide](/en/guides/markdown-content/).
Adding the MDX integration enhances your Markdown authoring with JSX variables, expressions and components.

Visit the [MDX docs](https://mdxjs.com/docs/what-is-mdx/) to learn about using standard MDX features.
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 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}`:

```mdx title="/src/pages/posts/post-1.mdx"
export const title = 'My first MDX post'

# {title}
```

Or you can use that exported `title` in your page using `import` and `import.meta.glob()` statements:

```astro title="src/pages/index.astro"
---
const matches = await import.meta.glob('./posts/*.mdx', { eager: true });
const posts = Object.values(posts);
---
{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 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’s `slug` corresponds to the generated ID for a given heading and can be used for anchor links.
- **`<Content />`** - A component that returns the full, rendered contents of the file.
- **(any `export` value)** - MDX files can also export data with an `export` statement.

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

```mdx title="/src/pages/posts/post-1.mdx"
---
layout: '../../layouts/BlogPostLayout.astro'
title: 'My first MDX post'
---

# {frontmatter.title}
```

### Using Components in MDX

After installing the MDX integration, you can import and use both [Astro components](/en/basics/astro-components/) and [UI framework components](/en/guides/framework-components/#using-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](https://mdxjs.com/docs/what-is-mdx/#esm).

```mdx title="src/pages/about.mdx" {5-6} /<.+\/>/
---
layout: ../layouts/BaseLayout.astro
title: About me
---
import Button from '../components/Button.astro';
import ReactCounter from '../components/ReactCounter.jsx';

I live on **Mars** but feel free to <Button title="Contact me" />.

Here is my counter component, working in MDX:

<ReactCounter client:load />
```


#### Custom components with imported MDX

When rendering imported MDX content, [custom components](#assigning-custom-components-to-html-elements) can be passed via the `components` prop.

```astro title="src/pages/page.astro" "components={{...components, h1: Heading }}"
---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<!-- Creates a custom <h1> for the # syntax, _and_ applies any custom components defined in `content.mdx` -->
<Content components={{...components, h1: Heading }} />
```

:::note
Custom components defined and exported in an MDX file must be imported and then passed back to the `<Content />` component via the `components` property.
:::

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

Import your custom component into your `.mdx` file, then export a `components` object that maps the standard HTML element to your custom component:

```mdx title="src/pages/about.mdx"
import Blockquote from '../components/Blockquote.astro';
export const components = {blockquote: Blockquote}

> This quote will be a custom Blockquote
```


```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 /> <!-- Be sure to add a `<slot/>` for child content! -->
</blockquote>
```
Visit the [MDX website](https://mdxjs.com/table-of-components/) for a full list of HTML elements that can be overwritten as custom components.

## Configuration

Expand Down
6 changes: 6 additions & 0 deletions src/content/docs/en/guides/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ You may notice an imported component's `<script>` or `<style>` tags included in

Astro's build process works on the module graph: once a component is included in the template, its `<script>` and `<style>` tags are processed, optimized, and bundled, whether it appears in the final output or not. This does not apply to scripts when the `is:inline` directive is applied.

## Escaping special characters in Markdown

Certain characters have a special meaning in Markdown. You may need to use a different syntax if you want to display them. To do this, you can use [HTML entities](https://developer.mozilla.org/en-US/docs/Glossary/Entity) for these characters instead.

For example, to prevent `<` being interpreted as the beginning of an HTML element, write `&lt;`.

## Creating minimal reproductions

When troubleshooting your code, it can be helpful to create a **minimal reproduction** of the issue that you can share. This is a smaller, simplified Astro project that demonstrates your issue. Having a working reproduction in a new project helps to confirm that this is a repeatable problem, and is not caused by something else in your personal environment or existing project.
Expand Down

0 comments on commit 582c0ee

Please sign in to comment.