Enhancing Your Astro Site with MDX: A Practical Guide
By ⚡ min read
<h2 id="introduction">Introduction</h2>
<p>Markdown has transformed the way developers write content for the web. Its simple syntax reduces the need for verbose HTML and automatically handles typographic niceties like converting straight quotes into curly ones. Astro, the modern static site generator, supports Markdown natively through <code>.md</code> files. However, the combination of Markdown and Astro can be taken to the next level with two powerful enhancements: <strong>MDX</strong> and <strong>Markdown Components</strong>. In this article, we’ll focus on MDX and show you how it unlocks new possibilities for content-rich Astro projects.</p><figure style="margin:20px 0"><img src="https://i0.wp.com/css-tricks.com/wp-content/uploads/2026/02/mdx-astro.webp" alt="Enhancing Your Astro Site with MDX: A Practical Guide" style="width:100%;height:auto;border-radius:8px" loading="lazy"><figcaption style="font-size:12px;color:#666;margin-top:5px">Source: css-tricks.com</figcaption></figure>
<h2 id="what-is-mdx">What is MDX?</h2>
<p>MDX is a superset of Markdown that allows you to embed JSX and use components directly inside your Markdown files. This means you can leverage the simplicity of Markdown for writing prose while sprinkling in interactive or styled components from any frontend framework. In Astro, MDX integrates seamlessly, letting you import components from React, Svelte, Vue, or even native Astro components.</p>
<h3 id="example-embedding-components-in-mdx">Example: Embedding Components in MDX</h3>
<p>Here’s a quick demonstration. Suppose you have an Astro component and a Svelte component. In an MDX file, you can write:</p>
<pre><code>---
// Frontmatter...
---
import AstroComp from '@/components/AstroComp.astro';
import SvelteComp from '@/components/SvelteComp.svelte';
<AstroComp />
<SvelteComp />
</code></pre>
<p>This flexibility makes MDX ideal for content-heavy pages, where you want to mix narrative text with rich elements like call-to-action buttons, charts, or embedded videos.</p>
<h2 id="simplifying-markup-with-mdx">Simplifying Markup with MDX</h2>
<p>One of the biggest advantages of MDX is that it retains all Markdown syntax within JSX blocks. For example, instead of writing verbose HTML for a card component, you can use Markdown inside a <code><div></code>:</p>
<pre><code><div class="card">
### Card Title
Content goes here
- List
- Of
- Items
Second paragraph
</div>
</code></pre>
<p>Astro then processes this MDX into clean HTML:</p>
<pre><code><div class="card">
<h2>Card Title</h2>
<p>Content goes here</p>
<ul>
<li>List</li>
<li>Of</li>
<li>Items</li>
</ul>
<p>Second paragraph</p>
</div>
</code></pre>
<p>Notice how you can use <code>###</code> for headings, <code>-</code> for list items, and skip paragraph tags entirely. Writing the same structure in raw HTML would be far more tedious.</p>
<h2 id="installing-mdx-in-astro">Installing MDX in Astro</h2>
<p>Adding MDX to your Astro project is straightforward thanks to the official integration. Run the following command in your project directory:</p>
<pre><code>npx astro add mdx
</code></pre>
<p>This will install the necessary package and update your Astro configuration file. Once done, you can start creating files with the <code>.mdx</code> extension and use all the features described above.</p>
<h2 id="three-ways-to-use-mdx">Three Ways to Use MDX</h2>
<p>These methods work for both standard Markdown and MDX files. Here are the primary approaches:</p>
<h3 id="import-directly">1. Import Directly into an Astro File</h3>
<p>The simplest method is to import an MDX file as a component and use it directly in your template. For example:</p>
<pre><code>---
import MDXContent from '../components/MyContent.mdx';
---
<MDXContent />
</code></pre>
<p>This makes MDX files function like reusable partials, perfect for things like testimonials, sidebars, or embedded content blocks.</p>
<h3 id="through-content-collections">2. Through Content Collections</h3>
<p>For larger sites, content collections are the recommended way to manage MDX files. First, configure your collection to include both <code>.md</code> and <code>.mdx</code> patterns:</p>
<pre><code>// src/content.config.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 };
</code></pre>
<p>Then, in an Astro page, you can retrieve an entry and render it:</p>
<pre><code>---
import { getEntry, render } from 'astro:content';
const { slug } = Astro.props;
const post = await getEntry('blog', slug);
const { Content } = await render(post);
---
<Content />
</code></pre>
<p>This approach gives you a powerful, type-safe way to handle multiple posts, complete with frontmatter validation.</p>
<h3 id="through-a-layout">3. Through a Layout</h3>
<p>You can also apply a layout to all collected MDX files by setting a default layout in your content collection configuration or by using Astro’s built-in layout frontmatter property. This ensures consistent styling across all your content pages without repeating code.</p>
<h2 id="conclusion">Conclusion</h2>
<p>MDX is a game-changer for Astro developers who want the best of both worlds: the simplicity of Markdown and the power of component-driven design. Whether you import MDX directly, leverage content collections, or use layouts, you’ll find that MDX streamlines your workflow and makes your content more expressive. Give it a try in your next Astro project, and experience the love between Markdown and Astro in a whole new way.</p>