Building a Markdown Blog Platform Using Astro and MDX
In the world of static site generation, Astro has quickly become a favorite among developers who want to build fast, flexible, and content-focused websites. Combined with MDX , a format that lets you write Markdown and embed JSX components , you can create a powerful, component-rich blog platform without sacrificing speed or simplicity.
Whether you’re building a personal blog, a documentation site, or a content-heavy project, this stack gives you the best of both worlds: Markdown simplicity and modern frontend interactivity.
In this guide, we’ll walk through how to set up a Markdown blog using Astro and MDX, covering content structure, dynamic routing, layout components, and customization tips.
Why Use Astro and MDX?
Astro Highlights
- Zero-JavaScript by default
- Component support from React, Vue, Svelte, etc.
- Built-in Markdown support
- Lightning-fast page loads
- Partial hydration for interactivity only when needed
MDX Benefits
- Write Markdown and include interactive components like charts, embeds, or custom UI blocks
- Richer content experience for readers
- Perfect for technical blogs, tutorials, and documentation
Step 1: Initialize an Astro Project
First, create a new Astro project:
npm create astro@latest
Follow the prompts to set up the project. Choose an empty starter or blog template depending on your preference.
Navigate into your project folder and install dependencies:
cd my-blog
npm install
Step 2: Install the MDX Integration
Astro doesn’t support MDX out of the box, but it’s easy to enable:
npm install @astrojs/mdx
Then, add it to your astro.config.mjs:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
integrations: [mdx()],
});
Now you can write .mdx files and import components directly into them.
Step 3: Set Up Your Blog Folder Structure
Create a /src/content/blog directory to hold your posts:
/src
├── /components
├── /layouts
└── /content
└── /blog
├── my-first-post.mdx
└── another-post.mdx
Example my-first-post.mdx:
---
title: "My First Post"
date: "2025-06-30"
tags: ["astro", "blog"]
---
# Hello, World!
Welcome to my blog built with **Astro** and **MDX**.
<Callout>This is an MDX component!</Callout>
Step 4: Create a Layout for Blog Posts
In /src/layouts/BlogLayout.astro:
---
const { title, date } = Astro.props;
---
<article>
<h1>{title}</h1>
<time>{date}</time>
<slot />
</article>
Now use this layout in your MDX files:
---
layout: ../layouts/BlogLayout.astro
title: "My First Post"
date: "2025-06-30"
---
# Welcome!
This is your first post with a custom layout.
Step 5: Display Blog Posts on the Homepage
In src/pages/index.astro, fetch and list your posts:
---
import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
---
<ul>
{posts.map(post => (
<li>
<a href={`/blog/${post.slug}/`}>{post.data.title}</a> , {post.data.date}
</li>
))}
</ul>
Use getStaticPaths for dynamic routing if you plan to create individual blog post pages from slugs.
Step 6: Add Components to Your MDX
In /src/components/Callout.astro:
<aside style="border-left: 4px solid #007acc; padding-left: 1rem; margin: 1rem 0;">
<slot />
</aside>
Import and use it in any MDX file:
import Callout from '../components/Callout.astro'
<Callout>This is a reusable callout box.</Callout>
Bonus: Tailwind, RSS, and Dark Mode
- Add Tailwind CSS for easy styling:
npm install -D tailwindcss - Generate an RSS feed using Astro plugins
- Implement dark/light mode with CSS variables or a toggle component
Conclusion
Astro and MDX are a powerful combination for building content-rich, blazing-fast blogs. You get the best of static site performance, modern component-driven design, and Markdown simplicity , all with the flexibility to scale as your content grows.
Whether you’re a developer, writer, or both, this stack empowers you to create a platform that’s clean, fast, and delightful to maintain.
Disclaimer
Article written with the help of AI.
Read the full Disclaimer HERE