Dossier d'Architecture Technique (DAT)
Couche 02 : Présentation (Rendu et Front-End)
Section titled âCouche 02 : PrĂ©sentation (Rendu et Front-End)âProjet : RĂ©architecture du Site Web (Vitrine, Blog, Portfolio, Documentation)
Statut : Version 1.4 (Fine-tuning L2 â Complet)
Date : 2 Septembre 2026
Ăquipe : Architecture IT
1. Introduction & Objectifs
Section titled â1. Introduction & ObjectifsâCe document spĂ©cifie les standards, la structure et les mĂ©canismes de fonctionnement de la Couche 02 (PrĂ©sentation). Cette couche est responsable de la rĂ©cupĂ©ration des donnĂ©es issues de la Couche 01 (Sanity et fichiers locaux), de leur transformation, de leur mise en page et de leur distribution optimisĂ©e aux utilisateurs finaux via un rendu hybride.
2. Architecture de Rendu & Configuration du Framework
Section titled â2. Architecture de Rendu & Configuration du FrameworkâLe projet utilise Astro configurĂ© avec lâadaptateur Cloudflare (@astrojs/cloudflare) pour activer les fonctionnalitĂ©s dynamiques. Ce choix garantit un alignement strict avec la Couche 03 (Pages Functions, Workers et Middleware Cloudflare).
2.1. Fichier de Configuration Core (astro.config.mjs)
Section titled â2.1. Fichier de Configuration Core (astro.config.mjs)âLe framework est paramĂ©trĂ© en mode hybrid. Ce choix stratĂ©gique impose le comportement suivant :
- Par défaut, toutes les pages sont compilées en HTML Statique (SSG) au moment du build.
- Les pages nécessitant une logique serveur à la volée activent explicitement le Rendu Serveur (SSR).
import { defineConfig } from 'astro/config';import tailwind from '@astrojs/tailwind';import sanity from '@sanity/astro';import starlight from '@astrojs/starlight';import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ output: 'hybrid', adapter: cloudflare({ // Mode recommandĂ© pour Pages + Functions platformProxy: { enabled: true, // Facilite le dĂ©veloppement local avec Wrangler }, }), integrations: [ tailwind(), sanity({ projectId: 'votre_project_id', dataset: 'production', useCdn: true, // CDN Sanity pour le build SSG // Le client sera reconfigurĂ© dynamiquement en mode preview (voir §5.3) }), starlight({ title: 'Documentation Technique', sidebar: [ { label: 'Guide de DĂ©marrage', autogenerate: { directory: 'guide' } }, { label: 'RĂ©fĂ©rences API', autogenerate: { directory: 'api' } }, ], }), ],});Alignement avec la Couche 03 : Lâadaptateur
@astrojs/cloudflareest obligatoire. Il compile les routesprerender = falseen Cloudflare Pages Functions et sâintĂšgre nativement avec le Middleware Worker et les Workers mĂ©tiers dĂ©finis en L3.
3. Structure de lâEspace de Travail (Workspace)
Section titled â3. Structure de lâEspace de Travail (Workspace)âLâarborescence du projet est rationalisĂ©e pour sĂ©parer les structures de pages globales de la logique applicative de Starlight :
âââ src/â âââ components/ # Composants d'interface rĂ©utilisables (Boutons, Cartes, etc.)â â âââ ui/ # Composants atomiques (HTML purs)â â âââ interactive/ # Ălots dynamiques (React/Vue/Svelte si nĂ©cessaire)â âââ content/ # DĂ©finition des schĂ©mas de donnĂ©es locauxâ â âââ config.ts # Validation Zod des schĂ©mas de contenuâ â âââ docs/ # Fichiers Markdown/MDX consommĂ©s par Starlightâ âââ layouts/ # Gabarits de page globaux (Header, Footer, Meta SEO)â â âââ MainLayout.astroâ â âââ BlogLayout.astroâ âââ pages/ # SystĂšme de routage du site principalâ âââ index.astro # Page d'accueil (Vitrine) - [SSG]â âââ blog/â â âââ index.astro # Liste des articles - [SSG]â â âââ [slug].astro # Article unitaire dynamique au build - [SSG]â âââ portfolio/â â âââ index.astro # Galerie de projets - [SSG]â âââ contact.astro # Exemple de page avec traitement de formulaire - [SSR]âââ astro.config.mjsâââ package.json4. StratĂ©gie dâHydratation & Gestion du JavaScript (Ălots)
Section titled â4. StratĂ©gie dâHydratation & Gestion du JavaScript (Ălots)âAfin de prĂ©server des performances maximales (Score Lighthouse / Core Web Vitals proche de 100), la couche de prĂ©sentation applique strictement la politique de lâArchitecture en Ălots :
- Rendu HTML Statique (Par dĂ©faut) : Les en-tĂȘtes, textes de la vitrine, articles de blog et pages de documentation nâembarquent aucun framework JS.
- Hydratation ciblĂ©e (Ălots interactifs) : Lorsquâun composant requiert du JavaScript cĂŽtĂ© client, lâhydratation est explicitement dĂ©clarĂ©e et diffĂ©rĂ©e selon le besoin :
client:load: Pour les Ă©lĂ©ments immĂ©diatement critiques (ex: un menu de navigation mobile interactif).client:visible: Pour les Ă©lĂ©ments plus bas dans la page (ex: un carrousel de tĂ©moignages sur la vitrine ou un graphique dans le portfolio). Le JS nâest chargĂ© que lorsque lâĂ©lĂ©ment entre dans le viewport.
5. Intégration et Consommation de la Couche 01
Section titled â5. IntĂ©gration et Consommation de la Couche 01â5.1. RĂ©cupĂ©ration des donnĂ©es Sanity (Vitrine, Blog, Portfolio)
Section titled â5.1. RĂ©cupĂ©ration des donnĂ©es Sanity (Vitrine, Blog, Portfolio)âLes requĂȘtes vers le Content Lake de Sanity sâexĂ©cutent cĂŽtĂ© serveur (au moment du build pour le SSG ou Ă la requĂȘte pour le SSR) Ă lâaide de lâoutil de requĂȘtage GROQ.
---// Exemple d'implémentation dans src/pages/blog/[slug].astroimport MainLayout from '../../layouts/MainLayout.astro';import { getSanityClient } from '../../lib/sanity';
export async function getStaticPaths() { // En phase de build SSG, on force toujours la perspective "published" const client = getSanityClient({ cookies: { get: () => undefined }, request: { headers: { get: () => null } } } as any);
const posts = await client.fetch(`*[_type == "post" && status == "published"]{ "slug": slug.current }`); return posts.map((post) => ({ params: { slug: post.slug } }));}
const sanityClient = getSanityClient(Astro); // Détecte automatiquement le mode Preview si présentconst { slug } = Astro.params;const post = await sanityClient.fetch( `*[_type == "post" && slug.current == $slug][0]{ title, publishedAt, body }`, { slug });---<MainLayout title={post.title}> <article> <h1>{post.title}</h1> <p>Publié le {new Date(post.publishedAt).toLocaleDateString()}</p> <!-- Rendu du texte riche via un composant portable text --> </article></MainLayout>5.2. Isolation de la Documentation (Starlight)
Section titled â5.2. Isolation de la Documentation (Starlight)âLâintĂ©gration de Starlight intercepte automatiquement la route /docs. Elle valide de maniĂšre autonome les fichiers Markdown situĂ©s dans src/content/docs/ en se basant sur ses propres schĂ©mas de mĂ©tadonnĂ©es (frontmatter).
5.3. Gestion du mode Preview (Draft Mode)
Section titled â5.3. Gestion du mode Preview (Draft Mode)âLa prĂ©visualisation des contenus Sanity en brouillon est entiĂšrement pilotĂ©e par le Middleware Cloudflare (voir DAT L1 §4.7 et DAT L3 §3.1).
Astro nâa quâun rĂŽle de dĂ©tection et de reconfiguration du client Sanity.
5.3.1. Détection du mode Preview
Section titled â5.3.1. DĂ©tection du mode PreviewâAstro dĂ©tecte la prĂ©sence du cookie sanity-preview=true (posĂ© par le Middleware) ou du header x-sanity-preview: true.
// src/lib/sanity.ts (ou utilitaire équivalent)import { createClient } from '@sanity/client';import type { AstroGlobal } from 'astro';
export function getSanityClient(astro: AstroGlobal) { const isPreview = astro.cookies.get('sanity-preview')?.value === 'true' || astro.request.headers.get('x-sanity-preview') === 'true';
return createClient({ projectId: import.meta.env.PUBLIC_SANITY_PROJECT_ID, dataset: import.meta.env.PUBLIC_SANITY_DATASET, apiVersion: '2025-01-01', useCdn: !isPreview, // Désactive le CDN en preview perspective: isPreview ? 'previewDrafts' : 'published', token: isPreview ? import.meta.env.SANITY_API_READ_TOKEN // Token avec droit de lecture des drafts : undefined, });}5.3.2. Route de sortie du mode Preview
Section titled â5.3.2. Route de sortie du mode PreviewâUne route dĂ©diĂ©e permet de sortir du mode preview (suppression du cookie) :
---export const prerender = false;
Astro.cookies.delete('sanity-preview', { path: '/' });return Astro.redirect('/');---5.3.3. RĂšgles importantes
Section titled â5.3.3. RĂšgles importantesâ- Aucune page en mode Preview nâest jamais gĂ©nĂ©rĂ©e en SSG.
- Les routes qui affichent du contenu Sanity doivent utiliser le client conditionnel ci-dessus.
- Le token
SANITY_API_READ_TOKEN(lecture drafts) est uniquement disponible en runtime (Pages Functions) et jamais exposĂ© cĂŽtĂ© client. - La documentation Starlight nâest pas concernĂ©e par ce mĂ©canisme.
5.4. Consommation et optimisation des médias (Cloudflare R2 + Stream)
Section titled â5.4. Consommation et optimisation des mĂ©dias (Cloudflare R2 + Stream)âTous les mĂ©dias sont stockĂ©s exclusivement sur Cloudflare R2 (images, documents) et Cloudflare Stream (vidĂ©os). Sanity ne conserve que les mĂ©tadonnĂ©es + URLs (voir DAT L1 §4.8).
5.4.1. Images
Section titled â5.4.1. Imagesâ- Source de vĂ©ritĂ© : URL publique R2 (ou URL signĂ©e si nĂ©cessaire).
- Optimisation recommandée :
- Utilisation de Cloudflare Polish (lossy/lossless) + Mirage activés sur la zone.
- Pour un contrÎle plus fin : Cloudflare Images (redimensionnement à la volée via
/cdn-cgi/image/). - CÎté Astro : composant
<Image>personnalisé ouastro:assetsavec un loader custom pointant vers R2 si besoin de transformation au build.
- Bonnes pratiques obligatoires :
- Toujours fournir
width,heightetalt. - Utiliser
loading="lazy"+decoding="async"sauf pour les images LCP (Hero). - Générer des
srcset/sizespour le responsive. - Formats modernes : Cloudflare sert automatiquement WebP/AVIF selon le support navigateur.
- Toujours fournir
5.4.2. Vidéos
Section titled â5.4.2. VidĂ©osâ- Les vidĂ©os sont hĂ©bergĂ©es sur Cloudflare Stream.
- Astro nâembarque que le player Stream (iframe ou SDK officiel) Ă partir de lâUID stockĂ© dans Sanity.
- Aucun fichier vidĂ©o nâest jamais servi directement depuis R2 en production.
5.4.3. Documents (PDF, etc.)
Section titled â5.4.3. Documents (PDF, etc.)â- Lien direct vers lâURL R2.
- PossibilitĂ© dâajouter une prĂ©visualisation (miniature gĂ©nĂ©rĂ©e par un Worker si besoin).
5.5. Typage fort (Sanity â Astro)
Section titled â5.5. Typage fort (Sanity â Astro)âAfin dâĂ©liminer le drift entre les schĂ©mas Sanity et le code Astro, un mĂ©canisme de gĂ©nĂ©ration de types TypeScript est mis en place.
5.5.1. Outil retenu
Section titled â5.5.1. Outil retenuâ- sanity-typegen (officiel Sanity) ou Ă©quivalent (
@sanity/codegen). - Les types sont générés à partir des schémas définis dans le projet
sanity-studio.
5.5.2. Workflow
Section titled â5.5.2. Workflowâ- Les schĂ©mas Sanity sont la source de vĂ©ritĂ©.
- Une commande (script npm + GitHub Action) génÚre les types TypeScript à chaque modification des schémas.
- Les types générés sont versionnés dans le dépÎt Astro (
src/types/sanity.d.tsou Ă©quivalent). - Toutes les requĂȘtes GROQ et les composants qui consomment des donnĂ©es Sanity utilisent ces types.
5.5.3. RĂšgles
Section titled â5.5.3. RĂšglesâ- Aucune donnĂ©e Sanity nâest manipulĂ©e avec le type
any. - Les queries GROQ critiques sont typées (retour attendu).
- Le pipeline CI échoue si les types générés ne sont pas à jour par rapport aux schémas.
6. Routage Dynamique (SSR) : Gestion des Exceptions
Section titled â6. Routage Dynamique (SSR) : Gestion des ExceptionsâPar dĂ©faut, lâapplication gĂ©nĂšre du contenu statique. Pour les routes nĂ©cessitant une logique serveur temps rĂ©el (ex: un formulaire de contact, un moteur de recherche interne cross-sources, ou un espace privĂ©), la directive de prĂ©-rendu est dĂ©sactivĂ©e.
6.1. Politique de cache des routes SSR
Section titled â6.1. Politique de cache des routes SSRâLes routes dĂ©clarĂ©es avec export const prerender = false sâexĂ©cutent sur Cloudflare Pages Functions.
La politique de cache est gérée selon le principe de responsabilité suivant (aligné avec la L3) :
-
Niveau Middleware Cloudflare (Worker indépendant)
- Pose les headers de sécurité.
- Applique une politique de cache par défaut.
- Force
Cache-Control: no-storedĂšs que le mode Preview est actif (sanity-preview=true).
-
Niveau page Astro (spécifique)
Chaque page SSR peut affiner sa propre politique viaAstro.response.headers:
| Type de page SSR | Cache-Control (navigateur) | CDN-Cache-Control (Cloudflare) |
|---|---|---|
| Pages semi-dynamiques | public, max-age=60 |
max-age=300, stale-while-revalidate=86400 |
| Pages hautement dynamiques / privées | private, no-store |
no-store |
| Pages de formulaire (GET) | public, max-age=300 |
max-age=600, stale-while-revalidate=3600 |
| RĂ©ponses dâactions (POST) | no-store |
no-store |
Exemple dans une page :
Astro.response.headers.set('Cache-Control', 'public, max-age=60');Astro.response.headers.set('CDN-Cache-Control', 'max-age=300, stale-while-revalidate=86400');6.2. Gestion des formulaires (exemple : Contact)
Section titled â6.2. Gestion des formulaires (exemple : Contact)âLes formulaires suivent un contrat strict entre la Couche 02 et la Couche 03 :
- Validation cÎté client (UX immédiate) avec Zod ou équivalent.
- Soumission vers le Worker
form-handler(L3) viafetch(jamais de logique métier dans Astro). - Protection anti-spam : Cloudflare Turnstile (recommandé) ou équivalent.
- Feedback utilisateur : états de chargement, succÚs et erreur clairement exposés.
- AccessibilitĂ© : labels explicites, messages dâerreur liĂ©s via
aria-describedby, gestion du focus.
Exemple de flux recommandé
Section titled âExemple de flux recommandĂ©â---export const prerender = false;
import { z } from 'zod';
const contactSchema = z.object({ email: z.string().email(), message: z.string().min(10).max(2000),});
let formState: 'idle' | 'loading' | 'success' | 'error' = 'idle';let errorMessage = '';
if (Astro.request.method === 'POST') { formState = 'loading'; try { const formData = await Astro.request.formData(); const raw = Object.fromEntries(formData); const data = contactSchema.parse(raw);
// Appel au Worker L3 const res = await fetch('https://api.votredomaine.com/form-handler', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), });
if (!res.ok) throw new Error('Erreur serveur'); formState = 'success'; } catch (err) { formState = 'error'; errorMessage = err instanceof z.ZodError ? 'Veuillez vĂ©rifier les champs.' : 'Une erreur est survenue. Merci de rĂ©essayer.'; }}---Toute logique de validation mĂ©tier lourde, dâenvoi dâemail ou dâintĂ©gration CRM reste dans le Worker
form-handler(L3). Astro ne fait que lâorchestration front + validation de surface.
7. Pipeline de DĂ©ploiement et dâInvalidation
Section titled â7. Pipeline de DĂ©ploiement et dâInvalidationâ- Build initial : Le pipeline CI/CD compile le projet. Astro gĂ©nĂšre lâensemble des fichiers HTML pour les routes statiques et prĂ©pare les fonctions Serverless pour les routes dynamiques (
prerender = false). - DĂ©clenchement externe : Lorsquâun contributeur publie un nouvel article sur Sanity, le webhook configurĂ© sur le CMS Ă©met une requĂȘte HTTP POST vers lâhĂ©bergeur pour relancer ce build. Le site statique est ainsi mis Ă jour sans interruption de service.
8. Stratégie de Recherche Unifiée (Pagefind)
Section titled â8. StratĂ©gie de Recherche UnifiĂ©e (Pagefind)âLa recherche doit couvrir de maniĂšre unifiĂ©e lâensemble du contenu du site : Vitrine, Blog, Portfolio (sources Sanity) et Documentation (Starlight).
8.1. Solution retenue
Section titled â8.1. Solution retenueâPagefind est adoptĂ© comme moteur de recherche unique pour les raisons suivantes :
- Gratuit et open-source
- Indexation statique au build (parfaitement aligné avec le mode SSG dominant)
- Déjà intégré nativement dans Starlight
- Excellent support Astro (
astro-pagefindou CLI) - Performance Ă©levĂ©e grĂące Ă lâindex chunkĂ© (faible bande passante)
- Zéro dépendance à un service externe
8.2. Fonctionnement
Section titled â8.2. Fonctionnementâ- Astro gĂ©nĂšre lâensemble des pages HTML (SSG).
- Pagefind indexe le dossier
dist/immédiatement aprÚs le build. - Un seul index couvre tout le site (contenu Sanity + documentation Starlight).
- Lâindex est rĂ©gĂ©nĂ©rĂ© automatiquement Ă chaque build (y compris ceux dĂ©clenchĂ©s par les webhooks Sanity).
8.3. RĂšgles dâindexation
Section titled â8.3. RĂšgles dâindexationâ- Inclus : toutes les pages publiĂ©es de la Vitrine, du Blog, du Portfolio et de la Documentation.
- Exclus :
- Pages en mode Preview / Draft
- Routes techniques (
/api/*, pages dâadministration, etc.) - ĂlĂ©ments de navigation et footer (via
exclude_selectors)
8.4. Expérience utilisateur & distinction visuelle des résultats
Section titled â8.4. ExpĂ©rience utilisateur & distinction visuelle des rĂ©sultatsâLa barre de recherche globale (header du site) utilise Pagefind.
Les rĂ©sultats sont visuellement distinguĂ©s par type de contenu afin dâamĂ©liorer la lisibilitĂ© :
| Type de contenu | Badge / Indicateur visuel | Exemple |
|---|---|---|
| Documentation | Badge « Doc » | Guide dâinstallation |
| Article de Blog | Badge « Blog » | Titre de lâarticle |
| Projet Portfolio | Badge « Portfolio » | Nom du projet |
| Page Vitrine | Badge « Page » | Titre de la page |
Cette distinction est rĂ©alisĂ©e via les mĂ©tadonnĂ©es Pagefind (filtres ou data-pagefind-meta) et un rendu custom de lâinterface de rĂ©sultats.
8.5. Cohérence avec Starlight
Section titled â8.5. CohĂ©rence avec StarlightâStarlight continue dâutiliser Pagefind nativement pour sa propre barre de recherche.
Lâobjectif est de partager le mĂȘme index (ou des index trĂšs proches) afin dâoffrir une expĂ©rience de recherche homogĂšne sur lâensemble du portail.
9. Gestion des erreurs et résilience
Section titled â9. Gestion des erreurs et rĂ©silienceâ9.1. Principes
Section titled â9.1. Principesâ- Aucune page ne doit planter complĂštement si Sanity est momentanĂ©ment indisponible.
- Les erreurs sont loggées et surveillées (via Cloudflare Logpush / Workers Analytics).
- Lâutilisateur final voit toujours une expĂ©rience dĂ©gradĂ©e Ă©lĂ©gante plutĂŽt quâune erreur 500 brute.
9.2. Stratégies par contexte
Section titled â9.2. StratĂ©gies par contexteâ| Contexte | Comportement attendu |
|---|---|
| Build SSG (Sanity down) | Le build Ă©choue â alerte immĂ©diate (CI + notification). Pas de dĂ©ploiement partiel. |
| Route SSR (Sanity down) | Affichage dâun fallback (contenu en cache si disponible, ou message « Contenu temporairement indisponible ») + status 503 ou 200 avec banniĂšre. |
| Erreur GROQ partielle | Les sections non critiques affichent un état vide ou un skeleton. Les sections critiques (Hero, etc.) utilisent un fallback statique. |
| Mode Preview | En cas dâerreur dâauthentification du token draft â redirection vers la version publiĂ©e + message. |
9.3. Mise en Ćuvre technique
Section titled â9.3. Mise en Ćuvre techniqueâ- Utilisation de
try/catchautour de toutes les requĂȘtes Sanity critiques. - Composants dâerreur rĂ©utilisables (
ErrorBoundary.astroou Ă©quivalent cĂŽtĂ© Islands). - Pages dâerreur Astro personnalisĂ©es (
src/pages/500.astro,404.astro). - En production, les erreurs 5xx des Pages Functions sont remontées via Cloudflare et déclenchent une alerte (seuil à définir, ex. > 2 % sur 5 min).
9.4. Observabilité
Section titled â9.4. ObservabilitĂ©â- Logs structurĂ©s des Ă©checs de fetch Sanity (avec query GROQ anonymisĂ©e).
- Corrélation possible avec les logs du Worker
cms-webhook-receiver(L3).
10. Stratégie SEO
Section titled â10. StratĂ©gie SEOâ10.1. Principes
Section titled â10.1. PrincipesâLe SEO est traitĂ© comme une responsabilitĂ© de premier niveau de la Couche 02.
Les objets seo définis dans les schémas Sanity (metaTitle, metaDescription, ogImage) constituent la source de vérité éditoriale. Astro se charge de les matérialiser correctement dans le HTML.
10.2. ĂlĂ©ments techniques obligatoires
Section titled â10.2. ĂlĂ©ments techniques obligatoiresâ| ĂlĂ©ment | ImplĂ©mentation |
|---|---|
| Balises meta | title, description, og:*, twitter:* gĂ©nĂ©rĂ©s dynamiquement Ă partir de lâobjet seo Sanity (avec fallback intelligent sur le titre et lâextrait). |
| Canonical | Balise <link rel="canonical"> systématique sur toutes les pages. |
| Sitemap | Génération automatique via @astrojs/sitemap (ou équivalent). Inclut uniquement les contenus status == "published". Exclut les routes techniques et le mode Preview. |
| robots.txt | Fichier statique + rĂšgles dynamiques si besoin (blocage des environnements de preview / staging). |
| Structured Data (JSON-LD) |
Organization(global)WebSite+SearchAction(pour la recherche)Article/BlogPosting(articles)CreativeWorkouProject(portfolio)- Injecté via un composant réutilisable
<JsonLd />. | | Open Graph & Twitter Cards | Image OG prioritaire =seo.ogImageâ sinon image principale du contenu â sinon image par dĂ©faut du site. |
10.3. RĂšgles de fallback
Section titled â10.3. RĂšgles de fallbackâseo.metaTitleâ sinontitledu documentseo.metaDescriptionâ sinonexcerpt/descriptionâ sinon truncation du bodyseo.ogImageâ sinonmainImage/ premiĂšre image de galerie â sinon image de fallback globale
10.4. Performance SEO
Section titled â10.4. Performance SEOâ- Toutes les pages de contenu principal restent en SSG (Core Web Vitals optimaux).
- Les images respectent les bonnes pratiques définies en §5.4 (dimensions, alt, formats modernes).
- Pas de JavaScript bloquant sur le chemin critique de rendu.
11. Accessibilité (a11y)
Section titled â11. AccessibilitĂ© (a11y)â11.1. Objectif
Section titled â11.1. ObjectifâConformitĂ© WCAG 2.1 niveau AA minimum sur lâensemble du site (Vitrine, Blog, Portfolio, Documentation).
11.2. RĂšgles de conception
Section titled â11.2. RĂšgles de conceptionâ- Tous les composants
ui/etinteractive/doivent ĂȘtre accessibles par dĂ©faut (focus visible, contraste, labels, etc.). - Navigation clavier complĂšte (Tab, Enter, Escape, flĂšches selon les patterns).
- Gestion correcte des zones
aria-*et des rÎles ARIA uniquement quand nécessaire (éviter la sur-utilisation). - Textes alternatifs obligatoires sur toutes les images informatives (récupérés depuis Sanity ou fallback).
- Respect des ratios de contraste (texte / fond) â Ă valider avec les design tokens.
11.3. Outils et contrĂŽles
Section titled â11.3. Outils et contrĂŽlesâ| Moment | Outil / Pratique |
|---|---|
| Développement | eslint-plugin-jsx-a11y + tests manuels clavier |
| CI | Lighthouse CI (score a11y â„ 95) + axe-core |
| Revue de design | Checklist WCAG 2.1 AA |
| Documentation | Starlight hérite déjà de bonnes bases a11y ; vérifier la cohérence avec le reste du site |
11.4. Points dâattention spĂ©cifiques
Section titled â11.4. Points dâattention spĂ©cifiquesâ- Modales / overlays (focus trap + restauration du focus)
- Carrousels et composants Islands interactifs
- Formulaires (labels, messages dâerreur liĂ©s,
aria-invalid,aria-describedby) - Mode sombre (si implémenté) : contraste maintenu
12. Design System et cohérence visuelle
Section titled â12. Design System et cohĂ©rence visuelleâ12.1. Objectifs
Section titled â12.1. Objectifsâ- Garantir une expĂ©rience visuelle homogĂšne entre la Vitrine, le Blog, le Portfolio et la Documentation (Starlight).
- Faciliter la maintenance et lâĂ©volution du design sans dette technique.
12.2. Structure recommandée
Section titled â12.2. Structure recommandĂ©eâsrc/âââ styles/â âââ tokens.css # Design tokens (couleurs, spacing, typographie, radiiâŠ)â âââ global.cssâ âââ starlight-overrides.css # Surcharges ciblĂ©es du thĂšme Starlightâââ components/â âââ ui/ # Composants atomiques purs (Button, Badge, CardâŠ)â âââ interactive/ # Ălots (carrousels, filtres, etc.)12.3. RĂšgles
Section titled â12.3. RĂšglesâ- Les design tokens sont la source de vĂ©ritĂ© (CSS variables ou Ă©quivalent).
- Starlight utilise le mĂȘme systĂšme de tokens via des overrides ciblĂ©s (pas de duplication de styles).
- Les composants
ui/sont indépendants de tout framework JS (HTML + CSS purs autant que possible). - Documentation des composants (Storybook ou équivalent léger) recommandée pour les composants complexes.
- Support du mode sombre (si prévu) via les tokens +
prefers-color-schemeou classe manuelle.
13. Analytics et observabilité front
Section titled â13. Analytics et observabilitĂ© frontâ13.1. Principes
Section titled â13.1. Principesâ- Privacy-first (pas de cookies non essentiels sans consentement).
- Mesure des Core Web Vitals en conditions réelles (RUM).
- Alignement avec lâĂ©cosystĂšme Cloudflare dĂ©jĂ retenu.
13.2. Stack recommandée
Section titled â13.2. Stack recommandĂ©eâ| Besoin | Solution recommandĂ©e | Commentaire |
|---|---|---|
| Analytics de base | Cloudflare Web Analytics | Gratuit, sans cookie, natif |
| Analytics produit / événements | Plausible ou Umami (self-hosté ou cloud) | Privacy-friendly, léger |
| Core Web Vitals (RUM) | Cloudflare Web Analytics + évent. SpeedCurve / Calibre | Suivi LCP, INP, CLS |
| Error tracking front | Cloudflare Workers Analytics + logs | Ou Sentry léger si besoin avancé |
13.3. RĂšgles dâimplĂ©mentation
Section titled â13.3. RĂšgles dâimplĂ©mentationâ- Aucun script analytics nâest chargĂ© en mode Preview.
- Les scripts tiers sont chargés en
defer/asyncet idĂ©alement via un Ălot ou un composant dĂ©diĂ©. - Consentement (si requis par la rĂ©glementation) gĂ©rĂ© de maniĂšre centralisĂ©e.
14. Stratégie de tests
Section titled â14. StratĂ©gie de testsâ14.1. Pyramide de tests
Section titled â14.1. Pyramide de testsâ| Niveau | PĂ©rimĂštre | Outils recommandĂ©s | FrĂ©quence |
|---|---|---|---|
| Unitaires | Composants ui/ et utilitaires |
Vitest + Testing Library | Ă chaque commit |
| IntĂ©gration | Pages + requĂȘtes Sanity (mockĂ©es) | Vitest / Playwright component | PR |
| End-to-End | Parcours critiques (navigation, formulaire, recherche, preview) | Playwright | PR + nightly |
| Visuels | Régression visuelle des composants clés | Playwright + screenshots ou Chromatic | PR |
| Accessibilité | Score a11y + rÚgles critiques | axe-core + Lighthouse CI | PR |
| Performance | Lighthouse CI (LCP, INP, CLSâŠ) | Lighthouse CI | PR |
14.2. RĂšgles
Section titled â14.2. RĂšglesâ- Les tests E2E couvrent au minimum : page dâaccueil, article de blog, page portfolio, documentation, formulaire de contact, bascule Preview.
- Les donnĂ©es Sanity sont mockĂ©es en environnement de test (pas dâappel rĂ©el au Content Lake).
- Le pipeline CI bloque le merge si les tests critiques ou le score a11y/performance descendent sous les seuils définis.
15. Internationalisation (i18n)
Section titled â15. Internationalisation (i18n)âCette section est conditionnelle. Elle sâapplique uniquement si le multi-langue est prĂ©vu dans la roadmap produit.
15.1. Principes
Section titled â15.1. Principesâ- Starlight gĂšre nativement lâi18n pour la documentation.
- Le reste du site (Vitrine, Blog, Portfolio) doit suivre la mĂȘme stratĂ©gie de routing et de content collections.
- Pagefind doit pouvoir indexer et filtrer par langue.
15.2. Approche recommandée
Section titled â15.2. Approche recommandĂ©eâ| ĂlĂ©ment | StratĂ©gie |
|---|---|
| Routing | Préfixe de locale (/fr/..., /en/...) ou domaine par langue |
| Contenu Sanity | Documents localisés ou champs localisés selon le volume |
| Documentation | Mécanisme natif Starlight |
| UI (labels, boutonsâŠ) | Fichiers de traduction (JSON/YAML) + helper Astro |
| SEO | hreflang, canonical par locale, sitemaps séparés ou indexés |
| Recherche (Pagefind) | Index par langue ou filtres de locale |
15.3. Décision à trancher
Section titled â15.3. DĂ©cision Ă trancherâAvant dâimplĂ©menter, valider avec le produit :
- Quelles langues sont prioritaires ?
- Le contenu marketing sera-t-il traduit Ă 100 % ou partiellement ?
- Faut-il un sélecteur de langue visible dÚs le lancement ?