Want to write blog posts using simple Markdown, but with the power of React components? That's where MDX comes in. Combine it with Tailwind CSS and Next.js, and you’ve got a clean, fast, and flexible blog setup no clunky CMS needed.
Before we start, make sure you have the following ready:
A Next.js project set up
Tailwind CSS installed and configured
Basic understanding of React/Next.js and routing
Think of MDX as Markdown with superpowers.
Regular Markdown is great for writing, but it's limited no custom components, no interactivity. MDX fixes that by letting you mix Markdown and JSX.
So you can write a blog post like this:
# Hello World
This is a paragraph.
<MyCustomComponent />
It feels like writing Markdown, but you can use React components inside it. Neat, right?
Next.js doesn't support MDX out of the box, but it's easy to add.
Install the following packages:
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
Then, update your next.config.js
file with below code. This tells Next.js to treat .mdx
and .md
files like pages or components.:
import createMDX from '@next/mdx'
/** @type {import('next').NextConfig} */
const nextConfig = {
// Configure `pageExtensions` to include markdown and MDX files
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
}
const withMDX = createMDX({
// Add markdown plugins here, as desired
extension: /\.(md|mdx)$/,
})
// Merge MDX config with Next.js config
export default withMDX(nextConfig)
mdx-components.tsx
to Customize MDX RenderingTo globally control how MDX content is rendered in your app, create a file called mdx-components.tsx
Place it in your project root — ideally at the same level as app/
or src/
.
📁 Your project might now look like:
/app
/mdx-components.tsx
/package.json
Now, open mdx-components.tsx
and add the following code:
import type { MDXComponents } from 'mdx/types'
const components: MDXComponents = {
// Example: Custom style for <h1> tags
h1: ({ children }) => (
<h1 className="text-3xl font-bold text-blue-600 mb-4">{children}</h1>
),
// You can add more custom elements here...
// p: ({ children }) => <p className="leading-relaxed">{children}</p>,
// a: ({ href, children }) => <a className="text-blue-500 underline" href={href}>{children}</a>
}
export function useMDXComponents(): MDXComponents {
return components
}
This file tells Next.js:
“Whenever I use MDX, here’s how I want my components like <h1>
, <p>
and <a>
to look.”
You can keep it simple at first or customize everything later as your design grows.
💡 This is especially useful if you want your blog posts to match the design system in your templates (colors, fonts, spacing, etc.).
Let’s create a simple folder structure for your blog:
/blog
└── hello-world.mdx
Inside hello-world.mdx
, add your first post:
# Hello World 👋
Welcome to my blog built with MDX, Tailwind, and Next.js!
This is a sample post.
We’ll use a basic layout component to wrap our posts.
Create a file: components/BlogLayout.js
export default function BlogLayout({ children }) {
return (
<main className="prose prose-lg mx-auto px-4 py-10">
{children}
</main>
);
}
✅ prose
is a Tailwind class from @tailwindcss/typography
that styles content beautifully. Make sure it's added in your Tailwind config!
Now, use this layout in your MDX page:
import BlogLayout from '../components/BlogLayout'
export default ({ children }) => <BlogLayout>{children}</BlogLayout>
# Hello World 👋
This post is using a custom layout!
If you don't want to wrap every MDX file manually, you can load layout globally using getLayout
pattern or page-level wrappers but for simplicity, manual import works just fine for now.
Want to add a dark mode? Or tweak fonts, spacing, or colors?
Tailwind makes it easy:
<main className="prose dark:prose-invert ...">
You can customize everything directly in your globals.css
to match your blog’s style or save time using a pre-built template (😉 more on that below).
Try this inside your .mdx
file:
import Alert from '../components/Alert'
# Welcome!
Here's a custom component below:
<Alert message="This is a custom alert inside MDX!" />
MDX lets you turn your blog into more than just text. You can add:
YouTube embeds
Charts
Interactive UI
Anything React can do!
You’ve just:
Set up MDX in Next.js
Styled content with Tailwind's prose
classes
Added custom components inside blog posts
That's a powerful combo for writing content and building a flexible site.
If you're building with Next.js and Tailwind CSS, and want to skip the design and layout work, we’ve got you covered.
Our premium templates are:
Built with clean Next.js + Tailwind CSS
Easy to customize
Fully responsive and production-ready
Whether you're working on a portfolio, landing page or startup site these templates help you go live faster, without starting from scratch.
👉 Check our templates now
What to write on every page of your website from homepage to contact. Clear, actionable copy tips with real examples.
Next.js & Tailwind CSS are redefining web dev in 2025. Discover why this stack powers our modern, ready-to-use templates built for speed and scalability.
Learn how ready to use website templates help startups save time, reduce costs, and launch faster so you can focus on growing your business.
Explore new PHP 8.5’s features pipe syntax, attributes on constants, NoDiscard, CLI enhancements, Intl tools and more simplified and easy to understand.
No Spam. Only high quality content and updates of our products.
Join 20,000+ other creators in our community