Skip to content

Diagnostic et plan - Découplage du contenu /blog via Sanity

Diagnostic & Plan d’exécution — Découplage du Contenu /blog via Sanity

Section titled “Diagnostic & Plan d’exécution — Découplage du Contenu /blog via Sanity”

Date : 2026-10-18
Auteurs : Pair-programming Antigravity IDE & Anderson
Référence : Spécification utilisateur (plan/description.md), ADR-001
Dépôts cibles :


L’analyse du code source d’amn-blog et du dataset Sanity development (projet 4wa7mvsz) révèle une séparation incomplète entre contenu éditorial et présentation :

Éléments de la page /blog Composant Astro État actuel Piloté par Sanity ? Problème constaté
Liste des articles & pagination index.astro & BlogCard.astro Requête GROQ SSR dynamique : *[_type == "post"] paginée par 5 OUI (avec fallback Markdown local) Conforme à l’architecture.
Hero (Titre & Sous-titre) BlogHero.astro Valeurs codées en dur dans index.astro : title="Welcome, world", subtitle="Get all the latest news from the Amnworld." NON (Hardcodé dans Astro) Tout changement de slogan ou de titre nécessite un commit de code Astro.
Sidebar — Popular posts PopularPosts.astro Prend les 4 premiers posts récents, mais a une liste de 4 articles en dur (defaultPopularPosts) si vide. Pas de sélection éditoriale dans Sanity. PARTIELLEMENT L’éditeur ne peut pas choisir manuellement les articles mis en avant dans la sidebar.
Sidebar — Callout plateforme (“AMN platform”) MerchCallout.astro Titre, description, URL vers les docs et badges codés en dur dans le composant. NON (100% hardcodé) L’encart publicitaire/plateforme ne peut pas être modifié sans déployer le front.
Sidebar — Inscription RSS SubscribeRss.astro Titre “Subscribe” et sous-titre codés en dur. NON (Hardcodé) Textes figés dans le code Astro.
Métadonnées SEO du Blog index.astro -> MainLayout.astro title="Blog — Latest news & insights", description="..." passés en dur dans index.astro. NON (Hardcodé) Les métadonnées du blog ne sont pas configurables depuis Sanity.

Dans amn-studio/schemaTypes/, les schémas existants sont :

  • post, author, category, blockContent
  • page (avec pageBuilder : hero, features, testimonials, cta, richText, imageGallery)
  • amn (document de test minimal avec message + status)
  • submission (formulaires)

👉 Constat clé : Il n’existe aucun schéma blogSettings (ou réglages de page de blog) dans Sanity. C’est la raison pour laquelle les textes du hero, de la sidebar et du SEO avaient été initialement renseignés en dur dans Astro.


2. Architecture cible (Séparation stricte CMS / Présentation)

Section titled “2. Architecture cible (Séparation stricte CMS / Présentation)”

Conformément à l’ADR-001 :

  • Sanity (amn-studio) = Contenu brut & Gouvernance éditoriale (titres, textes, slogans, liens, sélections d’articles populaires, encarts promo).
  • Astro (amn-blog) = Moteur de présentation pur (balisage HTML5 sémantique, design Tailwind CSS, responsive, accessibilité, rendu SSR).
+-----------------------------------------------------------------------+
| SANITY STUDIO (amn-studio) |
| |
| Document Singleton "blogSettings" : |
| • heroTitle: "Welcome, world" |
| • heroSubtitle: "Get all the latest news from the Amnworld." |
| • popularPosts: [ Ref(post1), Ref(post2), Ref(post3) ] |
| • callout: { title, description, linkUrl, badgeText } |
| • subscribe: { title, subtitle, rssUrl } |
| • seo: { metaTitle, metaDescription, ogImage } |
+-----------------------------------▲-----------------------------------+
│ Requête GROQ SSR
│ (loadQuery)
+-----------------------------------▼-----------------------------------+
| ASTRO SSR (amn-blog) |
| |
| 1. index.astro fetch posts + blogSettings en une seule passe |
| 2. Injecte dynamiquement les données dans : |
| • <BlogHero title={settings.heroTitle} ... /> |
| • <BlogSidebar popularPosts={settings.popularPosts} ... /> |
| • <MainLayout title={settings.seo.metaTitle} ... /> |
| 3. Aucun texte de contenu en dur dans le code Astro |
+-----------------------------------------------------------------------+

Étape 1 : Création du schéma blogSettings.ts dans amn-studio

Section titled “Étape 1 : Création du schéma blogSettings.ts dans amn-studio”

Ajouter le schéma singleton blogSettings avec les champs :

  • Hero :
    • heroTitle (string, titre d’accueil)
    • heroSubtitle (text, sous-titre)
  • Popular posts :
    • popularPosts (array de références vers post, avec prévisualisation)
  • Callout Encart Plateforme :
    • calloutTitle (string)
    • calloutDescription (text)
    • calloutLink (url / string)
    • calloutBadgeText (string, ex: “Audyssée architecture”)
  • Subscribe RSS :
    • subscribeTitle (string)
    • subscribeSubtitle (text)
  • SEO & Réseaux :
    • metaTitle (string)
    • metaDescription (text)
    • ogImage (image)

Enregistrer blogSettings dans amn-studio/schemaTypes/index.ts.


Étape 2 : Création & initialisation du document blogSettings dans le dataset Sanity

Section titled “Étape 2 : Création & initialisation du document blogSettings dans le dataset Sanity”
  • Via les outils MCP Sanity (create_documents) ou script, créer le document initial blogSettings avec les valeurs actuelles pour assurer une continuité parfaite sans rupture.

Étape 3 : Mise à jour de la requête GROQ dans amn-blog/src/pages/blog/index.astro

Section titled “Étape 3 : Mise à jour de la requête GROQ dans amn-blog/src/pages/blog/index.astro”

Adapter la requête pour récupérer posts, total ET settings en un seul appel :

{
"posts": *[_type == "post"] | order(publishedAt desc)[$start...$end] {
_id, title, slug, excerpt, publishedAt, mainImage { asset->{ url }, alt },
author->{ name, image { asset->{ url } } }, categories[]->{ _id, title }
},
"total": count(*[_type == "post"]),
"settings": *[_type == "blogSettings"][0] {
heroTitle,
heroSubtitle,
metaTitle,
metaDescription,
calloutTitle,
calloutDescription,
calloutLink,
calloutBadgeText,
subscribeTitle,
subscribeSubtitle,
"selectedPopularPosts": popularPosts[]->{
title,
"href": "/blog/" + slug.current + "/"
}
}
}

Étape 4 : Injection dynamique dans les composants Astro

Section titled “Étape 4 : Injection dynamique dans les composants Astro”
  1. BlogHero.astro : Reçoit title et subtitle depuis settings (avec fallback élégant si non défini).
  2. BlogSidebar.astro : Transmet les données dynamiques callout, subscribe et popularPosts à ses sous-composants.
  3. PopularPosts.astro : Utilise les articles sélectionnés dans Sanity (ou à défaut les articles les plus récents de Sanity).
  4. MerchCallout.astro : Affiche le titre, la description, le badge et le lien issus de settings.
  5. SubscribeRss.astro : Affiche les libellés issus de settings.
  6. MainLayout.astro : Reçoit metaTitle et metaDescription issus de settings.

Étape 5 : Validation & Traitement des retours utilisateurs (Feedback)

Section titled “Étape 5 : Validation & Traitement des retours utilisateurs (Feedback)”

Suite aux retours utilisateurs, les éléments complémentaires suivants ont été entièrement découplés et confiés à Sanity :

  1. Titre de la section “Popular posts” : Ajout du champ popularPostsTitle (string) dans le schéma blogSettings, récupéré dynamiquement et transmis à <PopularPosts title={popularPostsTitle} />.

  2. Visuel de l’encart callout (“Audyssée architecture”) & lien cliquable : Ajout du champ calloutImage (image avec hotspot) dans blogSettings. Le visuel est rendu sous forme de lien cliquable (<a href={href}>) avec l’image Sanity si fournie, ou avec le visuel vectoriel par défaut si aucune image n’est téléversée.

  3. Bouton & lien RSS Feed : Ajout des champs subscribeButtonLabel (“RSS Feed”) et subscribeRssLink (“/rss.xml”) dans blogSettings, transmis dynamiquement à <SubscribeRss />.

  4. Refonte visuelle du Merch Callout (conforme au style Astro) :

    • Élimination de la boîte/carte imbriquée interne autour du visuel.
    • Suppression du contour de carte (border border-purple-500/20, fond boîte) : la section s’intègre directement et harmonieusement dans la sidebar, délimitée uniquement par la bordure inférieure de section.
    • L’image occupe toute la largeur utile sous le titre et la description, avec coins arrondis (rounded-xl), intégrée dans un lien cliquable global (<a href={href}>).

Élément Propriété Sanity Statut
Titre du hero blogSettings.heroTitle ✅ Découplé & En ligne
Sous-titre du hero blogSettings.heroSubtitle ✅ Découplé & En ligne
Titre “Popular posts” blogSettings.popularPostsTitle ✅ Découplé & En ligne
Liste des articles populaires blogSettings.popularPosts[] ✅ Découplé & En ligne
Titre callout blogSettings.calloutTitle ✅ Découplé & En ligne
Description callout blogSettings.calloutDescription ✅ Découplé & En ligne
Badge callout blogSettings.calloutBadgeText ✅ Découplé & En ligne
Image callout cliquable blogSettings.calloutImage + calloutLink ✅ Découplé & En ligne
Titre & Sous-titre subscribe blogSettings.subscribeTitle / subscribeSubtitle ✅ Découplé & En ligne
Libellé & URL bouton RSS blogSettings.subscribeButtonLabel / subscribeRssLink ✅ Découplé & En ligne
Métadonnées SEO blogSettings.metaTitle / metaDescription ✅ Découplé & En ligne
Edit page

Last updated: