Markdown to MDX migration guide
Introduction
Migrating from traditional Markdown (.md) to MDX (.mdx) unlocks the ability to use typed, interactive React components inside your content. If you're moving to a modern CMS like TinaCMS or working in a Next.js-based static site, this guide shows how to automate the conversion of custom Markdown content into clean MDX.
At a glance
You need this if:
- You're adopting MDX for React-based content rendering
- Your Markdown files use custom containers e.g. YouTube embeds
- You want to avoid manually rewriting thousands of files
Key Migration Challenges
- Legacy shortcodes and custom syntax not MDX-compatible
- MDX requires valid JSX — raw HTML and plugins won’t work
- Markdown plugins are not portable
- Manual conversion is slow and error-prone
Script Overview
We built a Python script that:
- Recursively scans .md files
- Detects custom blocks using regex
- Replaces each with JSX components
- Cleans up formatting artifacts (e.g.
<!--endintro-->) - Outputs .mdx files
Block Types We Support
Here are the key Markdown patterns our script handles (some of these are unique to the project it was developed for):
Original Format | What It Represents | Converted To |
|---|---|---|
| Info or aside boxes |
|
| Emails with subject, body, etc. |
|
| Image with a feedback label |
|
| Image with size/border variants |
|
| Standalone images with captions |
|
| Styled caption text |
|
| YouTube video with a description |
|
These reflect common patterns we used in the original Markdown content.
Example Conversion (Before & After)
Before (Markdown):
::: email-template| | || -------- | --- || To: | XXX || Cc: | YYY || Bcc: | ZZZ || Subject: | {{ EMAIL SUBJECT }} |::: email-content### Hi XXX,{{ EMAIL CONTENT }}::::::::: goodFigure: Good example - Nice email template:::::: good:::`youtube: https://www.youtube.com/watch?v=dQw4w9WgXcQ`**Watch this classic hit**
After (MDX):
<emailEmbedfrom=""to="XXX"cc="YYY"bcc="ZZZ"subject="{{ EMAIL SUBJECT }}"body={<>## Hi XXX,{{ EMAIL CONTENT }}</>}figureEmbed={{preset: "goodExample",figure: "Good example - Nice email template",shouldDisplay: true}}/><imageEmbedalt="Image"size="large"showBorder={true}figureEmbed={{preset: "goodExample",figure: 'Well-structured diagram',shouldDisplay: true}}src="diagram.png"/><youtubeEmbed url="https://www.youtube.com/watch?v=dQw4w9WgXcQ" description="Watch this classic hit" />
Rendered email template:
Running the Script
To convert a single file:
python convert_md_to_mdx.py path/to/rule.md
To convert all files:
python convert_md_to_mdx.py
After conversion, start your local TinaCMS site and browse the converted pages to make sure that custom blocks (videos, asides, emails, images, etc.) render correctly.
Extending the Script
- Add new regex patterns for custom containers
- Modify JSX output to match your component APIs
- Tune parsing logic for edge cases or metadata
Final Notes
This script made it possible to convert thousands of Markdown files into clean, structured MDX suitable for modern frameworks.
If you're working on a similar migration and want help adapting or extending this approach, the team at SSW has experience with MDX and TinaCMS projects and can assist if needed.
→ View the script: convert_md_to_mdx.py