Content Power

MDX integration, Content Collections, and interactive documentation. The perfect foundation for blogs, docs, and content-rich sites.

MDX + Astro

MDX lets you use JSX components in Markdown. Combined with Astro's partial hydration, you get interactive content that only ships the JavaScript it needs.

Showcase Content

Live MDX Preview

Below is rendered MDX content with embedded interactive components:

🎮

Interactive MDX Demo

Experience the power of MDX with embedded interactive components

MDX Content

Interactive MDX Content

MDX lets you use JSX components directly in your Markdown content. This means you can create rich, interactive documentation and blog posts.

Embedded React Component

Here’s a fully interactive React component embedded in this MDX file:

Step CounterInteractive Component
10

This interactive React component is embedded directly in MDX content.

The component above is hydrated when it scrolls into view (client:visible), demonstrating Astro’s partial hydration in MDX content.

Custom Callout Components

Pro Tip

MDX components can be Astro components too! This callout is a static Astro component that ships zero JavaScript.

!

Warning

Remember that interactive components need a client: directive to hydrate. Without it, they render as static HTML.

i

Did you know?

Astro’s MDX integration automatically handles imports and component rendering. Just import your components and use them like HTML tags.

Code with Explanation

You can mix code blocks with interactive examples:

// This is the component used above
export default function InteractiveCounter({ step = 1 }) {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(c => c + step)}>
      Count: {count}
    </button>
  );
}

Try changing the step value in the component above to see how props work!

Another Interactive Example

Basic CounterInteractive Component
0

This interactive React component is embedded directly in MDX content.

This counter uses client:load to hydrate immediately when the page loads.

Benefits of MDX

  1. Write content naturally - Use Markdown for prose
  2. Add interactivity - Embed framework components where needed
  3. Reuse components - Same components work in pages and content
  4. Type safety - Full TypeScript support for component props
  5. Content collections - Organize and query your MDX content

Implementation

content.config.ts typescript
const showcase = defineCollection({
  loader: glob({
    pattern: '**/*.mdx',
    base: './src/content/showcase'
  }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    order: z.number().default(0),
    icon: z.string().optional(),
  }),
});
Using MDX Content astro
---
import { getCollection, render } from 'astro:content';

const entries = await getCollection('showcase');
const { Content } = await render(entries[0]);
---

<article>
  <Content />
</article>
MDX File Example mdx
---
title: "Interactive Demo"
description: "MDX with components"
---

import Counter from './Counter';
import Callout from './Callout.astro';

# Hello MDX!

<Counter client:visible />

<Callout type="tip">
  Static Astro components work too!
</Callout>
Component in MDX tsx
// Interactive component for MDX
export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(c => c + 1)}>
      Clicked {count} times
    </button>
  );
}

// Use in MDX:
// <Counter client:visible />

Content Features

MDX Support

  • + Import any component
  • + Use JSX in Markdown
  • + Partial hydration works
  • + TypeScript support

Content Collections

  • + Zod schema validation
  • + Type-safe queries
  • + Custom loaders
  • + Computed fields

Developer Experience

  • + Build-time validation
  • + Hot module reloading
  • + IDE autocomplete
  • + Error messages