Construire un blog statique avec Astro
Comment j’assemble une base de blog bilingue, rapide et maintenable avec Astro 5, MDX, RSS et des collections de contenu typées.
Publié le · par Naomi
Astro est une base parfaite pour un blog portfolio : peu de JavaScript par défaut, une génération statique simple et une excellente ergonomie pour mélanger pages, contenu et composants interactifs.
Pour ce projet, l’idée est de garder une architecture très lisible : des collections de contenu pour les articles, des routes localisées, et quelques îlots React uniquement là où l’interactivité apporte vraiment quelque chose.
1. Centraliser les posts
Les articles vivent dans src/content/blog/fr et src/content/blog/en. Le schéma valide les métadonnées, et le reste du site ne manipule que des objets bien typés.
const blog = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), }),});Cette approche évite les surprises en production : impossible d’oublier une date, de publier un article sans résumé, ou de mélanger un brouillon avec le contenu public.
2. Générer les routes localisées
Le blog est servi sous /fr/... et /en/.... Je crée les pages au build à partir des entrées de collection, puis je dérive les routes miroir pour les deux langues.
---export async function getStaticPaths() { return posts.map((post) => ({ params: { lang: getPostLocale(post), slug: getPostSlug(post) }, props: { post }, }));}
const { Content } = await post.render();---<SiteLayout lang={lang} title={post.data.title} description={post.data.description} pathname={Astro.url.pathname} recentPosts={recentPosts}> <article class="content-body"> <Content /> </article></SiteLayout>Le point important ici, c’est le rendu statique complet. Le HTML final existe déjà à la compilation, ce qui rend le site rapide à charger et simple à déployer sur cPanel via SSH.
3. Vérifier le résultat dans le terminal
npm run buildLe site final contient les pages de langue, les pages d’articles, le sitemap et les flux RSS par locale. C’est exactement le genre d’ossature propre que j’aime montrer dans un portfolio front-end.