Spécification : Implémentation Page d'accueil
Spécification : Implémentation Page d'accueil
Documentation technique
Slice : Slice 1 (Page d’accueil)
Cycle : DOC → SPEC → CODE → TEST → INTÉG
Statut : INTÉG
1. Objectif
Implémenter la page d’accueil avec rendu PageBuilder depuis Sanity, en mode SSG selon l’ADR-SSR-Pur.md, avec support du mode preview.
2. Configuration technique
2.1. Configuration Astro1/2
Fichier : apps/web/astro.config.mjs
Configuration actuelle :
export default defineConfig({ output: 'server', // Hybride : static par défaut, SSR à la demande via prerender = false adapter: cloudflare({ imageService: 'passthrough', prerenderEnvironment: 'node', }),});2.1. Configuration Astro2/2
Pour la page d’accueil :
- Ajouter
export const prerender = truedansindex.astro - Cela force le SSG pour cette page spécifique
2.2. Query GROQ1/2
Fichier : apps/web/src/pages/index.astro
Query pour récupérer la page d’accueil :
2.2. Query GROQ2/2
*[_type == "page" && slug.current == "/"][0]{ title, description, pageBuilder[]{ _type, _key, select( _type == "hero" => { heading, subheading, ctaText, ctaLink, image }, _type == "features" => { heading, features[]{ title, description, icon } }, _type == "testimonials" => { heading, testimonials[]{ name, role, quote, avatar } }, _type == "cta" => { heading, description, buttonText, buttonLink }, _type == "richText" => { content }, _type == "imageGallery" => { heading, images[]{ asset, alt, caption } } ) }}3. Structure des fichiers
3.1. Composants PageBuilder
Répertoire : apps/web/src/components/pagebuilder/
Fichiers à créer :
Hero.astro: Composant pour bloc heroFeatures.astro: Composant pour bloc featuresTestimonials.astro: Composant pour bloc testimonialsCTA.astro: Composant pour bloc CTARichText.astro: Composant pour bloc richTextImageGallery.astro: Composant pour bloc imageGallery
3.2. Page d’accueil1/2
Fichier : apps/web/src/pages/index.astro
Structure :
3.2. Page d’accueil2/2
---export const prerender = true;
import { getSanityClient } from '../lib/sanity';import MainLayout from '../layouts/MainLayout.astro';import Hero from '../components/pagebuilder/Hero.astro';import Features from '../components/pagebuilder/Features.astro';import Testimonials from '../components/pagebuilder/Testimonials.astro';import CTA from '../components/pagebuilder/CTA.astro';import RichText from '../components/pagebuilder/RichText.astro';import ImageGallery from '../components/pagebuilder/ImageGallery.astro';
const client = getSanityClient();const page = await client.fetch(/* GROQ query */);---
<MainLayout title={page?.title} description={page?.description}> {page?.pageBuilder?.map((block) => { switch (block._type) { case 'hero': return <Hero {...block} />; case 'features': return <Features {...block} />; case 'testimonials': return <Testimonials {...block} />; case 'cta': return <CTA {...block} />; case 'richText': return <RichText {...block} />; case 'imageGallery': return <ImageGallery {...block} />; default: return null; } })}</MainLayout>4. Implémentation des composants
4.1. Hero.astro
Structure :
---interface Props { heading: string; subheading?: string; ctaText?: string; ctaLink?: string; image?: any;}
const { heading, subheading, ctaText, ctaLink, image } = Astro.props;---
<section class="hero"> <div class="hero-content"> <h1>{heading}</h1> {subheading && <p>{subheading}</p>} {ctaText && ctaLink && ( <a href={ctaLink} class="cta-button">{ctaText}</a> )} </div> {image && <img src={image} alt={heading} />}</section>4.2. Features.astro
Structure :
---interface Props { heading?: string; features: Array<{ title: string; description: string; icon?: string; }>;}
const { heading, features } = Astro.props;---
<section class="features"> {heading && <h2>{heading}</h2>} <div class="features-grid"> {features.map((feature) => ( <div class="feature"> {feature.icon && <span class="icon">{feature.icon}</span>} <h3>{feature.title}</h3> <p>{feature.description}</p> </div> ))} </div></section>4.3. Autres composants
Implémentation similaire avec :
- Testimonials.astro : Grille de témoignages
- CTA.astro : Section call-to-action
- RichText.astro : Rendu Portable Text
- ImageGallery.astro : Galerie d’images
5. Intégration mode preview
5.1. Utilisation de getSanityClient()
Fichier : apps/web/src/lib/sanity.ts
Fonction existante :
export function getSanityClient() { const isPreview = Astro.cookies.has('sanity-preview');
return createClient({ projectId: import.meta.env.SANITY_PROJECT_ID, dataset: import.meta.env.SANITY_DATASET, apiVersion: '2026-09-06', useCdn: !isPreview, perspective: isPreview ? 'previewDrafts' : 'published', ...(isPreview && { token: import.meta.env.SANITY_API_READ_TOKEN, }), });}5.2. Cookie preview
Déjà configuré dans le middleware Cloudflare
- Cookie :
sanity-preview=true - Détection automatique dans
getSanityClient()
6. Tests et validation
6.1. Tests de build
Commandes :
task build:webAttendu :
- Build réussi sans erreurs
- Page d’accueil générée en HTML statique
- Fichiers CSS générés
6.2. Tests de rendu
Commandes :
task devAttendu :
- Page d’accueil accessible sur
http://localhost:4321 - Blocs PageBuilder rendus correctement
- Images affichées
6.3. Tests mode preview
Commandes :
task dev:preview-middlewareAttendu :
- Middleware démarré sur
http://localhost:8790 - Validation du secret de preview
- Cookie
sanity-previewposé correctement
7. Checklist de validation
Avant de passer à l’étape CODE, vérifier :
- La spécification technique est complète
- La structure des fichiers est définie
- Les interfaces TypeScript sont définies
- L’intégration mode preview est spécifiée
- Les tests de validation sont définis
8. Implémentation réalisée
8.1. Composants PageBuilder créés
Répertoire : apps/web/src/components/pagebuilder/
Fichiers créés :
Hero.astro: Composant hero avec heading, subheading, CTA et imageFeatures.astro: Grille de features avec icônesTestimonials.astro: Témoignages clients avec avatarsCTA.astro: Call-to-action avec boutonRichText.astro: Rendu Portable Text basiqueImageGallery.astro: Galerie d’images responsive
8.2. Page d’accueil modifiée
Fichier : apps/web/src/pages/index.astro
Modifications :
- Ajout de
export const prerender = truepour SSG - Import des composants PageBuilder
- Query GROQ pour récupérer la page Sanity
- Rendu conditionnel des blocs via switch/case
- Utilisation de MainLayout avec props SEO
8.3. Configuration conforme à l’ADR
Mode SSG : export const prerender = true (conforme ADR-SSR-Pur.md)
Query GROQ : Utilisation de ...select() pour conditionnels
Mode preview : Intégration via getSanityClient() existant
9. Approbation
Validation requise : Confirmer que l’implémentation peut passer à l’étape TEST.
10. Historique des modifications
| Date | Version | Description | Auteur |
|---|---|---|---|
| 2026-09-16 | 1.0 | Création initiale | Devin |
| 2026-09-17 | 2.0 | Implémentation composants PageBuilder et page d’accueil | Devin |