What is MDX and Why Does Astro Use It?

MDX lets you use components inside Markdown. Here is what that means in practice and why it matters for content sites.

Published June 17, 2026
VS Code showing MDX file with component imports

If you’ve written content in Markdown before, you know its limits.

Markdown is great for text. Headings, paragraphs, lists, code blocks — all clean and readable. But the moment you need something custom — a callout box, a rating widget, a comparison table — Markdown runs out of tools.

That’s where MDX comes in.

What is MDX?

MDX is Markdown with the ability to import and use components directly inside your content.

ℹ️

Simple definition

MDX = Markdown + JSX. Write text like Markdown, drop in components like React. Astro supports it natively with one integration.

Instead of being stuck with plain text, you can import any Astro component and use it inline:

import Callout from '../../components/Callout.astro'

# My post

<Callout type="tip" title="Pro tip">
  This renders as a styled box inside your content.
</Callout>

Back to normal text.

Why Astro uses MDX

Astro is built for content sites. Content sites need more than plain text — they need callout boxes, rating displays, comparison tables, affiliate CTAs, FAQ sections.

Without MDX, you have two bad options:

  • Write raw HTML inside Markdown — ugly and fragile
  • Put all UI logic in the page template — inflexible, can’t vary per article

MDX gives you a third option: define components once, use them anywhere in your content — inline, naturally, without leaving the writing flow.

⚠️

Astro 6 note

When using MDX with Content Collections, update your glob pattern to match both file types: **/*.{md,mdx}. Without this, your .mdx files won’t be picked up by getCollection().

The practical difference

Plain Markdown post: You write text. Astro renders it. Every post looks the same structurally.

MDX post: You write text, but you can also insert components wherever they add value. A review post can have a ProsConsBox. A guide can have a warning Callout. A comparison can have a full ComparisonTable — all inline, all part of the content file itself.

How to use MDX in Astro

Step 1: Install the MDX integration:

npx astro add mdx

Step 2: Update your Content Collections glob pattern:

loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/posts' })

Step 3: Create a .mdx file and import components at the top:

---
title: My MDX Post
publishedAt: 2026-06-17T00:00:00Z
---

import Callout from '../../components/Callout.astro'

Normal Markdown text here.

<Callout type="tip" title="Remember">
  Components are imported after the frontmatter, before the body content.
</Callout>

More text here.
💡

You're reading an MDX file right now

This post itself is a .mdx file. The colored boxes you see are Callout components imported at the top of this file and dropped inline — exactly the way MDX is meant to be used.

Method 1 vs Method 2: which should you use?

Method 1 — Markdown syntax:

![MDX components render inline with your content](../../assets/images/posts/what-is-mdx-2.jpg)

MDX components render inline with your content

Simple. Works in .md and .mdx. No import needed. Best for decorative images where exact dimensions don’t matter.

Method 2 — Astro Image component:

<Image
  src={mdxImage3}
  alt="Astro Image component gives you full control over optimization"
  width={800}
  height={420}
/>
<!--Note-->

You need to import:
import { Image } from 'astro:assets'
import mdxImage2 from '../../assets/images/posts/what-is-mdx-2.jpg'
import mdxImage3 from '../../assets/images/posts/what-is-mdx-3.jpg'
Astro Image component gives you full control over optimization

More control. Explicit width and height. Better for hero images or images where you need precise lazy loading behavior. Only works in .mdx files.

When to use which:

  • Use Markdown ![]() for quick inline images in any content file
  • Use <Image /> component when you need explicit dimensions, format control, or are inside an .mdx file and already importing components

When to use MD vs MDX

Use plain .md when the post is text-only — no custom components needed. Simpler, faster to parse, easier to read in a code editor.

Use .mdx when the post needs UI components — callouts, rating boxes, comparison tables, CTAs.

Don’t convert everything to MDX by default. Keep .md files as .md and only reach for .mdx when you actually need a component.

What this means for WordPress users

In WordPress, you’d handle this with shortcodes or Gutenberg blocks. MDX is the modern equivalent — but instead of clicking a block button in the editor, you import a component and use it as JSX.

The tradeoff: more control, slightly more technical. If your content is managed by non-developers, you’ll want to pair MDX with a CMS editor like TinaCMS that can wrap these components in a visual block interface.

ℹ️

Coming up in this series

Part 3 covers TinaCMS — which lets non-developers insert MDX components through a visual editor, without ever touching raw MDX syntax. Think Gutenberg blocks, but for Astro.

Steven Doan

Written by

Steven Doan

Freelance web developer. 10+ years building WordPress sites. Now learning Astro in public.

Follow me:

Stay in the loop

New articles on Astro, WordPress, and the modern stack. No spam. Unsubscribe anytime.

UI only — backend coming in a later article.

Related Posts

📦 This is a live demo project

Built step by step in the series Learn Astro from Scratch — read the full guide on doancongtuan.com.