PD-227 — Retour d'expérience¶
Navigation User Story
| Document | | | ---------- | -- | | [Spécification](PD-227-specification.md) | | | [Plan d'implémentation](PD-227-plan.md) | | | [Critères d'acceptation](PD-227-acceptability.md) | | | **Retour d'expérience** | *(ce document)* | [Retour à site-vitrine](../PD-225-epic.md) · [Index User Story](index.md)1. Résumé exécutif¶
L'objectif de PD-227 était d'implémenter l'internationalisation FR/EN du site vitrine avec routage linguistique explicite (/fr/, /en/), bascule de langue et balises hreflang SEO. L'implémentation initiale a été refusée en acceptabilité en raison d'un écart BLOQUANT (liens FR↔EN cassés sur pages légales) et de trois écarts MAJEURS/MINEURS. Après correction de l'ensemble des écarts (unification des slugs, ajout du middleware de redirection, script de validation CI, redirection serveur), la User Story a été acceptée. Le délai de correction a été d'un jour.
2. Points fluides¶
- Configuration Astro i18n native : l'option
prefixDefaultLocale: truea permis d'imposer le préfixe/fr/sans code additionnel. - Structure miroir des pages : la duplication
pages/fr/etpages/en/a facilité la compréhension et le déploiement. - Fichiers de traduction JSON : format simple, facilement éditable par l'équipe.
- LangSwitcher : composant minimal (~10 lignes) fonctionnel immédiatement pour les pages à slugs identiques.
- Balises hreflang : implémentation dans
BaseLayout.astroconforme aux recommandations SEO. - Correction rapide post-acceptabilité : tous les écarts ont été corrigés en une seule itération.
3. Points difficiles¶
| Difficulté | Contexte |
|---|---|
| Divergence des slugs FR/EN | Les pages légales avaient des noms localisés (mentions-legales vs legal-notice), ce que le mécanisme de remplacement de préfixe ne gérait pas. Cela a causé l'écart E-01 BLOQUANT. |
| Absence de middleware de fallback | La configuration redirectToDefaultLocale: false était nécessaire pour éviter les redirections non désirées, mais aucun fallback n'était prévu pour les langues non supportées. |
| Redirection racine JS vs serveur | L'implémentation initiale utilisait JavaScript client pour la redirection / → /fr/, ce qui dépendait du JS et différait du plan. |
| Validation de parité non automatisée | Le plan prévoyait un script CI, mais il n'a pas été implémenté initialement, laissant la parité non vérifiée. |
4. Hypothèses révélées tardivement¶
| Hypothèse | Découverte |
|---|---|
| Slugs identiques FR/EN | Le plan supposait implicitement que toutes les pages auraient le même slug dans les deux langues. Les pages légales avec slugs localisés ont invalidé cette hypothèse. |
| Hébergement statique (GitLab Pages) | Le middleware et Astro.redirect() génèrent du HTML statique (<meta http-equiv="refresh">), pas des redirections HTTP 302 serveur. Cela a été découvert lors du build. |
| Accept-Language inaccessible en SSG | L'en-tête Accept-Language n'est pas disponible lors du build statique, limitant la détection de langue côté serveur. |
5. Invariants complexes¶
| Invariant | Complexité |
|---|---|
| INV-1 : 100% pages FR et EN | Nécessite une validation automatique continue. Le script validate-i18n.sh vérifie désormais : parité des pages, parité des clés JSON, préfixes href. Toute nouvelle page doit être dupliquée. |
| INV-3 : Bascule FR↔EN fonctionnelle | Le mécanisme de remplacement de préfixe impose des slugs identiques. Toute divergence future nécessitera un mapping explicite ou une unification des slugs. |
6. Dette technique¶
| Élément | Description | Impact |
|---|---|---|
| Slugs unifiés en anglais | Les pages légales FR utilisent désormais des slugs anglais (legal-notice, privacy-policy). Cela peut être contre-intuitif pour les utilisateurs FR voyant l'URL. | Faible (URLs techniques, non visibles par défaut) |
| Pas de helper i18n/index.ts | Le plan prévoyait des fonctions t(), getLocale(), getAlternateUrl(). Elles n'ont pas été implémentées ; les traductions sont chargées directement via import JSON. | Faible (fonctionne, moins élégant) |
| Middleware statique | Le middleware génère des redirections HTML, pas des 302 HTTP. Le comportement est correct mais diffère d'un vrai middleware serveur. | Faible (transparent pour l'utilisateur) |
7. Risques résiduels¶
| Risque | Probabilité | Impact | Mitigation |
|---|---|---|---|
| Ajout de page sans équivalent | Moyenne | Échec CI | Script validate-i18n.sh bloque le déploiement |
| Nouveau slug localisé | Faible | Lien cassé | Convention établie : slugs identiques |
| Nouvelle locale (ex: DE) | Faible | Travail significatif | Script paramétrable via LOCALES et REFERENCE_LOCALE |
| Clé JSON manquante | Moyenne | Texte non traduit | Vérification CI des clés JSON |
8. Améliorations processus¶
| Suggestion | Bénéfice attendu |
|---|---|
| Exiger le script de validation dès la première implémentation | Aurait détecté E-01 et E-03 avant la revue d'acceptabilité |
| Documenter la convention de nommage des slugs | Éviter les divergences FR/EN futures |
| Ajouter un test E2E de bascule de langue | Valider le flux utilisateur FR↔EN automatiquement |
| Revoir le plan d'implémentation si hébergement statique | Clarifier les contraintes SSG dès le départ |
9. Enseignements clés¶
-
Les slugs localisés cassent le mécanisme de bascule par remplacement de préfixe. Convention à adopter : slugs identiques ou mapping explicite.
-
La validation automatique de parité i18n doit être implémentée dès le premier déploiement, pas après la revue d'acceptabilité.
-
L'hébergement statique impose des contraintes sur les redirections : pas d'accès aux headers HTTP, pas de 302 serveur natif. À anticiper dans le plan.
-
Le cas d'erreur "langue non supportée" est souvent oublié lors de l'implémentation initiale. Le middleware doit être prévu explicitement.
-
La revue d'acceptabilité a fonctionné : les 4 écarts ont été identifiés et corrigés rapidement. Le processus a prouvé sa valeur.
10. Addendum — Résolution des écarts¶
[2025-12-21] — Mise à jour suite à acceptation finale¶
Les écarts E-01 à E-04 identifiés lors de la revue initiale ont été corrigés :
| Écart | Résolution |
|---|---|
| E-01 (Liens FR↔EN cassés) | Slugs FR alignés sur EN (legal-notice, privacy-policy), liens navigation mis à jour |
| E-02 (Langue non supportée → 404) | Middleware src/middleware.ts redirige /de/*, /es/*, etc. vers /fr/* (302) |
| E-03 (Validation parité absente) | Script scripts/validate-i18n.sh + job CI validate-i18n |
| E-04 (Redirection racine JS) | src/pages/index.astro utilise Astro.redirect('/fr/', 302) côté serveur |
Verdict final : ✅ ACCEPTÉ (2025-12-19)
Document généré le 2025-12-19, mis à jour le 2025-12-21