How to Use MDX in Astro for Richer Content
Introduction
Markdown simplifies writing by reducing markup and automatically handling typographic conventions like converting straight apostrophes to proper quotation marks. Astro natively supports Markdown through .md files, but you can take your content further with MDX—a superset of Markdown that lets you embed components and JSX directly. This guide walks you through enhancing your Astro project with MDX, covering installation, setup, and three practical ways to use it. By the end, you'll be able to create richer, more interactive content without sacrificing Markdown's ease of use.

What You Need
- An existing Astro project (version 4.0 or later recommended)
- Node.js (version 18 or later)
- A package manager (npm, yarn, or pnpm)
- Basic familiarity with Markdown and Astro file structure
Step-by-Step Guide
Step 1: Install the MDX Integration
Astro provides an official integration to add MDX support. Open your terminal in the project root and run one of the following commands:
npm install @astrojs/mdx
or
yarn add @astrojs/mdx
or
pnpm add @astrojs/mdx
This package brings MDX parsing and component handling into your build pipeline.
Step 2: Configure Astro to Use MDX
Add the integration to your astro.config.mjs file:
import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; export default defineConfig({ integrations: [mdx()] });Save the file. Astro will now recognize
.mdxfiles and process them accordingly.Step 3: Create Your First MDX File
Create a file with the
.mdxextension, for examplesrc/pages/content-card.mdx. You can use standard Markdown syntax, but also import components and write JSX:--- title: "Interactive Card" --- import Button from '../components/Button.astro'; <div class="card"> ## Card Title Here's some Markdown content inside a div. - List item one - List item two <Button label="Click Me" /> </div>Astro will render the Markdown within the div to proper HTML:
##becomes an<h2>, list items become<li>, and the Button component gets injected. This is a huge time-saver compared to writing all that HTML manually.Step 4: Use MDX in Your Project
There are three primary ways to incorporate MDX content into Astro. Each method works for standard Markdown too, but MDX adds component superpowers.
Method A: Import MDX Directly into an Astro Page
Treat an MDX file as a component. For instance, in
src/pages/index.astro:--- import ContentCard from './content-card.mdx'; --- <html> <body> <ContentCard /> </body> </html>This is perfect for reusing small pieces of content—like a testimonial or a feature box—across multiple pages. MDX functions as a partial you can embed anywhere.
Method B: Use MDX with Content Collections
For blog posts or documentation, content collections offer structured file loading. First, define your collection in
src/content.config.ts(or.js):import { defineCollection } from 'astro:content'; import { glob } from 'astro/loaders'; const blog = defineCollection({ loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/blog" }), }); export const collections = { blog };Now, place your MDX files in
src/blog/. To render a specific entry:--- import { getEntry, render } from 'astro:content'; const { slug } = Astro.props; const post = await getEntry('blog', slug); const { Content } = await render(post); --- <Content />This automatically handles frontmatter and component imports, making it ideal for large content sets.
Method C: Apply a Layout to MDX Files
You can specify a layout in the frontmatter of an MDX file. Create a layout component (e.g.,
src/layouts/ArticleLayout.astro) and then reference it:--- layout: '../../layouts/ArticleLayout.astro' title: "My Blog Post" --- # Welcome This content will be wrapped by the layout. You can import components here too.When Astro renders this page, it injects the MDX content into the layout's
<slot />. This gives you consistent styling across all your posts while keeping content clean.Tips for Working with MDX in Astro
- Use meaningful filenames: Organize MDX files into folders like
src/blog/orsrc/components/based on their role. - Keep imports lean: Only import components you actually use inside the MDX file to avoid unnecessary bundle size.
- Leverage Astro components: You can use components from any framework (React, Svelte, Vue) as long as the integration is installed. For example, a Svelte button works inside MDX.
- Test rendering: Run
npm run buildto catch any import errors early. The dev server also refreshes on MDX changes. - Combine with content collections: For scalability, use content collections rather than direct imports. It gives you automatic routing and schema validation.
- Don't overuse JSX: MDX is most powerful when you mix Markdown with occasional components. Avoid writing large chunks of raw JSX—it defeats Markdown's readability.
Conclusion
MDX bridges the simplicity of Markdown and the flexibility of component-based development. By installing the @astrojs/mdx integration, configuring your project, and using one of the three methods—direct import, content collections, or layouts—you can create dynamic, rich content with minimal effort. Start by converting a simple Markdown page to MDX, add a custom component, and see how much cleaner your code becomes. Happy building!