Aller au contenu

PD-227 — Plan d'implémentation


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-227-specification.md) | | | 🛠️ **Plan d'implémentation** | *(ce document)* | | ✅ [Critères d'acceptation](PD-227-acceptability.md) | | | 📝 [Retour d'expérience](PD-227-rex.md) | | [← Retour à site-vitrine](../PD-225-epic.md) · [↑ Index User Story](index.md)

1. Découpage en composants

Structure i18n

src/
├── pages/
│   ├── index.astro           # Redirect → /fr/
│   ├── fr/
│   │   ├── index.astro       # Homepage FR
│   │   ├── product.astro
│   │   ├── pricing.astro
│   │   └── [...slug].astro   # Pages dynamiques FR
│   └── en/
│       ├── index.astro       # Homepage EN
│       ├── product.astro
│       ├── pricing.astro
│       └── [...slug].astro   # Pages dynamiques EN
├── i18n/
│   ├── index.ts              # Fonctions utilitaires i18n
│   ├── fr.json               # Traductions FR
│   └── en.json               # Traductions EN
└── components/
    └── LangSwitcher.astro    # Bascule FR↔EN

Composants clés

Composant Responsabilité
astro.config.mjs Configuration i18n native Astro
LangSwitcher.astro Lien vers l'autre langue
i18n/index.ts Helpers : t(), getLocale(), getAlternateUrl()
BaseLayout.astro Injection lang, hreflang, LangSwitcher

2. Flux techniques

Routage linguistique

Requête: /fr/product
Astro i18n routing
    ├── Locale détectée: fr
    ├── Page: src/pages/fr/product.astro
    └── Traductions: i18n/fr.json
HTML avec lang="fr" + hreflang alternates

Redirection racine

Requête: /
src/pages/index.astro
    └── return Astro.redirect('/fr/', 302)

Bascule de langue

Page: /fr/product
LangSwitcher.astro
    ├── Calcule URL alternative: /en/product
    └── Affiche lien "EN"

3. Mapping invariants → mécanismes

Invariant Mécanisme technique
INV-1 : 100% pages en FR et EN Structure miroir pages/fr/ et pages/en/
INV-2 : Préfixe langue dans URL prefixDefaultLocale: true dans config
INV-3 : Lien bascule FR↔EN LangSwitcher.astro dans header
INV-3 : Pas de page non traduite Script CI vérifie parité des fichiers

Configuration Astro i18n

// astro.config.mjs
export default defineConfig({
  site: 'https://probatiovault.com',
  i18n: {
    defaultLocale: 'fr',
    locales: ['fr', 'en'],
    routing: {
      prefixDefaultLocale: true  // INV-2: /fr/ explicite
    }
  }
});

Composant LangSwitcher

---
// src/components/LangSwitcher.astro
const { lang } = Astro.props;
const currentPath = Astro.url.pathname;
const alternateLang = lang === 'fr' ? 'en' : 'fr';
const alternateUrl = currentPath.replace(`/${lang}/`, `/${alternateLang}/`);
---

<a href={alternateUrl} hreflang={alternateLang}>
  {alternateLang.toUpperCase()}
</a>

Balises hreflang (SEO)

---
// Dans BaseLayout.astro
const lang = Astro.currentLocale;
const canonicalUrl = Astro.url.href;
const alternateUrl = canonicalUrl.replace(`/${lang}/`, `/${lang === 'fr' ? 'en' : 'fr'}/`);
---

<html lang={lang}>
<head>
  <link rel="canonical" href={canonicalUrl} />
  <link rel="alternate" hreflang="fr" href={canonicalUrl.replace(`/${lang}/`, '/fr/')} />
  <link rel="alternate" hreflang="en" href={canonicalUrl.replace(`/${lang}/`, '/en/')} />
  <link rel="alternate" hreflang="x-default" href={canonicalUrl.replace(`/${lang}/`, '/fr/')} />
</head>

4. Gestion des erreurs

Erreur Cause Mitigation
Page non traduite Fichier manquant en/fr CI compare les arborescences
Langue inconnue URL /de/product Middleware redirect → /fr/
Clé traduction manquante t('missing.key') Fallback FR + warning dev
hreflang incorrect URL mal formée Tests automatisés

Script de validation i18n

#!/bin/bash
# scripts/validate-i18n.sh

FR_PAGES=$(find src/pages/fr -name "*.astro" | wc -l)
EN_PAGES=$(find src/pages/en -name "*.astro" | wc -l)

if [ "$FR_PAGES" != "$EN_PAGES" ]; then
  echo "ERROR: Nombre de pages FR ($FR_PAGES) ≠ EN ($EN_PAGES)"
  exit 1
fi

# Vérifier que chaque page FR a son équivalent EN
for fr_page in src/pages/fr/*.astro; do
  en_page="${fr_page/fr/en}"
  if [ ! -f "$en_page" ]; then
    echo "ERROR: Page manquante: $en_page"
    exit 1
  fi
done

5. Impacts sécurité

Aspect Mesure
Open redirect Validation des URLs de redirection
XSS Échappement des paramètres de langue
SEO spam Canonical + hreflang corrects

6. Hypothèses techniques

Hypothèse Justification
Astro i18n natif suffisant Pas besoin de plugin externe
Traductions JSON statiques Pas de backend de traduction
Français = langue par défaut x-default pointe vers /fr/
Contenu existe en 2 langues Équipe fournit les traductions

7. Points de vigilance

Point Risque Action
Parité pages Page oubliée CI obligatoire
Liens internes Lien hardcodé /fr/ depuis /en/ Utiliser helpers i18n
Sitemap URLs dupliquées Sitemap avec hreflang
Canonical Mauvaise langue Tests automatisés
SEO Contenu dupliqué hreflang correctement implémenté

Fichiers à créer/modifier

Fichier Description
astro.config.mjs Ajouter config i18n
src/i18n/index.ts Helpers i18n
src/i18n/fr.json Traductions FR
src/i18n/en.json Traductions EN
src/components/LangSwitcher.astro Bascule langue
src/pages/index.astro Redirect → /fr/
scripts/validate-i18n.sh Validation CI