Comment nous avons construit le blog byte5
Nous voulions un blog qui donne la même impression que le reste de byte5.ai : rapide, statique, sans base de données, sans verrouillage fournisseur. Pas de CMS headless, pas d'API externe — le contenu vit sous forme de fichiers dans le dépôt et passe par le même processus de revue que le code.
Cet article parcourt l'architecture qui le sous-tend et pourquoi elle passe bien à l'échelle pour une équipe multilingue.
Le contenu sous forme de fichiers#
Chaque article est un fichier MDX par langue plus une entrée typée dans le registre. Le registre contient tous les champs indépendants de la langue — date, tags, auteur, couverture :
export const posts: BlogPostMeta[] = [
{
slug: "wie-wir-den-byte5-blog-gebaut-haben",
publishedAt: "2026-05-20",
tags: ["MDX", "Next.js", "Engineering", "byte5"],
authorId: "christian-wendler",
sourceLanguage: "de",
},
];L'avantage : le filtrage et le tri dans la vue d'ensemble fonctionnent uniquement sur ces données typées. Le texte lui-même reste là où il doit être — dans le fichier MDX.
Le contenu appartient au dépôt, pas à une base de données. Ainsi chaque article reçoit le même soin que n'importe quelle modification de code : branche, revue, diff.
Du markdown à un composant serveur#
Les fichiers MDX sont compilés au moment du build/rendu et rendus comme un React Server Component. La coloration syntaxique est gérée par Shiki — entièrement sur le serveur, sans envoyer le moindre kilo-octet de JavaScript au navigateur :
Pourquoi aucune bibliothèque client ?#
La coloration, les ancres de titres et le markdown façon GitHub se produisent tous au moment du rendu. Le navigateur reçoit du HTML terminé. Cela garde les pages légères et les Core Web Vitals au vert.
Préparer, ne pas se précipiter#
Un détail qui comptait pour nous : les articles dont la date de publication est dans le futur n'apparaissent pas dans la vue d'ensemble — mais la page de détail est déjà accessible par lien. Les articles peuvent ainsi être préparés tranquillement et sont publiés automatiquement dès que leur date arrive.
export const revalidate = 600;
export default async function BlogIndex() {
const now = Date.now(); // toujours évaluer au moment du rendu
const published = getPublishedPosts(now);
// ...
}Le support multilingue complète le tableau : un article est rédigé en allemand ou en anglais puis traduit dans les autres langues. Si une traduction manque, la page se rabat proprement sur la langue d'origine et affiche un discret badge de langue.
Le résultat est un blog techniquement ennuyeux — dans le meilleur sens du terme. C'est exactement ce que nous voulions.