Aller au contenu

Astro : contenu et collections

Les collections de contenu organisent des fichiers Markdown (ou JSON, YAML) avec un schéma vérifié à la compilation. Les exemples utilisent une collection blog et reprennent l’API d’Astro 7.

src/content.config.ts :

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
schema: z.object({
titre: z.string(),
description: z.string().max(160),
date: z.coerce.date(),
tags: z.array(z.string()).default([]),
brouillon: z.boolean().default(false),
}),
});
export const collections = { blog };
Élément Rôle
loader: glob(...) Lit les fichiers correspondant au motif
schema Valide le frontmatter (Zod) et type les données
z.coerce.date() Convertit une chaîne de date en objet Date
.default() Valeur par défaut

Un fichier src/content/blog/premier-article.md :

---
titre: 'Premier article'
description: 'Un article de démonstration'
date: 2026-01-15
tags: ['astro', 'blog']
---
Contenu **Markdown** de l'article.

Si le frontmatter ne respecte pas le schéma, la compilation échoue avec un message précis (champ et règle).

---
import { getCollection, getEntry } from 'astro:content';
const articles = (
await getCollection('blog', ({ data }) => !data.brouillon)
).sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
const premier = await getEntry('blog', 'premier-article');
---
<ul>
{articles.map((a) => (
<li>
<a href={`/blog/${a.id}/`}>{a.data.titre}</a> :{' '}
{a.data.date.toLocaleDateString('fr-FR')}
</li>
))}
</ul>

id est dérivé du nom de fichier (premier-article). Le filtre en second argument exclut par exemple les brouillons.

src/pages/blog/[id].astro :

---
import { getCollection, render } from 'astro:content';
import Base from '../../layouts/Base.astro';
export async function getStaticPaths() {
const articles = await getCollection('blog', ({ data }) => !data.brouillon);
return articles.map((article) => ({
params: { id: article.id },
props: { article },
}));
}
const { article } = Astro.props;
const { Content, headings } = await render(article);
---
<Base titre={article.data.titre} description={article.data.description}>
<article>
<h1>{article.data.titre}</h1>
<Content />
</article>
</Base>

render() renvoie le composant Content (le Markdown rendu) et la liste des titres (headings, utile pour une table des matières).

const auteurs = defineCollection({
loader: glob({ pattern: '**/*.json', base: './src/content/auteurs' }),
schema: z.object({ nom: z.string(), email: z.email() }),
});

Il existe aussi un loader file() pour un fichier unique contenant plusieurs entrées, et des loaders personnalisés (API distante, base de données).

import { reference } from 'astro:content';
const blog = defineCollection({
loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
schema: z.object({
titre: z.string(),
auteur: reference('auteurs'),
}),
});
---
const auteur = await getEntry(article.data.auteur);
---
<p>Par {auteur?.data.nom}</p>
  • Syntaxe courante : titres, listes, tableaux, code, liens (GitHub Flavored Markdown).
  • Astro 7 utilise par défaut un processeur Markdown natif (Sätteri) : les options markdown.remarkPlugins et markdown.rehypePlugins ne sont utilisables qu’en installant @astrojs/markdown-remark et en le configurant comme processeur.
  • Pour des composants dans le contenu, installer l’intégration MDX (npx astro add mdx) et utiliser des fichiers .mdx.
  • Coloration du code : Shiki, intégrée (markdown.shikiConfig pour choisir le thème).
Fenêtre de terminal
npx astro add sitemap
npm install @astrojs/rss

src/pages/rss.xml.ts :

import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
export async function GET(context) {
const articles = await getCollection('blog', ({ data }) => !data.brouillon);
return rss({
title: 'Mon blog',
description: 'Les derniers articles',
site: context.site,
items: articles.map((a) => ({
title: a.data.titre,
pubDate: a.data.date,
description: a.data.description,
link: `/blog/${a.id}/`,
})),
});
}
Symptôme Piste
Invalid frontmatter Un champ ne respecte pas le schéma : le message nomme le champ
The collection "blog" does not exist Collection absente de collections dans content.config.ts
La collection est vide Motif glob ou dossier base incorrects
Cannot find module 'astro:content' Exécuter npx astro sync pour régénérer les types
Le frontmatter casse sur un : Mettre la valeur entre guillemets
Date invalide Utiliser z.coerce.date() et le format 2026-01-15
Les images du contenu ne s’affichent pas Chemin relatif au fichier Markdown, ou images dans public/

Ubuntu 24.04 et 26.04 : différences à connaître

Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »

Aucune.