Setting Up My Blog with Next.js and MDX
A detailed guide on how I built this blog using Next.js, MDX, and a custom file-based content management system.
Setting Up My Blog with Next.js and MDX
Building this blog has been an exciting journey! I wanted to create something that was both powerful and simple to maintain. After considering various options, I settled on a custom solution using Next.js and MDX with a unique file-based approach.
Why This Stack?
Next.js
- Performance: Built-in optimizations and static generation
- Developer Experience: Hot reloading, TypeScript support, and great tooling
- Flexibility: Can handle both static and dynamic content seamlessly
MDX
- Power of Markdown: Easy to write and read
- React Integration: Can include interactive components when needed
- Extensibility: Custom renderers and plugins
The File Structure
Instead of using folders for each post, I implemented a date-prefixed naming system:
src/app/blog/
├── 2025-08-30-my-first-blog-post.mdx
├── 2025-08-31-setting-up-my-blog.mdx
└── 2025-09-01-upcoming-post.mdx
This approach has several advantages:
- Chronological Organization: Posts are naturally sorted by date
- Simple URLs: Clean slug-based URLs like
/blog/setting-up-my-blog - Easy Management: No nested folder structure to maintain
- Git Friendly: Clear history and easy to track changes
Key Features
🎯 Automatic Discovery
The system automatically scans the blog directory and discovers posts without manual configuration:
export function getAllPosts(): BlogPost[] {
const blogDir = path.join(process.cwd(), "src/app/blog");
const files = fs.readdirSync(blogDir);
// Parse each file and extract metadata
// ...
}
🔒 Hidden Posts
Posts can be marked as hidden for drafts or private content:
export const metadata = {
title: "My Draft",
description: "Work in progress...",
robots: "noindex, nofollow", // Prevents search engine indexing
};
📝 Rich Content Rendering
Custom markdown renderer with:
- Syntax highlighting for code blocks
- Anchor links for headings
- Responsive tables and images
- Custom styling for all elements
🚀 Easy Post Creation
Simple script to create new posts:
bun run new-post "My Amazing Post Title"
# Creates: 2025-08-31-my-amazing-post-title.mdx
Technical Implementation
The core of the system revolves around three main utilities:
- File Scanner: Automatically discovers and parses blog posts
- Metadata Extractor: Reads frontmatter and metadata exports
- Content Renderer: Processes markdown with custom components
Dynamic Routing
Using Next.js dynamic routes with [slug] to handle clean URLs while maintaining the date-prefixed file structure.
SEO Optimization
- Automatic sitemap generation
- Meta tags from post metadata
- Robots.txt with hidden post exclusions
Performance Considerations
- Static Generation: All posts are pre-rendered at build time
- Code Splitting: Each post is a separate chunk
- Image Optimization: Next.js handles image optimization automatically
- Lazy Loading: Syntax highlighting only loads when needed
What's Next?
Some features I'm planning to add:
- Full-text search functionality
- Tag-based filtering
- RSS feed generation
- Related posts suggestions
- Comment system integration
Conclusion
This setup gives me the perfect balance of simplicity and power. Writing posts is as easy as creating a new .mdx file, while still having access to all the dynamic features of React when needed.
The best part? No database, no complex CMS, just files and code. Sometimes the simplest solutions are the most elegant ones.
Want to build something similar? The entire setup is based on modern web standards and can be easily adapted for your own projects. Feel free to reach out if you have questions!