Développer un site Astro avec Claude Code : Collections, SSG et vérification
Guide pratique Astro avec Claude Code : configuration, articles, tags, hydratation ciblée et commandes de build.
Pourquoi Claude Code fonctionne bien avec Astro
Astro est particulièrement adapté aux blogs, documentations, portfolios, pages produits et sites où le contenu est surtout lu. Il permet d’utiliser React, Vue ou Svelte, mais ne transforme pas tout le site en application cliente lourde. Son architecture en îlots garde le contenu statique côté serveur et n’hydrate dans le navigateur que les parties réellement interactives, comme une recherche ou un filtre.
Claude Code devient utile quand on lui demande d’analyser le projet avant de modifier les fichiers. Dans Astro, une page ne vit pas seule : astro.config.mjs, src/content.config.ts, src/pages/, src/components/, les images, les routes et les commandes de build influencent le résultat. Le faire lire ces éléments d’abord permet d’obtenir un plan plus limité et d’éviter les dépendances inutiles.
Ce guide utilise le modèle actuel des Content Collections Astro : src/content.config.ts, astro/loaders et astro/zod. Avant de l’appliquer à votre projet, vérifiez les sources officielles : Claude Code Quickstart, Astro Content Collections, Astro template directives et Astro routing reference. Pour les choix d’architecture, gardez aussi le comparatif SSR/SSG et le guide SEO sous la main.
Fixer un périmètre clair
Un prompt comme « crée un blog Astro » est trop large. Claude Code risque de toucher au design, aux routes, au modèle de contenu et aux dépendances en même temps. Mieux vaut préciser : site statique de contenu, MDX, sitemap, frontmatter typé, liste d’articles, pages de tags et vérification par build.
npm create astro@latest my-astro-site
cd my-astro-site
npx astro add mdx sitemap tailwind
npm run dev
Ensuite, demandez une lecture avant édition :
claude "Examine ce projet Astro comme un site de contenu. Lis astro.config.mjs, src/content.config.ts, src/pages et src/components. Avant de modifier, explique le plan d'implémentation et les commandes de vérification."
La configuration peut rester simple :
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
site: 'https://example.com',
output: 'static',
integrations: [mdx(), sitemap(), tailwind()],
markdown: {
shikiConfig: {
theme: 'github-dark',
},
},
});
Remplacez site par le domaine réel avant publication. Le sitemap, les URL canoniques et une partie du SEO dépendent de cette valeur.
Définir les Content Collections avec l’API actuelle
Les Content Collections transforment les fichiers Markdown et MDX en données typées. Au lieu d’espérer que chaque article respecte le même frontmatter, on définit un schéma et Astro signale les erreurs avant le déploiement. C’est essentiel pour un site multilingue, car une traduction peut casser un champ fixe sans le vouloir.
// src/content.config.ts
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';
const blog = defineCollection({
loader: glob({
base: './src/content/blog',
pattern: '**/*.{md,mdx}',
}),
schema: z.object({
title: z.string().max(80),
description: z.string().max(120),
pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
heroImage: z.string().optional(),
}),
});
export const collections = { blog };
Une demande de revue ciblée est plus efficace :
claude "Relis src/content.config.ts pour Astro 5. Vérifie l'API actuelle des Content Collections, la longueur de description, l'exclusion des drafts, updatedDate optionnel et les anciens patterns."
Ce schéma agit comme un contrat de publication. Une date invalide, une description trop longue ou un tableau tags cassé apparaît avant la mise en ligne.
Cas 1 : liste d’articles et pagination
Le premier cas d’usage est l’index du blog. Ne supposez pas que getCollection() renvoie les articles dans le bon ordre. Filtrez les brouillons, triez par date et transmettez les entrées à une carte.
---
// src/pages/blog/[...page].astro
import { getCollection } from 'astro:content';
import PostCard from '../../components/PostCard.astro';
export async function getStaticPaths({ paginate }) {
const posts = (await getCollection('blog', ({ data }) => data.draft !== true))
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
return paginate(posts, { pageSize: 12 });
}
const { page } = Astro.props;
---
<section class="mx-auto max-w-5xl px-4 py-10">
<h1 class="text-3xl font-bold">Blog</h1>
<div class="mt-8 grid gap-6 md:grid-cols-2">
{page.data.map((post) => <PostCard post={post} />)}
</div>
<nav class="mt-10 flex justify-between">
{page.url.prev ? <a href={page.url.prev}>Previous</a> : <span />}
{page.url.next ? <a href={page.url.next}>Next</a> : <span />}
</nav>
</section>
La carte reste volontairement simple :
---
// src/components/PostCard.astro
import type { CollectionEntry } from 'astro:content';
type Props = {
post: CollectionEntry<'blog'>;
lang?: string;
};
const { post, lang = 'fr' } = Astro.props;
const href = lang === 'ja' ? `/blog/${post.id}/` : `/${lang}/blog/${post.id}/`;
const date = post.data.updatedDate ?? post.data.pubDate;
---
<article class="rounded border border-slate-200 p-5">
<p class="text-sm text-slate-500">
<time datetime={date.toISOString()}>{date.toLocaleDateString('fr-FR')}</time>
</p>
<h2 class="mt-2 text-xl font-semibold">
<a href={href}>{post.data.title}</a>
</h2>
<p class="mt-3 text-slate-700">{post.data.description}</p>
<ul class="mt-4 flex flex-wrap gap-2">
{post.data.tags.map((tag) => <li class="rounded bg-slate-100 px-2 py-1 text-xs">{tag}</li>)}
</ul>
</article>
Cette structure convient à trois usages fréquents : blog technique personnel, base de connaissances interne et changelog produit. Dans chaque cas, demandez à Claude Code de préserver date, titre, description et tags avant de modifier le style.
Cas 2 : pages de tags et hydratation ciblée
Le deuxième cas est l’archive par tag. L’erreur courante consiste à utiliser le libellé du tag directement dans l’URL. Les espaces, majuscules et caractères non latins peuvent créer des routes fragiles. Séparez slug d’URL et label d’affichage.
---
// src/pages/tags/[tag]/[...page].astro
import { getCollection } from 'astro:content';
import PostCard from '../../../components/PostCard.astro';
const tagSlug = (tag) =>
encodeURIComponent(tag.toLowerCase().trim().replace(/\s+/g, '-'));
export async function getStaticPaths({ paginate }) {
const posts = await getCollection('blog', ({ data }) => data.draft !== true);
const groups = new Map();
for (const post of posts) {
for (const label of post.data.tags) {
const slug = tagSlug(label);
const group = groups.get(slug) ?? { slug, label, posts: [] };
group.posts.push(post);
groups.set(slug, group);
}
}
return [...groups.values()].flatMap((group) =>
paginate(group.posts, {
params: { tag: group.slug },
props: { tag: group.label },
pageSize: 10,
}),
);
}
const { page, tag } = Astro.props;
---
<section class="mx-auto max-w-5xl px-4 py-10">
<h1 class="text-3xl font-bold">Tag: {tag}</h1>
<div class="mt-8 grid gap-6 md:grid-cols-2">
{page.data.map((post) => <PostCard post={post} />)}
</div>
</section>
Le troisième cas est la recherche. Il n’est pas nécessaire de transformer toute la page en application cliente :
---
// src/pages/index.astro
import Hero from '../components/Hero.astro';
import SearchBox from '../components/SearchBox.tsx';
import LatestPosts from '../components/LatestPosts.astro';
---
<Hero />
<SearchBox client:visible />
<LatestPosts />
client:load convient aux éléments interactifs immédiats. client:visible convient aux composants qui peuvent attendre d’entrer dans le viewport. Faites expliquer ce choix à Claude Code avant d’ajouter la directive.
Erreurs fréquentes et vérification
Première erreur : copier un ancien tutoriel de Content Collections sans vérifier la version. Deuxième erreur : demander une amélioration globale du site, impossible à relire proprement. Troisième erreur : oublier heroImage, description et Open Graph. Quatrième erreur : considérer un build réussi comme une validation complète.
npm run build
npx astro check
npm run preview
En cas d’échec, demandez une classification :
claude "Lis l'échec de npm run build. Classe-le en syntaxe Astro, schema Content Collections, code fence MDX, génération de routes ou liens. Propose ensuite le plus petit correctif."
CTA et résultat observé
Pour commencer, la fiche gratuite aide à mémoriser les commandes de base. Pour des modèles réutilisables, consultez les produits. Pour une équipe qui veut organiser un site Astro, les règles de revue et l’adoption de Claude Code, la suite logique est la formation et consultation.
En pratique, Claude Code génère vite les fichiers .astro et relie bien les pages aux collections. Les points à vérifier restent l’API Astro actuelle, l’encodage des tags dans les URL, l’abus possible de client:load et l’exécution réelle du build. Le flux le plus fiable : lire le projet, limiter la modification, comparer aux docs officielles, lancer le build, puis vérifier l’aperçu.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Workflow Obsidian vers CLAUDE.md avec Claude Code
Transformer des notes Obsidian en notes CLAUDE.md concises pour reprendre les sessions sans réexpliquer.
Claude Code Revenue CTA Routing : relier articles, PDF, Gumroad et consultation
Un workflow Claude Code pour orienter les lecteurs vers PDF gratuit, Gumroad ou consultation selon l'intention.
Règles de handoff Claude Code en équipe: preuves, permissions, rollback et revenus
Un format concret pour transmettre un travail Claude Code avec preuves, permissions, rollback, PDF gratuit, Gumroad et consultation.