MDX is a powerful format that combines Markdown with JSX, allowing you to use React components directly in your content. This post demonstrates all the custom MDX components available for creating rich, interactive blog posts.
Callout Components
Callouts are perfect for highlighting important information. We have four types available, each with its own visual style and icon.
Info Callout
Use info callouts for general information or notes that readers should be aware of.
Did you know?
MDX was first released in 2018 and has since become a popular choice for documentation sites and blogs. It combines the simplicity of Markdown with the power of React components.
Tip Callout
Tips are great for sharing best practices and helpful suggestions.
Pro Tip
When writing MDX content, you can import components at the top of your file just like in a regular React component. This keeps your content clean and organized.
Warning Callout
Warnings help readers avoid common pitfalls or potential issues.
Heads Up
Make sure to wrap your MDX content in proper JSX syntax when using components. Forgetting to close tags or using incorrect attribute names can cause build errors.
Danger Callout
Danger callouts are for critical information that could cause serious problems if ignored.
Important
Never commit sensitive information like API keys or passwords directly in your MDX files. Always use environment variables for secrets.
Code Blocks
Code blocks support syntax highlighting for various languages. They also include a convenient copy button that appears on hover.
TypeScript Example
1interface BlogPost {
2 title: string;
3 slug: string;
4 excerpt: string;
5 publishDate: string;
6 tags: string[];
7 author: string;
8 featured?: boolean;
9}
10
11async function fetchBlogPosts(): Promise<BlogPost[]> {
12 const response = await fetch("/api/posts");
13 if (!response.ok) {
14 throw new Error("Failed to fetch blog posts");
15 }
16 return response.json();
17}React/TSX Example
1import { useEffect, useState } from "react";
2
3interface Props {
4 initialCount?: number;
5}
6
7export function Counter({ initialCount = 0 }: Props) {
8 const [count, setCount] = useState(initialCount);
9
10 useEffect(() => {
11 console.log(`Count changed to ${count}`);
12 }, [count]);
13
14 return (
15 <div className="flex items-center gap-4">
16 <button onClick={() => setCount((c) => c - 1)}>-</button>
17 <span className="text-2xl font-bold">{count}</span>
18 <button onClick={() => setCount((c) => c + 1)}>+</button>
19 </div>
20 );
21}CSS Example
1.glass-effect {
2 background: rgba(255, 255, 255, 0.05);
3 backdrop-filter: blur(10px);
4 border: 1px solid rgba(255, 255, 255, 0.1);
5 border-radius: 1rem;
6}
7
8.gradient-text {
9 background: linear-gradient(135deg, #00d4ff, #7c3aed, #f472b6);
10 -webkit-background-clip: text;
11 -webkit-text-fill-color: transparent;
12 background-clip: text;
13}Link Cards
Link cards provide a visually appealing way to reference external resources. They automatically extract the domain and display it below the description.
MDX Documentation
The official MDX documentation with guides, API references, and examples for getting started with MDX.
mdxjs.comNext.js Documentation
Learn about Next.js features and API, including App Router, Server Components, and more.
nextjs.orgTailwind CSS
A utility-first CSS framework packed with classes that can be composed to build any design.
tailwindcss.comVideo Embeds
Embed videos from YouTube or Vimeo with automatic URL parsing. The component supports different aspect ratios and optional captions.
YouTube Video
Tables
Tables are styled automatically with proper borders, padding, and alternating row colors for better readability.
| Component | Purpose | Props |
|---|---|---|
Callout | Highlight important info | type, title, children |
CodeBlock | Display code with syntax | language, filename, showLineNumbers |
LinkCard | External resource links | href, title, description |
VideoEmbed | Embed YouTube/Vimeo videos | src, title, caption, aspectRatio |
Feature Comparison Table
| Feature | Basic Markdown | MDX |
|---|---|---|
| Text formatting | Yes | Yes |
| Code blocks | Yes | Yes |
| Images | Yes | Yes |
| React components | No | Yes |
| Interactive UI | No | Yes |
| Custom styling | Limited | Full control |
Blockquotes
Blockquotes are styled with a distinctive left border and subtle background to make them stand out from regular text.
The best way to predict the future is to create it.
-- Peter Drucker
You can also use blockquotes for longer passages:
MDX bridges the gap between content and code. It allows content writers to focus on writing while giving developers the flexibility to create rich, interactive experiences. This combination makes MDX an excellent choice for documentation, blogs, and any content-heavy application.
Lists
Unordered Lists
Here are the key benefits of using MDX:
- Flexibility: Mix Markdown with React components seamlessly
- Reusability: Create components once, use them everywhere
- Type Safety: Full TypeScript support for component props
- Developer Experience: Hot reloading and familiar React tooling
- Content Management: Easier to manage than pure JSX files
Ordered Lists
Steps to create an MDX blog post:
- Create a new
.mdxfile in the content directory - Add frontmatter with title, slug, and other metadata
- Import any components you need at the top of the file
- Write your content using Markdown syntax
- Insert React components where needed
- Preview your post in the development server
- Commit and deploy your changes
Nested Lists
Project structure for an MDX-powered blog:
content/blogs/my-first-post/index.mdximages/
another-post/index.mdx
src/components/mdx/callout.tsxcode-block.tsxlink-card.tsxvideo-embed.tsx
lib/mdx.ts
Combining Components
The real power of MDX comes from combining multiple components to create rich content experiences.
Component Composition
You can nest components and combine them with regular Markdown to create complex layouts. For example, this callout contains a link to the MDX documentation.
Here's a quick reference table followed by relevant resources:
| Resource Type | Link |
|---|---|
| Documentation | mdxjs.com |
| Examples | GitHub MDX examples repository |
| Community | Discord and GitHub Discussions |
MDX on GitHub
The official MDX repository with source code, issues, and discussions.
github.comDiagrams
Visualize complex systems and workflows with Mermaid diagrams and Excalidraw embeds. These components render beautiful, interactive diagrams directly in your blog posts.
Flowchart: Authentication Flow
Flowcharts are perfect for illustrating processes and decision trees. Here's an authentication flow diagram:
Sequence Diagram: API Request with Caching
Sequence diagrams show interactions between different components over time:
Entity Relationship Diagram: Blog Schema
ER diagrams help visualize database schemas and relationships:
State Diagram: Newsletter Workflow
State diagrams are ideal for modeling system states and transitions:
Excalidraw: Hand-drawn Style Diagrams
For a more informal, whiteboard-style look, use Excalidraw embeds. Great for brainstorming, architecture sketches, or explanatory drawings:
Excalidraw Integration
Excalidraw diagrams can be embedded by sharing a link from excalidraw.com. Create your diagram, click Share, and use the link in the ExcalidrawEmbed component.
Diagram Tips
- Use Flowcharts for processes and decision trees - Use Sequence Diagrams for API flows and component interactions - Use ER Diagrams for database schemas - Use State Diagrams for workflows and state machines - Use Excalidraw for informal sketches and brainstorming
Conclusion
With these MDX components, you can create engaging, interactive blog posts that go beyond traditional Markdown. Each component is designed to be:
- Easy to use - Simple, intuitive APIs
- Accessible - Built with accessibility in mind
- Customizable - Styled to match the site's design system
- Performant - Minimal JavaScript footprint
All components shown in this post are available for use in any blog post. Simply import them at the top of your MDX file and start creating!
Happy writing!