MDX te permite escribir JSX dentro de tus archivos Markdown, lo cual es perfecto para blogs técnicos donde necesitas componentes interactivos.
// Puedes usar componentes React en tus posts!
<CustomButton onClick={() => console.log('Click!')}>Haz clic aquí</CustomButton>
Instalación
pnpm add @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
pnpm add rehype-highlight rehype-slug rehype-autolink-headings
pnpm add gray-matter reading-time
Configuración de Next.js
Actualiza tu next.config.ts:
import createMDX from '@next/mdx';
import rehypeHighlight from 'rehype-highlight';
import rehypeSlug from 'rehype-slug';
const nextConfig = {
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
};
const withMDX = createMDX({
options: {
rehypePlugins: [rehypeHighlight, rehypeSlug],
},
});
export default withMDX(nextConfig);
Estructura de archivos
Organiza tus posts así:
content/
blog/
mi-primer-post.mdx
segundo-post.mdx
Cada post debe tener frontmatter:
---
title: 'Mi Primer Post'
date: '2025-01-15'
summary: 'Descripción del post'
tags: ['React', 'Next.js']
---
Rutas dinámicas
Crea app/blog/[slug]/page.tsx:
export async function generateStaticParams() {
const posts = getAllPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export default async function Post({ params }) {
const post = getPostBySlug(params.slug);
return <MDXRemote source={post.content} />;
}
SEO Optimization
export async function generateMetadata({ params }) {
const post = getPostBySlug(params.slug);
return {
title: post.title,
description: post.summary,
};
}
Tips finales
Checklist
Usa reading-time para mostrar tiempo de lectura, agrega highlight.js para syntax highlighting, implementa búsqueda con un simple filter(), y considera next-sitemap para SEO.