Loading...
Loading...

Anders Planck / June 15, 2024 • 2 min read
MDX is a powerful format that combines Markdown with JSX, allowing you to write interactive content with React components directly in your markdown files. It's perfect for documentation, blogs, and any content that needs both rich formatting and dynamic functionality.
current votes: 0
First, install MDX and related dependencies using Bun:
bun add @next/mdx @mdx-js/loader @mdx-js/react @types/mdxCreate or update your next.config.mjs file to enable MDX support:
import createMDX from '@next/mdx'
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
experimental: {
mdxRs: true,
},
}
const withMDX = createMDX({
options: {
remarkPlugins: [],
rehypePlugins: [],
},
})
export default withMDX(nextConfig)Create a mdx-components.tsx file in your project root:
import type { MDXComponents } from 'mdx/types'
import Image, { ImageProps } from 'next/image'
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
h1: ({ children }) => (
<h1 className="text-4xl font-bold mb-4">{children}</h1>
),
h2: ({ children }) => (
<h2 className="text-3xl font-semibold mb-3 mt-8">{children}</h2>
),
h3
Create a new file app/blog/my-post.mdx:
---
title: "My First MDX Post"
date: "2024-01-15"
---
# Welcome to My Post
This is a paragraph with **bold** and *italic* text.
<CustomButton>Click Me</CustomButton>
## Code Examples
Here's some JavaScript:
\`\`\`javascript
const greeting = "Hello, MDX!"
console.log(greeting)
\`\`\`Import and use custom components in your MDX:
import { Alert } from '@/components/ui/alert'
import { Card } from '@/components/ui/card'
<Alert>
This is an important message!
</Alert>
<Card>
<h3>Card Title</h3>
<p>Card content goes here</p>
</Card>Add metadata to your MDX files using frontmatter:
---
title: "Advanced MDX"
author: "Anders Planck"
publishedAt: "2024-06-15"
tags: ["mdx", "nextjs", "react"]
---
Your content here...Load components dynamically:
import dynamic from 'next/dynamic'
export const DynamicChart = dynamic(() => import('@/components/chart'), {
loading: () => <p>Loading chart...</p>
})
<DynamicChart data={chartData} />Pass props to your MDX page:
// app/blog/[slug]/page.tsx
import { MDXRemote } from 'next-mdx-remote/rsc'
export default function BlogPost({ params }: { params: { slug: string } }) {
return (
<MDXRemote
source={content}
components={customComponents}
options={{
mdxOptions: {
remarkPlugins: [],
rehypePlugins: [],
},
}}
/>
)
}bun add rehype-highlight rehype-pretty-code shikiimport rehypePrettyCode from 'rehype-pretty-code'
const withMDX = createMDX({
options: {
rehypePlugins: [
[
rehypePrettyCode,
{
theme: 'github-dark',
keepBackground: false,
},
],
],
},
})content directoryimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'
<Tabs defaultValue="install">
<TabsList>
<TabsTrigger value="install">Installation</TabsTrigger>
<TabsTrigger value="usage">Usage</TabsTrigger>
</TabsList>
<TabsContent value="install">
Installation instructions...
</TabsContent>
<TabsContent value="usage">
Usage examples...
</TabsContent>
</Tabs>import { Counter } from '@/components/counter'
import { CodeSandbox } from '@/components/code-sandbox'
Try this interactive counter:
<Counter initialValue={0} />
Edit the code live:
<CodeSandbox template="react" />import { ProjectCard } from '@/components/project-card'
import { ImageGallery } from '@/components/image-gallery'
<ProjectCard
title="My Project"
description="Project description"
image="/project.png"
link="/projects/my-project"
/>
<ImageGallery images={projectImages} />// Add error boundaries
import { ErrorBoundary } from 'react-error-boundary'
<ErrorBoundary fallback={<div>Something went wrong</div>}>
<YourMDXContent />
</ErrorBoundary>MDX is a powerful tool for creating rich, interactive content in Next.js applications. By combining the simplicity of Markdown with the power of React components, you can build engaging documentation, blogs, and content-driven applications.
Start experimenting with MDX today and unlock new possibilities for your Next.js projects!