Collections de contenu
Ajouté à la version :
astro@2.0.0
Les collections de contenu sont la meilleure façon de gérer des ensembles de contenu dans n’importe quel projet Astro : articles de blog, descriptions de produits, pages de profil, recettes ou tout autre contenu structuré. Les collections permettent d’organiser et d’interroger vos documents, activent l’IntelliSense et la vérification des types dans votre éditeur, et fournissent automatiquement la sûreté du typage TypeScript pour l’ensemble de votre contenu.
Astro fournit des API performantes et évolutives pour charger, interroger et restituer du contenu provenant de n’importe quelle source : stocké localement dans votre projet, hébergé à distance ou récupéré en direct à partir de sources fréquemment mises à jour.
Que sont les collections de contenu ?
Section intitulée « Que sont les collections de contenu ? »Une collection de contenu est un ensemble de données liées et structurellement identiques. Ces données peuvent être stockées localement dans un ou plusieurs fichiers (par exemple, un dossier contenant des fichiers Markdown d’articles de blog ou un fichier JSON unique de descriptions de produits) ou récupérées depuis des sources distantes telles qu’une base de données, un CMS ou un point de terminaison d’API. Chaque élément de la collection est appelé une entrée.
Répertoiresrc/
- …
Répertoirenewsletter/ la collection « newsletter »
- semaine-1.md une entrée de collection
- semaine-2.md une entrée de collection
- semaine-3.md une entrée de collection
Répertoireauteurs/ la collection « auteur »
- auteurs.json un fichier unique contenant toutes les entrées de la collection
Les collections sont définies par l’emplacement et la structure de leurs entrées et offrent une manière pratique d’interroger et de restituer votre contenu et les métadonnées associées. Vous pouvez créer une collection dès lors que vous disposez d’un groupe de données ou de contenus liés, stockés au même emplacement et partageant une structure commune.
Deux types de collections de contenu sont disponibles pour vous permettre de travailler avec des données récupérées soit lors de la compilation, soit lors d’une requête. Les collections consommées au moment de la compilation et les collections mises à jour en direct utilisent toutes deux :
- Un chargeur (
loader) obligatoire pour récupérer votre contenu et vos métadonnées depuis leur emplacement de stockage et les mettre à disposition de votre projet via des API dédiées au contenu. - Un schéma de collection (
schema) facultatif qui vous permet de définir la structure attendue de chaque entrée pour la sûreté du typage, la saisie semi-automatique et la validation dans votre éditeur.
Les collections stockées localement dans votre projet ou dans votre système de fichiers peuvent utiliser l’un des chargeurs appelés lors de la compilation fournis par Astro pour récupérer des données à partir de fichiers Markdown, MDX, Markdoc, YAML, TOML ou JSON. Indiquez à Astro l’emplacement de votre contenu, définissez la structure de vos données, et vous voilà prêt à lancer un blog ou un site similaire, riche en contenu et principalement statique, en un rien de temps !
Avec des chargeurs créés par la communauté ou en créant vous-même un chargeur personnalisé pour les collections consommées lors la compilation ou un chargeur en direct, vous pouvez récupérer des données distantes à partir de n’importe quelle source externe, telle qu’un CMS, une base de données ou un système de paiement headless, soit au moment de la compilation, soit en direct à la demande.
Types de collections
Section intitulée « Types de collections »Les collections de contenu consommées lors de la compilation sont mises à jour lors de la génération du site, et les données sont enregistrées dans une couche de stockage. Cette approche offre d’excellentes performances pour la plupart des contenus, mais peut ne pas convenir aux sources de données fréquemment mises à jour qui nécessitent des données actualisées en temps réel, comme les cours boursiers.
Pour obtenir les meilleures performances et la meilleure évolutivité, utilisez les collections de contenu consommées au moment de la compilation lorsqu’une ou plusieurs des conditions suivantes sont remplies :
- Les performances sont essentielles et vous souhaitez effectuer le pré-rendu des données lors de la compilation.
- Vos données sont relativement statiques (par exemple, articles de blog, documentation, descriptions de produits).
- Vous souhaitez bénéficier de l’optimisation au moment de la compilation et de la mise en cache.
- Vous devez traiter les fichiers MDX ou effectuer des optimisations d’images.
- Vos données peuvent être récupérées une seule fois et réutilisées pour plusieurs compilations.
Consultez le modèle de démarrage officiel d’Astro pour les blogs afin de démarrer rapidement avec un exemple d’utilisation du chargeur glob() intégré et de définition d’un schéma pour une collection d’articles de blog locaux au format Markdown ou MDX.
Les collections de contenu en direct récupèrent leurs données au moment de l’exécution plutôt qu’au moment de la compilation. Cela vous permet d’accéder à des données fréquemment mises à jour provenant de CMS, d’API, de bases de données ou d’autres sources via une API unifiée, sans avoir à recompiler votre site à chaque modification des données. Cependant, cette approche peut avoir un impact sur les performances, car les données sont récupérées à chaque requête et renvoyées directement, sans magasin de données persistant.
Les collections de contenu en direct sont conçues pour les données qui changent fréquemment et qui doivent être à jour lorsqu’une page est demandée. Envisagez de les utiliser lorsqu’une ou plusieurs des conditions suivantes sont remplies :
- Vous avez besoin d’informations en temps réel (par exemple, des données spécifiques à l’utilisateur, les niveaux de stock actuels).
- Vous souhaitez éviter les recompilations constantes pour un contenu qui change fréquemment.
- Vos données sont fréquemment mises à jour (par exemple, inventaire des produits, prix, disponibilité à la minute près).
- Vous devez transmettre des filtres dynamiques à votre source de données en fonction des paramètres saisis par l’utilisateur ou des paramètres de la requête.
- Vous développez une fonctionnalité de prévisualisation pour un CMS où les rédacteurs ont besoin de voir immédiatement le contenu en brouillon.
Les deux types de collections peuvent coexister dans un même projet, ce qui vous permet de choisir le type de collection le plus adapté à chaque source de données. Par exemple, une collection consommée lors de la compilation peut gérer les descriptions de produits, tandis qu’une collection en direct peut gérer l’inventaire du contenu.
Les deux types de collections utilisent des API similaires (par exemple getCollection() et getLiveCollection()), de sorte que travailler avec les collections vous semblera familier quel que soit votre choix, tout en vous assurant de toujours savoir avec quel type de collection vous travaillez.
Nous vous recommandons d’utiliser les collections de contenu consommées lors de la compilation chaque fois que cela est possible, et les collections en direct lorsque votre contenu doit être mis à jour en temps réel et que les compromis en termes de performances sont acceptables. Par ailleurs, les collections en direct présentent certaines limitations par rapport aux collections consommées lors de la compilation :
- Aucune prise en charge de MDX : Le rendu de MDX est impossible dans l’environnement d’exécution.
- Aucune optimisation d’images : Les images ne peuvent pas être traitées dans l’environnement d’exécution.
- Considérations relatives aux performances : Les données sont récupérées à chaque requête (sauf si elles sont mises en cache).
- Aucune persistance des données : Les données ne sont pas enregistrées dans le magasin de données de la couche de contenu.
Quand créer une collection
Section intitulée « Quand créer une collection »Définissez vos données comme une collection lorsque :
- Vous avez plusieurs fichiers ou données à organiser qui partagent la même structure globale (par exemple, un répertoire d’articles de blog écrits en Markdown qui possèdent tous les mêmes propriétés de frontmatter).
- Vous disposez de contenus existants stockés à distance, par exemple dans un CMS, et vous souhaitez tirer parti des fonctions utilitaires des collections au lieu d’utiliser
fetch()ou des SDK. - Vous devez récupérer des (dizaines de) milliers de données connexes au moment de la compilation, et vous avez besoin d’une méthode de requête et de mise en cache qui peut s’appliquer à grande échelle.
La plupart des avantages provenant de l’utilisation des collections viennent :
- De la définition d’une structure de données commune pour valider qu’une entrée individuelle est « correcte » ou « complète », évitant ainsi les erreurs en production.
- Des API axées sur le contenu, conçues pour rendre les requêtes intuitives (par exemple
getCollection()au lieu deimport.meta.glob()) lors de l’importation et du rendu des contenus sur vos pages. - De l’accès aux chargeurs intégrés et à l’API des chargeurs de contenu de bas niveau pour récupérer votre contenu. Il existe en outre plusieurs chargeurs tiers et développés par la communauté, et vous pouvez créer votre propre chargeur personnalisé pour récupérer des données depuis n’importe où.
- Des performances et de l’évolutivité. Les données des collections de contenu consommées lors de la compilation peuvent être mises en cache entre les compilations et conviennent à des dizaines de milliers d’entrées de contenu.
Quand ne pas créer de collection
Section intitulée « Quand ne pas créer de collection »Les collections offrent une excellente structure, sécurité et organisation lorsque vous avez plusieurs entrées de contenu qui doivent partager les mêmes propriétés.
Les collections ne sont peut-être pas la solution idéale si :
- Vous n’avez qu’une seule ou un petit nombre de pages de contenu. Envisagez plutôt de créer des composants de page individuels, comme
src/pages/about.astro, contenant directement votre contenu. - Vous affichez des fichiers qui ne sont pas traités par Astro, tels que des PDF. Placez plutôt ces ressources statiques dans le dossier
public/de votre projet. - Votre source de données possède sa propre bibliothèque SDK/client pour les importations, qui est incompatible ou ne propose pas de chargeur de contenu, et vous préférez l’utiliser directement.
Configuration de TypeScript pour les collections
Section intitulée « Configuration de TypeScript pour les collections »Les collections de contenu s’appuient sur TypeScript pour fournir la validation avec Zod, l’Intellisense et la vérification des types dans votre éditeur. Par défaut, Astro configure un modèle strict pour TypeScript lorsque vous créez un nouveau projet à l’aide de la commande create astro. Les modèles strict et strictest d’Astro incluent tous deux les paramètres TypeScript dont votre projet a besoin pour les collections de contenu.
Si vous avez remplacé ce paramètre par base parce que vous n’écrivez pas de TypeScript dans votre projet ou que vous n’utilisez aucun des modèles intégrés d’Astro, vous devrez également ajouter les options de compilation (compilerOptions) suivantes dans votre fichier tsconfig.json pour utiliser les collections de contenu :
{ "extends": "astro/tsconfigs/base", // non nécessaire pour `strict` ou `strictest` "compilerOptions": { "strictNullChecks": true, "allowJs": true }}Définition de collections de contenu consommées lors de la compilation
Section intitulée « Définition de collections de contenu consommées lors de la compilation »Toutes vos collections de contenu consommées au moment de la compilation sont définies dans un fichier spécial src/content.config.ts (les extensions .js et .mjs sont également prises en charge) à l’aide de defineCollection(), puis un seul objet de collections est exporté pour être utilisé dans votre projet.
Chaque collection individuelle configure :
- un chargeur appelé lors de la compilation (
loader) pour une source de données (obligatoire) - Un schéma utilisé au moment de la compilation (
schema) pour la sûreté du typage (optionnel, mais fortement recommandé !)
// 1. Importer des utilitaires depuis `astro:content`import { defineCollection } from 'astro:content';
// 2. Importer un ou plusieurs chargeursimport { glob, file } from 'astro/loaders';
// 3. Importer Zodimport { z } from 'astro/zod';
// 4. Définir un `loader` et un `schema` pour chaque collectionconst blog = defineCollection({ loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }), schema: z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), }),});
// 5. Exporter un seul objet `collections` pour enregistrer votre ou vos collectionsexport const collections = { blog };Vous pouvez ensuite utiliser les fonctions dédiées getCollection() et getEntry() pour interroger les données de vos collections de contenu et afficher votre contenu.
Vous pouvez choisir de générer des routes de page à partir des entrées de votre collection au moment de la compilation pour un site entièrement statique et pré-rendu. Vous pouvez également générer vos collections déclarées pour la compilation, mais à la demande, en choisissant de retarder la compilation de votre page jusqu’à sa première requête. Cette option est utile lorsque vous avez un grand nombre de pages (par exemple, des milliers ou des dizaines de milliers) et que vous souhaitez différer la génération d’une page statique jusqu’à ce qu’elle soit nécessaire.
Chargeurs de collections appelés lors de la compilation
Section intitulée « Chargeurs de collections appelés lors de la compilation »Astro propose deux chargeurs intégrés (glob() et file()) pour récupérer votre contenu local lors de la compilation. Indiquez l’emplacement de vos données dans votre projet ou dans votre système de fichiers, et ces chargeurs géreront automatiquement vos données et mettront à jour la couche de contenu du magasin de données persistant.
Pour récupérer des données distantes au moment de la compilation, vous pouvez créer un chargeur personnalisé pour récupérer vos données et mettre à jour le magasin de données. Ou vous pouvez utiliser n’importe quelle intégration de chargeur tierce ou publiée par la communauté. Plusieurs existent déjà pour les systèmes de gestion de contenu populaires ainsi que pour des sources de données courantes telles que les coffres-forts Obsidian, les dépôts GitHub ou les publications Bluesky.
Le chargeur glob()
Section intitulée « Le chargeur glob() »Le chargeur glob() récupère les entrées à partir de dossiers de fichiers au format Markdown, MDX, Markdoc, JSON, YAML ou TOML situés n’importe où dans le système de fichiers. Si vous stockez vos entrées de contenu localement sous forme de fichiers séparés, comme un répertoire d’articles de blog, alors le chargeur glob() est tout ce dont vous avez besoin pour accéder à votre contenu.
Ce chargeur nécessite un modèle (pattern) de fichiers à faire correspondre à l’aide des motifs glob pris en charge par micromatch, ainsi qu’un chemin d’accès indiquant l’emplacement de base de vos fichiers. Un id unique sera généré automatiquement pour chaque entrée à partir du nom de son fichier, mais vous pouvez définir des identifiants personnalisés si nécessaire.
import { defineCollection } from 'astro:content';import { glob } from 'astro/loaders';
const blog = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }),});
export const collections = { blog };Définition d’identifiants personnalisés
Section intitulée « Définition d’identifiants personnalisés »Lors de l’utilisation du chargeur glob() avec des fichiers Markdown, MDX, Markdoc, JSON ou TOML, l’id de chaque entrée de contenu est automatiquement généré dans un format compatible avec les URL à partir du nom du fichier. Cet identifiant unique (id) est utilisé pour interroger directement l’entrée dans votre collection. Il est également utile lors de la création de nouvelles pages et d’URL à partir de votre contenu.
Vous pouvez remplacer l’identifiant généré d’une entrée en ajoutant votre propre propriété slug dans le frontmatter du fichier ou dans l’objet contenant vos données pour les fichiers JSON. Cela est similaire à la fonctionnalité « lien permanent » d’autres frameworks web.
---title: Mon article de blogslug: mon-identifiant-personnalisé/prend-en-charge/les-barres-obliques---Le contenu de votre article de blog ici.{ "title": "Ma Catégorie", "slug": "mon-identifiant-personnalisé/prend-en-charge/les-barres-obliques", "description": "La description de votre catégorie ici."}Vous pouvez également transmettre des options à la fonction utilitaire generateID() du chargeur glob() lors de la définition de votre collection consommée lors de la compilation, afin d’ajuster la façon dont les id sont générés. Par exemple, vous pouvez souhaiter annuler le comportement par défaut qui consiste à convertir les majuscules en minuscules pour chaque entrée de la collection :
const auteurs = defineCollection({ /* Récupérer tous les fichiers JSON de votre répertoire d'auteurs tout * en conservant les majuscules dans l'identifiant. */ loader: glob({ pattern: '**/*.json', base: "./src/data/auteurs", generateId: ({ entry }) => entry.replace(/\.json$/, ''), }),});Le chargeur file()
Section intitulée « Le chargeur file() »Le chargeur file() récupère plusieurs entrées à partir d’un seul fichier local défini dans votre collection. Il détectera et analysera automatiquement (en fonction de l’extension du fichier) un seul tableau d’objets provenant de fichiers JSON et YAML, et traitera chaque table de premier niveau comme une entrée indépendante dans les fichiers TOML.
import { defineCollection } from 'astro:content';import { file } from 'astro/loaders';
const chiens = defineCollection({ loader: file("src/data/chiens.json"),});
export const collections = { chiens };Chaque objet dans le fichier doit posséder un nom de propriété id avec une valeur unique afin de pouvoir être identifié et interrogé. Contrairement au chargeur glob(), le chargeur file() ne générera pas automatiquement d’identifiants pour chaque entrée.
Vous pouvez fournir vos entrées sous forme de tableau d’objets avec une propriété id, ou sous forme d’objet où l’identifiant unique (id) est le nom de la propriété :
// Spécifier une propriété `id` dans chaque objet d'un tableau[ { "id": "caniche", "pelage": "bouclé", "mue": "faible" }, { "id": "afghan", "pelage": "short", "mue": "low" }]// Chaque nom de propriété sera utilisé comme `id`{ "caniche": { "pelage": "bouclé", "mue": "faible" }, "afghan": { "pelage": "soyeux", "mue": "faible" }}Analyse syntaxique d’autres formats de données
Section intitulée « Analyse syntaxique d’autres formats de données »La prise en charge de la transformation de fichiers JSON, YAML et TOML uniques en entrées de collection avec le chargeur file() est intégrée (sauf si vous avez un document JSON imbriqué). Pour charger votre collection à partir de types de fichiers non pris en charge, tels que .csv, vous devrez créer une fonction d’analyse. Cette fonction peut être rendue asynchrone si nécessaire (par exemple pour récupérer des fichiers sur le web, ou si votre analyseur syntaxique est asynchrone).
L’exemple suivant montre comment importer un analyseur CSV tiers, puis comment transmettre une fonction parser personnalisée au chargeur file() :
import { defineCollection } from "astro:content";import { file } from "astro/loaders";import { parse as parseCsv } from "csv-parse/sync";
const chats = defineCollection({ loader: file("src/data/chats.csv", { parser: (text) => parseCsv(text, { columns: true, skipEmptyLines: true }), }),});Documents .json imbriqués
Section intitulée « Documents .json imbriqués »L’argument parser() peut être utilisé pour charger une seule collection à partir d’un document JSON imbriqué. Par exemple, ce fichier JSON contient plusieurs collections :
{"chiens": [{}], "chats": [{}]}Vous pouvez séparer ces collections en transmettant une fonction parser() personnalisée au chargeur file() pour chaque collection, en utilisant l’analyse JSON intégrée d’Astro :
import { file } from "astro/loaders";import { defineCollection } from "astro:content";
const chiens = defineCollection({ loader: file("src/data/animaux.json", { parser: (text) => JSON.parse(text).chiens })});const chats = defineCollection({ loader: file("src/data/animaux.json", { parser: (text) => JSON.parse(text).chats })});Chargeurs personnalisés appelés lors de la compilation
Section intitulée « Chargeurs personnalisés appelés lors de la compilation »Vous pouvez créer un chargeur personnalisé en utilisant l’API des chargeurs de contenu pour récupérer du contenu distant à partir de n’importe quelle source de données, comme un CMS, une base de données ou un point de terminaison d’API.
Vous pouvez ensuite importer et définir votre chargeur personnalisé dans la configuration de vos collections, en transmettant les valeurs requises :
import { defineCollection } from 'astro:content';import { monChargeur } from './loader.ts';
const blog = defineCollection({ loader: monChargeur({ url: "https://api.example.com/articles", apiKey: "mon-secret", }),});Trouvez des chargeurs créés par la communauté et des chargeurs tiers dans le répertoire des intégrations d’Astro.
L’utilisation d’un chargeur personnalisé pour récupérer vos données créera automatiquement une collection à partir de vos données distantes. Vous bénéficierez ainsi de tous les avantages des collections locales, y compris l’accès aux fonctions utilitaires spécifiques à l’API des collections telles que getCollection() et render() pour interroger et afficher vos données, ainsi que de la validation du schéma.
De la même manière que pour la création d’une intégration Astro ou d’un module d’extension pour Vite, vous pouvez distribuer votre chargeur en tant que paquet npm que d’autres peuvent utiliser dans leurs projets.
Définition d’un schéma de collection
Section intitulée « Définition d’un schéma de collection »Les schémas garantissent la cohérence des données ou du frontmatter au sein d’une collection grâce à l’utilisation de Zod pour la validation. Un schéma garantit que ces données existent sous une forme prévisible lorsque vous devez les consulter ou les interroger. Si un fichier enfreint le schéma de sa collection, Astro vous fournira un message d’erreur utile pour vous en informer.
Les schémas permettent également à Astro de générer automatiquement les types TypeScript pour votre contenu. Lorsque vous définissez un schéma pour votre collection, Astro génèrera et appliquera automatiquement une interface TypeScript à celle-ci. Le résultat est une prise en charge complète de TypeScript lors de l’interrogation de votre collection, y compris la saisie semi-automatique des propriétés et la vérification des types.
Pour qu’Astro reconnaisse un schéma nouveau ou mis à jour, vous devrez peut-être redémarrer le serveur de développement ou synchroniser la couche de contenu (s + enter) pour définir le module astro:content.
Fournir un schema est facultatif, mais fortement recommandé ! Si vous choisissez d’utiliser un schéma, chaque propriété de vos entrées de collection utilisée dans le frontmatter ou dans vos données doit être définie à l’aide d’un type de données Zod :
import { defineCollection } from 'astro:content';import { z } from 'astro/zod';import { glob, file } from 'astro/loaders';
const blog = defineCollection({ loader: glob({ pattern: "**/*.md", base: "./src/data/blog" }), schema: z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), })});const dogs = defineCollection({ loader: file("src/data/chiens.json"), schema: z.object({ id: z.string(), breed: z.string(), temperament: z.array(z.string()), }),});
export const collections = { blog, dogs };Définition des types de données avec Zod
Section intitulée « Définition des types de données avec Zod »Astro utilise Zod pour alimenter ses schémas de contenu. Avec Zod, Astro est capable de valider les données de chaque fichier au sein d’une collection et de fournir automatiquement les types TypeScript lorsque vous interrogez le contenu depuis votre projet.
Pour utiliser Zod dans Astro, importez l’utilitaire z depuis "astro/zod". Il s’agit d’une réexportation de la bibliothèque Zod, et elle prend en charge toutes les fonctionnalités de Zod 4.
z pour obtenir un aide-mémoire des types de données courants et pour apprendre comment Zod fonctionne et quelles fonctionnalités sont disponibles.
Méthodes de schéma Zod
Section intitulée « Méthodes de schéma Zod »Toutes les méthodes des schéma Zod (par exemple .parse(), .transform()) sont disponibles, avec certaines limitations. Notamment, l’exécution de contrôles de validation personnalisés sur les images à l’aide de image().refine() n’est pas prise en charge.
Définition des références de collection
Section intitulée « Définition des références de collection »Les entrées de collection peuvent également « faire référence » à d’autres entrées connexes.
Avec la fonction reference(), vous pouvez définir une propriété dans un schéma de collection en tant qu’entrée d’une autre collection. Par exemple, vous pouvez exiger que chaque entrée de navette-spaciale inclue une propriété pilote qui utilise le schéma propre à la collection pilote pour la vérification des types, la saisie semi-automatique et la validation.
Un exemple courant est un article de blog qui fait référence à des profils d’auteurs réutilisables stockés au format JSON, ou à des URL d’articles connexes enregistrés dans la même collection :
import { defineCollection, reference } 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(), // Faire référence à un seul auteur de la collection `authors` par `id` author: reference('authors'), // Faire référence à un tableau d'articles connexes de la collection `blog` par `id` relatedPosts: z.array(reference('blog')), })});
const authors = defineCollection({ loader: glob({ pattern: '**/*.json', base: "./src/data/auteurs" }), schema: z.object({ name: z.string(), portfolio: z.url(), })});
export const collections = { blog, authors };Cet exemple d’article de blog spécifie les id des articles associés et l’id de l’auteur de l’article :
---title: "Bienvenue sur mon blog"author: ben-holmes # fait référence à `src/data/auteurs/ben-holmes.json`relatedPosts:- a-propos # fait référence à `src/content/blog/a-propos.md`- mon-bilan-annee # fait référence à `src/content/blog/mon-bilan-annee.md`---Ces références seront transformées en objets contenant les noms de propriété collection et id, vous permettant de les interroger facilement dans vos modèles.
Interroger les collections consommées lors de la compilation
Section intitulée « Interroger les collections consommées lors de la compilation »Astro fournit des fonctions utilitaires pour interroger une collection consommée au moment de la compilation et renvoyer une ou plusieurs entrées de contenu.
getCollection()récupère une collection entière et renvoie un tableau d’entrées.getEntry()récupère une seule entrée d’une collection.
Ces fonctions renvoient des entrées avec un id unique, un objet data contenant toutes les propriétés définies, et renverront également une propriété body contenant le corps brut et non compilé d’un document Markdown, MDX ou Markdoc.
---import { getCollection, getEntry } from 'astro:content';
// Récupérer toutes les entrées d'une collection.// Nécessite le nom de la collection comme argument.const allBlogPosts = await getCollection('blog');
// Récupérer une seule entrée de collection.// Nécessite le nom de la collection et l'`id`const poodleData = await getEntry('chiens', 'caniche');---L’ordre de tri des collections générées n’est pas déterministe et dépend de la plateforme. Cela signifie que si vous appelez getCollection() et que vous avez besoin que vos entrées soient renvoyées dans un ordre spécifique (par exemple, des articles de blog triés par date), vous devez trier vous-même les entrées de la collection :
---import { getCollection } from 'astro:content';
const posts = (await getCollection('blog')).sort( (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),);---CollectionEntry.
Utilisation du contenu dans les modèles Astro
Section intitulée « Utilisation du contenu dans les modèles Astro »Après avoir interrogé vos collections, vous pouvez accéder au contenu et aux métadonnées de chaque entrée directement dans le modèle de votre composant Astro.
Par exemple, vous pouvez créer une liste de liens vers vos articles de blog, affichant les informations du frontmatter de votre article à l’aide de la propriété data :
---import { getCollection } from 'astro:content';const posts = await getCollection('blog');---<h1>Mes articles</h1><ul> {posts.map(post => ( <li><a href={`/blog/${post.id}`}>{post.data.title}</a></li> ))}</ul>Restitution du contenu
Section intitulée « Restitution du contenu »Une fois interrogées, vous pouvez convertir les entrées Markdown et MDX en HTML à l’aide de la fonction render() du module astro:content. L’appel de cette fonction vous donne accès au contenu HTML généré, incluant un composant <Content /> et la liste de tous les titres générés.
---import { getEntry, render } from 'astro:content';
const entry = await getEntry('blog', 'article-1');
const { Content } = await render(entry);---<h1>{entry.data.title}</h1><p>Publié le : {entry.data.published.toDateString()}</p><Content /><Content /> pour remplacer les éléments HTML par des alternatives personnalisées.
Transmettre du contenu en tant que props
Section intitulée « Transmettre du contenu en tant que props »Un composant peut également transmettre une entrée de collection entière en tant que propriété.
Vous pouvez utiliser l’utilitaire CollectionEntry pour saisir correctement les propriétés de votre composant à l’aide de TypeScript. Cet utilitaire prend en tant qu’argument une chaîne de caractères qui correspond au nom de votre schéma de collection et héritera de toutes les propriétés du schéma de cette collection.
---import type { CollectionEntry } from 'astro:content';interface Props { post: CollectionEntry<'blog'>;}
// `post` correspondra au type du schéma de votre collection 'blog'.const { post } = Astro.props;---Filtrer les requêtes sur les collections
Section intitulée « Filtrer les requêtes sur les collections »getCollection() accepte une fonction de rappel facultative filter qui vous permet de filtrer votre requête en fonction des propriétés id ou data d’une entrée.
Vous pouvez utiliser cette fonction pour filtrer selon n’importe quel critère de contenu. Par exemple, vous pouvez filtrer par des propriétés comme draft pour empêcher la publication d’ébauches d’articles sur votre blog :
---// Exemple : Filtrer les entrées de contenu avec `draft: true`import { getCollection } from 'astro:content';const publishedBlogEntries = await getCollection('blog', ({ data }) => { return data.draft !== true;});---Vous pouvez également créer des pages brouillon qui seront disponibles lors de l’exécution du serveur de développement, mais qui ne seront pas générées en production :
---// Exemple : Filtrer les entrées de contenu avec `draft: true` uniquement lors de la génération pour la productionimport { getCollection } from 'astro:content';const blogEntries = await getCollection('blog', ({ data }) => { return import.meta.env.PROD ? data.draft !== true : true;});---L’argument filter prend également en charge le filtrage par répertoires imbriqués au sein d’une collection. Étant donné que l’id inclut le chemin imbriqué complet, vous pouvez filtrer par le début de chaque id pour ne renvoyer que les éléments d’un répertoire imbriqué spécifique :
---// Exemple : Filtrer les entrées par sous-répertoire dans la collectionimport { getCollection } from 'astro:content';const englishDocsEntries = await getCollection('docs', ({ id }) => { return id.startsWith('en/');});---Accès aux données référencées
Section intitulée « Accès aux données référencées »Pour accéder aux références définies dans votre schéma, commencez par interroger votre entrée de collection. Vos références seront disponibles dans l’objet data renvoyé (par exemple, entry.data.author et entry.data.relatedPosts).
Ensuite, vous pouvez utiliser à nouveau la fonction getEntry() (ou getEntries() pour récupérer plusieurs entrées référencées) en transmettant ces valeurs renvoyées. La fonction reference() de votre schéma transforme ces valeurs en un ou plusieurs objets contenant collection et id, ce qui facilite l’interrogation de ces données associées.
---import { getEntry, getEntries } from 'astro:content';
// Tout d'abord, interroger un article de blog.const blogPost = await getEntry('blog', "Aventures dans l'espace");
// Récupérer un seul élément de référence : l’auteur de l’article de blog// Équivalent à une requête utilisant `{collection: "auteurs", id: "ben-holmes"}`const author = await getEntry(blogPost.data.author);
// Récupérer un tableau d'éléments référencés : tous les articles associés// Équivalent à une requête utilisant `[{collection: "blog", id: "visiter-mars"}, {collection: "blog", id: "quitter-la-terre-pour-la-premiere-fois"}]`const relatedPosts = await getEntries(blogPost.data.relatedPosts);---
<h1>{blogPost.data.title}</h1><p>Auteur : {author.data.name}</p>
<!-- ... -->
<h2>Vous pourriez également aimer :</h2>{relatedPosts.map(post => ( <a href={post.id}>{post.data.title}</a>))}Générer des routes à partir du contenu
Section intitulée « Générer des routes à partir du contenu »Les collections de contenu sont stockées en dehors du répertoire src/pages/. Cela signifie qu’aucune page ni route n’est générée par défaut pour les éléments de votre collection par le système de routage reposant sur les fichiers d’Astro.
Vous devrez créer manuellement une nouvelle route dynamique si vous souhaitez générer des pages HTML pour chacune des entrées de votre collection, telles que des articles de blog individuels. Cette route dynamique associera le paramètre de la requête entrante (par exemple, Astro.params.id dans src/pages/blog/[...id].astro) à l’élément correspondant sur chaque page.
La méthode exacte de génération des routes dépendra du fait que vos pages soient pré-rendues (par défaut) ou générées à la demande par un serveur.
Compilation pour sortie statique (par défaut)
Section intitulée « Compilation pour sortie statique (par défaut) »Si vous créez un site web statique (comportement par défaut d’Astro) avec des collections consommées lors de la compilation, utilisez la fonction getStaticPaths() pour créer plusieurs pages à partir d’un seul composant de page (par exemple src/pages/[id].astro) lors de votre compilation.
Appelez getCollection() à l’intérieur de getStaticPaths() pour que les données de votre collection soient disponibles pour la création de routes statiques. Ensuite, créez les chemins d’URL individuels à l’aide de la propriété id de chaque entrée de contenu. Chaque page reçoit l’intégralité de l’entrée de collection comme propriété à utiliser dans votre modèle de page.
---import { getCollection, render } from 'astro:content';// 1. Générer un nouveau chemin pour chaque entrée de collectionexport async function getStaticPaths() { const posts = await getCollection('blog'); return posts.map(post => ({ params: { id: post.id }, props: { post }, }));}// 2. Pour votre modèle, vous pouvez obtenir l'entrée directement à partir de la propriétéconst { post } = Astro.props;const { Content } = await render(post);---<h1>{post.data.title}</h1><Content />Cela générera une route de page pour chaque entrée de la collection blog. Par exemple, une entrée dans src/blog/hello-world.md possèdera un id avec la valeur hello-world, ainsi son URL finale sera /articles/hello-world/.
Si vos slugs personnalisés contiennent le caractère / pour produire des URL avec plusieurs segments de chemin, vous devez utiliser un paramètre du reste (par exemple [...id]) dans le nom de fichier .astro pour cette page de routage dynamique.
Création de routes à la demande au moment de la requête
Section intitulée « Création de routes à la demande au moment de la requête »Avec un adaptateur installé pour le rendu à la demande, vous pouvez générer vos routes de page dynamiques au moment de la requête. Commencez par examiner la requête (à l’aide de Astro.request ou Astro.params) pour trouver le slug demandé, puis récupérez-le à l’aide d’une des fonctions utilitaires des collections de contenu d’Astro :
getEntry()pour les pages de collection consommées au moment de la compilation, qui sont générées une seule fois, lors de la première requête.getLiveEntry()pour les pages de collection en direct où les données sont récupérées (à nouveau) à chaque requête.
---export const prerender = false; // Pas nécessaire en mode `server`
import { getEntry, render } from "astro:content";
// 1. Récupérer le slug de la requête entrante du serveur.const { id } = Astro.params;if (id === undefined) { return Astro.redirect("/404");}
// 2. Interroger l'entrée directement en utilisant le slug de la requête.const post = await getEntry("blog", id);
// 3. Rediriger si l'entrée n'existe pasif (post === undefined) { return Astro.redirect("/404");}
// 4. Effecter le rendu de l'entrée en HTML dans le modèleconst { Content } = await render(post);---<h1>{post.data.title}</h1><Content />Explorez le dossier src/pages/ du code de démonstration du tutoriel de blog sur GitHub pour voir des exemples complets de création de pages dynamiques à partir de vos collections pour des fonctionnalités de blog telles qu’une liste d’articles de blog, des pages de tags, et plus encore !
Collections de contenu en direct
Section intitulée « Collections de contenu en direct »Les collections en direct utilisent une API différente de celle des collections de contenu consommées lors de la compilation, même si les fonctions de configuration et utilitaires sont conçues pour être familières.
Les principales différences sont les suivantes :
- Moment d’exécution : Exécuté au moment de la requête et non au moment de la compilation
- Fichier de configuration : Utilise
src/live.config.tsau lieu desrc/content.config.ts - Définition de collections : Utilise
defineLiveCollection()au lieu dedefineCollection() - API du chargeur : Implémente les méthodes
loadCollectionetloadEntryau lieu de la méthodeload - Données renvoyées : Renvoie les données directement au lieu de les stocker dans le magasin de données
- Fonctions destinées aux utilisateurs : Utilise
getLiveCollection()/getLiveEntry()au lieu degetCollection()/getEntry()
De plus, vous devez disposer d’un adaptateur configuré pour le rendu à la demande des données de la collection en direct.
Définissez vos collections en direct dans le fichier spécial src/live.config.ts (distinct de votre fichier src/content.config.ts pour les collections consommées lors de la compilation, si vous en avez un).
Chaque collection configure :
- un chargeur en direct (
loader) pour votre source de données, et éventuellement pour la sûreté du typage (obligatoire) - un schéma de collection en direct (
schema) pour la sûreté du typage (optionnel)
Contrairement aux collections consommées lors de la compilation, aucun chargeur en direct intégré n’est disponible. Vous devrez créer un chargeur en direct personnalisé pour votre source de données spécifique ou trouver un chargeur tiers à transmettre à la propriété loader de votre collection en direct.
Vous pouvez éventuellement inclure la sûreté du typage dans vos chargeurs en direct. Par conséquent, définir un schéma Zod pour les collections en direct est facultatif. Cependant, si vous en fournissez un, il sera prioritaire sur les types du chargeur en direct.
// Définir des collections en direct pour accéder aux données en temps réelimport { defineLiveCollection } from 'astro:content';import { storeLoader } from '@mystore/astro-loader';
const products = defineLiveCollection({ loader: storeLoader({ apiKey: process.env.STORE_API_KEY, endpoint: 'https://api.mystore.com/v1', }),});
// Exporter un seul objet `collections` pour enregistrer votre ou vos collections.export const collections = { products };Vous pouvez ensuite utiliser les fonctions dédiées getLiveCollection() et getLiveEntry() pour accéder à vos données en direct et afficher votre contenu.
Vous pouvez générer des routes de page à partir des entrées de votre collection en direct à la demande, en récupérant des données fraîches au moment de l’exécution à chaque requête sans avoir besoin d’une recompilation de votre site comme le font les collections consommées lors de la compilation. Ceci est utile lorsque l’accès à des données en direct et actualisées est plus important que la disponibilité de votre contenu dans une couche de stockage de données performante qui persiste entre les différentes compilations du site.
Création d’un chargeur en direct
Section intitulée « Création d’un chargeur en direct »Vous pouvez créer un chargeur en direct personnalisé en utilisant l’API des chargeurs en direct pour récupérer du contenu distant à la demande à partir de n’importe quelle source de données, telle qu’un CMS, une base de données ou un point de terminaison d’API. Vous devrez indiquer à votre chargeur en direct comment récupérer et renvoyer les entrées de contenu à partir de votre source de données souhaitée, ainsi que prévoir la gestion des erreurs pour les requêtes de données infructueuses.
L’utilisation d’un chargeur en direct pour récupérer vos données créera automatiquement une collection à partir de vos données distantes. Vous bénéficierez ainsi de tous les avantages des collections de contenu d’Astro, notamment des fonctions utilitaires spécifiques à l’API des collections telles que getLiveCollection() et render() pour interroger et afficher vos données, ainsi que d’une gestion utile des erreurs.
Trouvez des chargeurs en direct créés par la communauté et par des tiers dans le répertoire des intégrations d’Astro.
Utilisation des schémas Zod avec des collections en direct
Section intitulée « Utilisation des schémas Zod avec des collections en direct »Vous pouvez utiliser des schémas Zod avec des collections en direct pour valider et transformer les données à l’exécution. Cette validation Zod fonctionne de la même manière que les schémas pour les collections consommées lors de la compilation.
Lorsque vous définissez un schéma pour une collection en direct, celui-ci a priorité sur les types du chargeur en direct lorsque vous interrogez la collection :
import { defineLiveCollection } from 'astro:content';import { z } from 'astro/zod';import { apiLoader } from './loaders/api-loader';
const products = defineLiveCollection({ loader: apiLoader({ endpoint: process.env.API_URL }), schema: z .object({ id: z.string(), name: z.string(), price: z.number(), // Transformer le format de catégorie de l'API category: z.string().transform((str) => str.toLowerCase().replace(/\s+/g, '-')), // Convertir la date en un objet Date createdAt: z.coerce.date(), }) .transform((data) => ({ ...data, // Ajouter un champ de prix formaté displayPrice: `${data.price.toFixed(2)} €`, })),});
export const collections = { products };Lors de l’utilisation de schémas Zod avec des collections en direct, les erreurs de validation sont automatiquement interceptées et renvoyées sous forme d’objets AstroError :
---export const prerender = false; // Pas nécessaire en mode `server`
import { LiveCollectionValidationError } from 'astro/content/runtime';import { getLiveEntry } from 'astro:content';
const { entry, error } = await getLiveEntry('products', '123');
// Vous pouvez gérer spécifiquement les erreurs de validationif (LiveCollectionValidationError.is(error)) { console.error(error.message); return Astro.rewrite('/500');}
// TypeScript sait que entry.data correspond à votre schéma Zod, et non au type du chargeur.console.log(entry?.data.displayPrice); // p. ex., "29.99 €"---Accès aux données en direct
Section intitulée « Accès aux données en direct »Astro fournit des fonctions utilitaires pour les collections en direct permettant d’accéder aux données en temps réel à chaque requête et de renvoyer une ou plusieurs entrées de contenu. Celles-ci peuvent être utilisées de la même manière que leurs homologues des collections consommées lors de la compilation.
getLiveCollection()récupère une collection entière et renvoie un tableau d’entrées.getLiveEntry()récupère une seule entrée d’une collection.
Ces fonctions renvoient des entrées avec un identifiant unique (id) et un objet data contenant toutes les propriétés définies par le chargeur en direct. Lors de l’utilisation de chargeurs tiers ou communautaires distribués sous forme de paquets npm, veuillez consulter leur documentation pour connaître le format des données renvoyées.
Vous pouvez utiliser ces fonctions pour accéder à vos données en direct, en transmettant le nom de la collection et, éventuellement, des conditions de filtrage.
---export const prerender = false; // Pas nécessaire en mode `server`
import { getLiveCollection, getLiveEntry } from 'astro:content';
// Utiliser des filtres spécifiques au chargeurconst { entries: draftArticles } = await getLiveCollection('articles', { status: 'brouillon', author: 'john-doe',});
// Obtenir un produit spécifique par son identifiantconst { entry: product } = await getLiveEntry('produits', Astro.params.slug);---Génération du contenu
Section intitulée « Génération du contenu »Si votre chargeur en direct renvoie une propriété rendered, vous pouvez utiliser la fonction render() et le composant <Content /> pour générer votre contenu directement dans vos pages, en utilisant la même méthode que les collections consommées lors de la compilation.
Vous avez également accès à toute erreur renvoyée par le chargeur en direct, par exemple, pour rediriger vers une page 404 lorsque le contenu ne peut pas être affiché :
---export const prerender = false; // Pas nécessaire en mode `server`
import { getLiveEntry, render } from 'astro:content';const { entry, error } = await getLiveEntry('articles', Astro.params.id);if (error) { return Astro.rewrite('/404');}
const { Content } = await render(entry);---
<h1>{entry.data.title}</h1><Content />Gestion des erreurs
Section intitulée « Gestion des erreurs »Les chargeurs en direct peuvent échouer en raison de problèmes de réseau, d’erreurs d’API ou de problèmes de validation. L’API est conçue pour rendre la gestion des erreurs explicite.
Lorsque vous appelez getLiveCollection() ou getLiveEntry(), l’erreur sera l’une des suivantes :
- Le type d’erreur défini par le chargeur (s’il a renvoyé une erreur)
- Une erreur
LiveEntryNotFoundErrorsi l’entrée est introuvable - Une erreur
LiveCollectionValidationErrorsi les données de la collection ne correspondent pas au schéma attendu - Une erreur
LiveCollectionCacheHintErrorsi l’indication de cache est invalide - Une erreur
LiveCollectionErrorpour les autres types d’erreurs, comme les erreurs non interceptées émises par le chargeur
Vous pouvez utiliser instanceof pour vérifier le type d’une erreur lors de l’exécution :
---export const prerender = false; // Pas nécessaire en mode `server`
import { LiveEntryNotFoundError } from 'astro/content/runtime';import { getLiveEntry } from 'astro:content';
const { entry, error } = await getLiveEntry('produits', Astro.params.id);
if (error) { if (error instanceof LiveEntryNotFoundError) { console.error(`Produit introuvable : ${error.message}`); Astro.response.status = 404; } else { console.error(`Erreur lors du chargement du produit : ${error.message}`); return Astro.redirect('/500'); }}---Utiliser des fichiers de schéma JSON dans votre éditeur
Section intitulée « Utiliser des fichiers de schéma JSON dans votre éditeur »
Ajouté à la version :
astro@4.13.0
Astro génère automatiquement des fichiers de schéma JSON pour les collections, que vous pouvez utiliser dans votre éditeur pour obtenir IntelliSense et la vérification de type pour les fichiers de données.
Un fichier de schéma JSON est généré pour chaque collection de votre projet et enregistré dans le répertoire .astro/collections/.
Par exemple, si vous avez deux collections, l’une nommée auteurs et l’autre nommée articles, Astro générera .astro/collections/auteurs.schema.json et .astro/collections/articles.schema.json.
Utiliser des schémas JSON dans les fichiers JSON
Vous pouvez indiquer manuellement un schéma généré par Astro en définissant le champ $schema dans votre fichier JSON.
La valeur doit être un chemin relatif entre le fichier de données et le schéma.
Dans l’exemple suivant, un fichier de données situé dans src/data/auteurs/ utilise le schéma généré pour la collection auteurs :
{ "$schema": "../../../.astro/collections/auteurs.schema.json", "nom": "Armand", "competences": ["Astro", "Starlight"]}Utiliser un schéma pour un groupe de fichiers JSON dans VS Code
Dans VS Code, vous pouvez configurer un schéma à appliquer à tous les fichiers d’une collection à l’aide du paramètre json.schemas.
Dans l’exemple suivant, tous les fichiers du répertoire src/data/auteurs/ utiliseront le schéma généré pour la collection auteurs :
{ "json.schemas": [ { "fileMatch": ["/src/data/auteurs/**"], "url": "./.astro/collections/auteurs.schema.json" } ]}Utiliser des schémas dans les fichiers YAML dans VS Code
Dans VS Code, vous pouvez ajouter la prise en charge de l’utilisation de schémas JSON dans les fichiers YAML à l’aide de l’extension Red Hat YAML. Une fois cette extension installée, vous pouvez référencer un schéma dans un fichier YAML en utilisant une syntaxe de commentaire spéciale :
# yaml-language-server: $schema=../../../.astro/collections/auteurs.schema.jsonnom: Armandcompetences: - Astro - StarlightUtiliser des schémas pour un groupe de fichiers YAML dans VS Code
Avec l’extension Red Hat YAML, vous pouvez configurer un schéma à appliquer à tous les fichiers YAML d’une collection à l’aide du paramètre yaml.schemas.
Dans l’exemple suivant, tous les fichiers YAML du répertoire src/data/auteurs/ utiliseront le schéma généré pour la collection auteurs :
{ "yaml.schemas": { "./.astro/collections/auteurs.schema.json": ["/src/content/auteurs/*.yml"] }}Consultez la section « Associating schemas » dans la documentation de l’extension YAML de Red Hat pour plus de détails.
Learn