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:


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'
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.mdxfile 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.


