Ajouter un blog en MDX dans Next.js 16
Le tutoriel que j'ai suivi pour ce site : des articles en fichiers, sans base de données, avec Turbopack et la coloration du code.
Lithor
Sommaire
Envie d'un blog sans base de données ni service externe ? Avec MDX, un article est un fichier de votre dépôt. Voici les étapes que j'ai suivies pour ce site, avec les pièges rencontrés.
Installer les paquets
Le guide officiel demande quatre paquets. J'ajoute deux plugins pour les identifiants de titres et la coloration du code.
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
npm install rehype-slug rehype-pretty-code shikiConfigurer Next.js
Le fichier de configuration déclare les extensions de pages et branche MDX. Avec Turbopack, les plugins se donnent par leur nom (une chaîne), car des fonctions JavaScript ne peuvent pas être passées au code Rust.
import createMDX from "@next/mdx";
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
pageExtensions: ["ts", "tsx", "md", "mdx"],
};
const withMDX = createMDX({
options: {
rehypePlugins: [
"rehype-slug",
["rehype-pretty-code", { theme: { light: "github-light", dark: "github-dark-dimmed" } }],
],
},
});
export default withMDX(nextConfig);Créer le fichier de composants
Avec l'App Router, mdx-components.tsx est obligatoire. C'est aussi l'endroit pour remplacer un élément HTML par votre composant.
import type { MDXComponents } from "mdx/types";
export function useMDXComponents(): MDXComponents {
return {};
}Charger un article depuis une route
Une route dynamique importe le fichier dont le nom correspond au paramètre. generateStaticParams produit les pages au build, et dynamicParams = false renvoie une 404 pour tout le reste.
export const dynamicParams = false;
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const { default: Post } = await import(`@/content/blog/${slug}.mdx`);
return <Post />;
}Notez que params est une promesse : il faut l'attendre avant de lire slug.
Lister les articles
Pour la liste, je lis le dossier avec fs, puis j'importe chaque fichier pour récupérer son export meta. Le temps de lecture se calcule à partir du nombre de mots du fichier brut.
Ce que j'en retiens
- Les articles sont versionnés avec le code, chaque correction laisse une trace.
- Aucun service tiers : le blog fonctionne hors ligne en développement.
- Ajouter un article demande un nouveau build, ce qui convient à un site personnel.