vendredi 25 septembre 2026

À propos

Contact

Headless & API

Astro 5 et le Content Layer : charger WordPress comme une collection

Écrire un loader Content Layer pour importer des contenus WordPress dans Astro, typés et rebuild-friendly, sans plugin générique tout-fait.

Par Clément Hadrot • 4 août 2025 • 4 min de lecture • Aucun commentaire
Astro 5 et le Content Layer : charger WordPress comme une collection

Le Content Layer d’Astro traite historiquement les fichiers Markdown locaux comme des collections typées. La question s’est posée sur un projet de blog culturel : pourquoi ne pas traiter WordPress exactement de la même façon, comme une source de collection parmi d’autres, plutôt que de bricoler des appels fetch dispersés dans les pages ? Un loader personnalisé permet précisément cela.

Ce choix évite d’installer un plugin générique aux options mal maîtrisées : le loader reste un simple fichier, entièrement lisible, adapté exactement au schéma du site.

Déclarer la collection

Dans src/content/config.ts, la collection s’appuie sur un loader personnalisé plutôt que sur un dossier de fichiers, avec un schéma validé via Zod :

import { defineCollection, z } from 'astro:content';
import { loaderWordPress } from '../loaders/wordpress';

const articles = defineCollection({
  loader: loaderWordPress({ url: 'https://cms.exemple.fr/graphql' }),
  schema: z.object({
    titre: z.string(),
    slug: z.string(),
    extrait: z.string(),
    datePublication: z.string(),
  }),
});

export const collections = { articles };

Écrire le loader lui-même

Un loader Content Layer expose une fonction qui reçoit un contexte avec un accès au store de données d’Astro, dans lequel chaque élément est inséré avec un identifiant stable :

export function loaderWordPress({ url }) {
  return {
    name: 'loader-wordpress',
    load: async ({ store, logger }) => {
      const reponse = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query: REQUETE_ARTICLES }),
      });
      const { data } = await reponse.json();

      store.clear();
      for (const article of data.posts.nodes) {
        store.set({
          id: article.slug,
          data: {
            titre: article.title,
            slug: article.slug,
            extrait: article.excerpt,
            datePublication: article.date,
          },
        });
      }
      logger.info(`${data.posts.nodes.length} articles chargés depuis WordPress`);
    },
  };
}
L'essentiel à retenir : WordPress devient une collection de contenu comme les fichiers locaux ; Le schéma est validé au moment du chargement, pas au rendu ; Les rebuilds peuvent rester incrémentaux plutôt que tout recharger

Ce que la validation de schéma apporte

Si un champ attendu manque côté WordPress (un extrait vide sur un article mal renseigné), Astro le signale au moment du chargement, avec un message d’erreur explicite pointant vers l’élément fautif. C’est une différence appréciable par rapport à un simple fetch dans une page, où une donnée manquante ne se découvre souvent qu’au rendu, sous forme d’un affichage cassé silencieux.

Consommer la collection dans une page

Une fois la collection déclarée, elle se consomme exactement comme n’importe quelle collection basée sur des fichiers locaux, avec les mêmes fonctions getCollection et getEntry déjà connues des utilisateurs d’Astro :

---
import { getCollection } from 'astro:content';
const tousLesArticles = await getCollection('articles');
---
<ul>
  {tousLesArticles.map((a) => <li>{a.data.titre}</li>)}
</ul>

Le reste de l’équipe front, qui ne connaît pas forcément WPGraphQL, manipule une collection Astro classique, sans avoir besoin de comprendre le détail de la requête envoyée à WordPress en coulisses.

Rebuilds incrémentaux

Le store fourni au loader permet, plutôt que de vider et recharger l’intégralité de la collection à chaque fois, de ne mettre à jour que les éléments réellement modifiés depuis le dernier chargement, à condition de comparer une date de modification avant de réécrire chaque entrée. Sur ce projet, le loader interroge d’abord les identifiants et dates de modification, puis ne redemande le contenu complet que pour les articles réellement changés.

  • Utiliser le champ modified de chaque contenu WordPress comme référence de comparaison.
  • Conserver la date du dernier chargement complet dans le contexte du loader entre deux exécutions.
  • Ne réécrire dans le store que les entrées dont la date de modification a réellement changé.

Un loader Content Layer maison prend une heure à écrire correctement, contre plusieurs jours passés par le passé à configurer et déboguer un plugin générique pas toujours pensé pour le schéma exact du projet.

Ce qu’on retient

Le Content Layer d’Astro traite WordPress avec la même rigueur que n’importe quelle autre source de contenu : schéma validé, identifiants stables, chargement incrémental possible. Pour un site qui n’a pas besoin de rendu dynamique à chaque requête, cette approche simplifie nettement la relation entre WordPress et le générateur de site statique, sans dépendance à un plugin tiers à la roadmap incertaine.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi