SPEC — Finalisation & Correction du Composant 2 : Blog
SPEC — Finalisation & Correction du Composant 2 : Blog
Documentation technique
Cycle : DOC → SPEC → CODE → TEST
Scope : Correction des 4 points soulevés lors de la validation (Design listing, Bio auteur, SEO complet, Pagination SSR)
Destination Spec :docs/PM/phase0-blog-validation-fix.spec.md
1. Problème 1 : Design du listing /blog/ (Interface & Layout non homogène)
1.1 Constat (Screenshot 1)
- La mise en page du listing
/blog/actuelle manque de finition et de cohérence visuelle. - Le 1er élément avait un comportement CSS particulier (
width: 100%, image géante), tandis que les suivants étaient décalés en dessous. - Absence d’un composant de carte d’article harmonieux (badges de catégories, avatar auteur, temps de lecture, mise en page en grille responsive 3 colonnes / 2 colonnes / 1 colonne sur mobile).
1.2 Solution & Spécification technique
Fichier : apps/web/src/pages/blog/index.astro et/ou composant apps/web/src/components/BlogCard.astro
- Créer une grille CSS moderne et responsive (
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr))). - Tous les articles possèdent une carte au design identique et soigné :
- Image de couverture avec
aspect-ratio: 16/9,object-fit: coveret effet de survol zoom/box-shadow. - Badges des catégories en haut de la carte.
- Titre propre et bien typographié.
- Extrait (
excerpt) tronqué à 2 lignes avecline-clamp. - Pied de carte avec l’avatar de l’auteur, le nom de l’auteur et la date de publication.
- Image de couverture avec
2. Problème 2 : Affichage de la Bio de l’Auteur dans /blog/[slug].astro
2.1 Constat (Screenshot 2)
- Sur la page de détail de l’article, l’auteur apparaît sous la forme d’un petit avatar avec “By: name”.
- La Bio de l’auteur configurée dans Sanity Studio (“Platform & Cloud Engineer @ Audyssee…”) n’est pas affichée.
2.2 Solution & Spécification technique
Fichiers : apps/web/src/pages/blog/[slug].astro et apps/web/src/components/AuthorCard.astro (ou bloc auteur dédié).
- Extension Query GROQ dans
[slug].astro:author->{_id,name,slug,image{asset->{ _id, url, metadata { lqip, dimensions } },alt},bio} - Affichage du composant/bloc Auteur :
- En bas de chaque article (et/ou dans l’en-tête), intégrer un encadré Auteur (“À propos de l’auteur”) comprenant :
- Grand avatar de l’auteur (
64x64ou80x80arrondi). - Nom et rôle de l’auteur.
- Rendement du champ
author.bio(PortableText) converti en HTML viarenderPortableText(author.bio).
- Grand avatar de l’auteur (
- En bas de chaque article (et/ou dans l’en-tête), intégrer un encadré Auteur (“À propos de l’auteur”) comprenant :
3. Problème 5 : Métadonnées SEO avancées & Open Graph
3.1 Constat
BaseHead.astroattend actuellement un objetImageMetadataAstro importé localement. Si une URL d’image Sanity CDN est transmise (string), Open Graph et Twitter fallbackent sur l’image par défaut.- Absence de balises Twitter (
twitter:title,twitter:description,twitter:image), de balises OpenGraph d’article (og:type="article",article:published_time,article:author) et de données structurées JSON-LDBlogPostingpour les moteurs de recherche.
3.2 Solution & Spécification technique1/2
Fichiers : apps/web/src/components/BaseHead.astro et apps/web/src/pages/blog/[slug].astro
-
BaseHead.astro:- Accepter
image?: ImageMetadata | string; - Déterminer
imageUrl: si string, l’utiliser directement ; siImageMetadata, utilisernew URL(image.src, Astro.url).toString(). - Ajouter les balises Twitter complètes :
<meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content={title} /><meta name="twitter:description" content={description} /><meta name="twitter:image" content={imageUrl} />
- Accepter un type
ogType(websitepar défaut,articlepour les articles).
- Accepter
3.2 Solution & Spécification technique2/2
-
JSON-LD Schema.org dans
[slug].astro:- Injecter un bloc
<script type="application/ld+json">avec le schémaBlogPosting:{"@context": "https://schema.org","@type": "BlogPosting","headline": "...","description": "...","image": "...","datePublished": "...","author": { "@type": "Person", "name": "..." }}
- Injecter un bloc
4. Problème 6 : Pagination SSR du Listing (/blog/)
4.1 Constat
- Le listing des articles affiche tous les articles sur une seule page sans système de pagination.
4.2 Solution & Spécification technique
Fichier : apps/web/src/pages/blog/index.astro
- Gestion de la pagination via paramètre URL SSR (
?page=1,?page=2) :- Définir
POSTS_PER_PAGE = 6. - Lire le paramètre URL
const currentPage = Math.max(1, Number(Astro.url.searchParams.get('page') || '1')). - Calculer les index GROQ
$start = (currentPage - 1) * POSTS_PER_PAGEet$end = start + POSTS_PER_PAGE.
- Définir
- Requetage Sanity paginé :
{"posts": *[_type == "post"] | order(publishedAt desc)[$start...$end] {_id, _type, title, slug, excerpt, publishedAt,mainImage { asset->{ _id, url, metadata { lqip, dimensions } }, alt },author->{ _id, name, image { asset->{ _id, url } } },categories[]->{ _id, title }},"total": count(*[_type == "post"])}
- Barre de Navigation de Pagination :
- Afficher les boutons
PrécédentetSuivantavec indicationPage X sur Y. - Masquer ou désactiver les boutons lorsque sur la 1ère ou dernière page.
- Afficher les boutons
5. Matrice de validation & Critères d’acceptation (TEST)
- Design Listing : Grille d’articles 3D/2D responsive avec cartes uniformes, badges catégories et pied de carte auteur.
- Bio Auteur : L’encadré auteur en bas de l’article affiche le nom, l’avatar ET le texte complet de la Bio Sanity.
- SEO Complet : Balises
<meta name="description">,og:imageavec URL Sanity CDN valide, balises Twitter et bloc JSON-LDBlogPosting. - Pagination SSR : Navigation fonctionnelle avec
?page=1,?page=2, désactivation des boutons aux bornes et total exact. - Contrôle des types :
npx pnpm@12.3.4 typecheck-> 0 erreurs.