Converting HTML to MDX in Astro
A guide for converting HTML content into MDX format within Astro projects.
Converting HTML to MDX in Astro
MDX lets you mix Markdown, HTML-like JSX syntax, and imported components in the same document. That flexibility is useful, but it also means copied HTML often needs cleanup before it will compile.
Use this guide when you are moving existing HTML into an Astro .mdx file.
The Core Rule
MDX follows JSX parsing rules, not loose browser HTML parsing rules.
That means:
- Every tag must be closed.
- Attribute values must follow JSX rules.
- Comments must use JSX syntax.
- Simple content is usually better written as Markdown instead of HTML.
1. Fix Self-Closing Tags
Some HTML tags can appear without a closing tag in plain HTML, but MDX requires them to be self-closed.
<!-- HTML -->
<input type="text">
<br>
<img src="/hero.png" alt="Hero image">{/* MDX */}
<input type="text" />
<br />
<img src="/hero.png" alt="Hero image" />Common tags to check:
<img><br><hr><input><meta><link>
2. Convert Inline Styles
HTML uses a string for the style attribute. In MDX, style must be a JavaScript object.
<!-- HTML -->
<p style="color: blue; font-size: 14px;">Hello</p>{/* MDX */}
<p style={{ color: 'blue', fontSize: '14px' }}>Hello</p>Rules to remember:
- Use double braces:
{{ ... }}. - Convert CSS property names to camelCase.
- Wrap string values in quotes.
3. Replace HTML Comments
HTML comments are not valid in MDX.
<!-- HTML -->
<!-- This is a comment -->{/* MDX */}
{/* This is a comment */}4. Know When class Changes
This is where people often over-correct.
- In React JSX,
classusually becomesclassName. - In Astro MDX,
classis generally fine for normal markup.
If you are writing standard content inside an Astro MDX page, do not assume every class attribute needs to be renamed.
5. Prefer Markdown When Possible
Do not keep HTML just because it already exists. If the content is simple, Markdown is cleaner and easier to maintain.
| HTML | Markdown |
|---|---|
<h1>Title</h1> | # Title |
<strong>Bold text</strong> | **Bold text** |
<a href="/docs">Docs</a> | [Docs](/docs) |
Good candidates for conversion:
- headings
- paragraphs
- links
- emphasis
- lists
Keep HTML or components only when you need layout, attributes, or custom behavior.
6. Add Components Carefully
One reason to use MDX is that you can import and render components directly in the document.
import FeatureNote from '../../components/FeatureNote.astro'
# Hello World
This is a normal paragraph.
<FeatureNote title="Cool Feature">
This content is rendered inside the component.
</FeatureNote>Keep these details in mind:
- Leave a blank line after imports before the document content starts.
- Use imports only when you actually need a component.
- Prefer Markdown for normal prose even when components are available.
7. Fast Cleanup Workflow
When converting a larger HTML snippet:
- Paste the original markup into the MDX file.
- Fix self-closing tags.
- Convert inline styles and comments.
- Replace simple HTML with Markdown.
- Run the build and fix any remaining JSX parsing errors.
If you want a quick first pass, tools like Transform.tools can help convert raw HTML into JSX-style markup before you clean it up for Astro.
Quick Checklist
- All tags are properly closed.
- Inline styles use object syntax.
- Comments use
{/* ... */}. - Simple HTML has been converted to Markdown.
- Imported components render with valid MDX syntax.
Summary
The safest way to move HTML into MDX is to treat it like JSX, not like browser HTML. Clean up the syntax first, then simplify the document back into Markdown wherever possible. That keeps the file easier to read and much less likely to break during build.