MDX Components Showcase
A comprehensive test of every UI component available in the blog MDX system — headings, code blocks, callouts, quotes, math, tables, and more.
- #MDX
- #React
- #Next.js
- #Testing
MDX Components Showcase
Introduction
This post is a comprehensive showcase of every UI component available in the blog MDX system. It tests headings, paragraphs, inline formatting, code blocks, callouts, quote blocks, math blocks, tables, lists, images, embeds, and more.
Let's start with some basic italic text, some bold text, and some `inline code` to verify the fundamentals work.
Here is a link to the Next.js docs and an internal link to test link rendering.
Heading Level 2
This section tests h2 headings with the `#` hover indicator and HashScroll anchor behavior.
Heading Level 3
A nested h3 heading under the h2 to verify indentation and sizing differences.
Heading Level 4
The smallest tracked heading level. All three should appear in the Table of Contents sidebar.
Code Blocks
JavaScript
1function fibonacci(n) {
2 if (n <= 1) return n;
3 return fibonacci(n - 1) + fibonacci(n - 2);
4}
5
6// Generate first 10 Fibonacci numbers
7const sequence = Array.from({ length: 10 }, (_, i) => fibonacci(i));
8console.log(sequence); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]1function fibonacci(n) {
2 if (n <= 1) return n;
3 return fibonacci(n - 1) + fibonacci(n - 2);
4}
5
6// Generate first 10 Fibonacci numbers
7const sequence = Array.from({ length: 10 }, (_, i) => fibonacci(i));
8console.log(sequence); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]TypeScript with React
1import { useState, useEffect } from "react";
2
3interface User {
4 id: number;
5 name: string;
6 email: string;
7}
8
9export default function UserList() {
10 const [users, setUsers] = useState<User[]>([]);
11 const [loading, setLoading] = useState(true);
12
13 useEffect(() => {
14 fetch("/api/users")
15 .then((res) => res.json())
16 .then((data) => {
17 setUsers(data);
18 setLoading(false);
19 });
20 }, []);
21
22 if (loading) return <p>Loading...</p>;
23
24 return (
25 <ul>
26 {users.map((user) => (
27 <li key={user.id}>
28 {user.name} — {user.email}
29 </li>
30 ))}
31 </ul>
32 );
33}1import { useState, useEffect } from "react";
2
3interface User {
4 id: number;
5 name: string;
6 email: string;
7}
8
9export default function UserList() {
10 const [users, setUsers] = useState<User[]>([]);
11 const [loading, setLoading] = useState(true);
12
13 useEffect(() => {
14 fetch("/api/users")
15 .then((res) => res.json())
16 .then((data) => {
17 setUsers(data);
18 setLoading(false);
19 });
20 }, []);
21
22 if (loading) return <p>Loading...</p>;
23
24 return (
25 <ul>
26 {users.map((user) => (
27 <li key={user.id}>
28 {user.name} — {user.email}
29 </li>
30 ))}
31 </ul>
32 );
33}Python
1from dataclasses import dataclass
2from typing import List
3
4@dataclass
5class Point:
6 x: float
7 y: float
8
9 def distance_to(self, other: "Point") -> float:
10 return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
11
12def convex_hull(points: List[Point]) -> List[Point]:
13 """Compute the convex hull using Graham scan."""
14 points = sorted(points, key=lambda p: (p.x, p.y))
15 lower = []
16 for p in points:
17 while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
18 lower.pop()
19 lower.append(p)
20 return lower1from dataclasses import dataclass
2from typing import List
3
4@dataclass
5class Point:
6 x: float
7 y: float
8
9 def distance_to(self, other: "Point") -> float:
10 return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
11
12def convex_hull(points: List[Point]) -> List[Point]:
13 """Compute the convex hull using Graham scan."""
14 points = sorted(points, key=lambda p: (p.x, p.y))
15 lower = []
16 for p in points:
17 while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
18 lower.pop()
19 lower.append(p)
20 return lowerShell / Bash
1#!/bin/bash
2set -euo pipefail
3
4echo "Setting up development environment..."
5
6# Install dependencies
7npm install
8
9# Run database migrations
10npx prisma migrate dev
11
12# Start the dev server
13npm run dev1#!/bin/bash
2set -euo pipefail
3
4echo "Setting up development environment..."
5
6# Install dependencies
7npm install
8
9# Run database migrations
10npx prisma migrate dev
11
12# Start the dev server
13npm run devTerminal
npm create next-app@latest my-app
cd my-app
npm install
npm run devCSS
1.container {
2 display: grid;
3 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
4 gap: 1.5rem;
5 padding: 2rem;
6}
7
8.card {
9 border-radius: 1rem;
10 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
12 transition: transform 0.3s ease;
13}
14
15.card:hover {
16 transform: translateY(-4px);
17}1.container {
2 display: grid;
3 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
4 gap: 1.5rem;
5 padding: 2rem;
6}
7
8.card {
9 border-radius: 1rem;
10 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
12 transition: transform 0.3s ease;
13}
14
15.card:hover {
16 transform: translateY(-4px);
17}JSON
1{
2 "name": "baiyuechu.dev",
3 "version": "2.0.0",
4 "dependencies": {
5 "next": "^15.0.0",
6 "react": "^19.0.0",
7 "next-mdx-remote": "^5.0.0"
8 }
9}1{
2 "name": "baiyuechu.dev",
3 "version": "2.0.0",
4 "dependencies": {
5 "next": "^15.0.0",
6 "react": "^19.0.0",
7 "next-mdx-remote": "^5.0.0"
8 }
9}Callouts
This is an info callout. It's great for highlighting important information
that readers should pay attention to. You can use `inline code` and bold
inside callouts.
This is a warning callout. Be careful when modifying configuration files without backing them up first!
This is a success callout. Your deployment completed successfully and all tests passed.
This is an error callout. The build failed due to a missing dependency.
Run `npm install` to fix this.
This is a tip callout. You can speed up your build by enabling the
Turbopack bundler with `next dev --turbopack`.
Quote Blocks
Classic Style
The best way to predict the future is to invent it.
Frame Style
Any sufficiently advanced technology is indistinguishable from magic.
Colors Style
Simplicity is the ultimate sophistication.
Talk is cheap. Show me the code.
Color Highlights
Here is some text with blush-rose highlighting and ocean-amber highlighting and lavender-mist highlighting to test the color highlight component.
Tables
| Feature | Status | Notes |
|---|---|---|
| MDX Blog Posts | Done | Full parity with Sanity |
| MDX Projects | Done | Same styling as blog |
| Code Blocks | Done | macOS dots, syntax highlighting |
| Callouts | Done | All 5 types supported |
| Quote Blocks | Done | Classic, frame, colors styles |
| Math Blocks | Done | KaTeX rendering |
| Tables | Done | GFM markdown tables |
Lists
Unordered List
- First item in the unordered list
- Second item with some bold text and
`inline code` - Third item with a link to somewhere
- Fourth item to test spacing
Ordered List
- Step one: Install the dependencies
- Step two: Configure the environment
- Step three: Run the development server
- Step four: Deploy to production
Blockquote
The computer programmer is a creator of universes for which he alone is the lawgiver. No playwright, no stage director, no emperor, however powerful, has ever exercised such absolute authority to arrange a stage or field of battle. — Joseph Weizenbaum
YouTube Embed
Loading video...
Image
Mixed Content Section
Combining Components
Here's a realistic example mixing multiple components. When building a Next.js application with `App Router`, you need to understand the rendering model:
Server Components are the default in Next.js 13+. Add `"use client"` only when
you need interactivity, browser APIs, or React hooks like `useState`.
1// This is a Server Component by default
2export default async function Page() {
3 const data = await fetch("https://api.example.com/posts");
4 const posts = await data.json();
5
6 return (
7 <main>
8 {posts.map((post) => (
9 <article key={post.id}>
10 <h2>{post.title}</h2>
11 <p>{post.excerpt}</p>
12 </article>
13 ))}
14 </main>
15 );
16}1// This is a Server Component by default
2export default async function Page() {
3 const data = await fetch("https://api.example.com/posts");
4 const posts = await data.json();
5
6 return (
7 <main>
8 {posts.map((post) => (
9 <article key={post.id}>
10 <h2>{post.title}</h2>
11 <p>{post.excerpt}</p>
12 </article>
13 ))}
14 </main>
15 );
16}The key formula for performance optimization:
The fastest code is the code that never runs on the client.
Conclusion
If all the components above render correctly with the same styling as the Sanity-powered blog, the migration is complete and working. Every heading should have a `#` on hover, code blocks should have macOS dots with language logos, callouts should have colored accent bars, and quote blocks should have their distinct styles.
Join Baiyuechu Newsletter!
Get notified when I publish new articles, tutorials, and project updates. Subscribe for insights and actionable content.

_hello world_