Mirroir EN (/en/...)

Ce dossier contient le mirroir anglais des pages FR de src/pages/. Il existe 12 pages EN, une par page FR « mirrorable » (cf. liste des exclusions ci-dessous). Ce README documente le patron de réplication à suivre pour ajouter une nouvelle page EN ou faire évoluer une page existante.

Principe général

Chaque page EN est un mirroir quasi-littéral de son équivalent FR : même structure de sections, mêmes composants, mêmes requêtes Directus — seule la locale change ('fr''en'), ainsi que les chemins et libellés qui en dépendent. Les clés i18n existent déjà dans fr.json/en.json ; aucune nouvelle clé n’est nécessaire pour les mirroirs EN.

Routing Astro i18n

Configuré dans astro.config.mjs :

i18n: {
  locales: ['fr', 'en'],
  defaultLocale: 'fr',
  routing: { prefixDefaultLocale: false, redirectToDefaultLocale: false },
}

Conséquence : les pages FR vivent à la racine (/), les pages EN vivent sous src/pages/en/ et sont servies sous /en/....

currentPath : la règle à ne jamais oublier

Nav.astro calcule isActive(href) via localizeHref(href, locale) (qui ajoute le préfixe /en pour la locale anglaise) et compare au currentPath reçu par <BaseLayout>.

Conséquence : pour toute page EN, currentPath DOIT inclure le préfixe /en.

Deux cas :

path passé à buildSeoMeta

Le paramètre path de buildSeoMeta est toujours sans préfixe de locale. buildSeoMeta calcule en interne canonical = ${SITE_URL}${localePrefix}${path}localePrefix = locale === 'fr' ? '' : '/en'.

Pour les mirroirs EN, path est donc l’équivalent EN du chemin, sans /en : /about, /services, /case-studies/${slug}, /resources/${slug}, /contact, /contact/thank-you, /search, etc.

Pages dynamiques : getStaticPaths + alternates

Pour les pages de détail ([slug].astro), getStaticPaths() est construit à partir des slugs EN natifs :

export async function getStaticPaths() {
  const items = await getServices('en'); // ou getCaseStudies / getBlogPosts
  return items.map((item) => ({ params: { slug: item.slug }, props: { key: item.key /* ou id */ } }));
}

Pour résoudre l’équivalent FR (lien alternate / hreflang), on utilise les helpers get*SlugsByLocale() (getServiceSlugsByLocale, getCaseStudySlugsByLocale, getBlogPostSlugsByLocale), qui renvoient Record<string, Partial<Record<Locale, string>>> indexé par un identifiant stable (key pour les services, id pour les cas clients et articles) :

const slugsByKey = await getServiceSlugsByLocale();
const translatedSlugs = slugsByKey[item.key] ?? {};

alternateUrl() vs. alternateHref manuel

Pages NON mirroirées (EN)

Ces pages FR n’ont pas d’équivalent sous /en/ ; leur translatedPaths.en (et/ou .fr) vaut null :

Limitation : 404 sous /en

La page 404 (src/pages/404.astro) n’est pas dupliquée sous /en/404. Une URL /en/... inexistante affichera donc la 404 par défaut d’Astro (locale FR par défaut côté contenu). Acceptable pour ce périmètre — à traiter dans une itération ultérieure si besoin (ex. src/pages/en/404.astro mirroir).

Liste des 12 pages EN

Page ENMirroir deChemin (sans préfixe)
en/index.astroindex.astro/
en/expertise.astroexpertise.astro/expertise
en/methodology.astromethodologie.astro/methodology
en/about.astroa-propos.astro/about
en/services/index.astroservices/index.astro/services
en/services/[slug].astroservices/[slug].astro/services/:slug
en/case-studies/index.astrocas-clients/index.astro/case-studies
en/case-studies/[slug].astrocas-clients/[slug].astro/case-studies/:slug
en/resources/index.astroressources/index.astro/resources
en/resources/[slug].astroressources/[slug].astro/resources/:slug
en/contact/index.astrocontact/index.astro/contact
en/contact/thank-you.astrocontact/merci.astro/contact/thank-you
en/search/index.astrorecherche/index.astro/search