Prise en charge multilingue et changement de langue
EpoCanvas Docs intègre en natif un multilinguisme complet au niveau du contenu : les textes d’interface (barre de navigation, barre latérale, aides à la recherche, etc.) ainsi que le corps du texte de chaque document existent en 10 versions linguistiques indépendantes. Lorsque le lecteur choisit une langue en haut à droite de la page, il est redirigé vers la version de l’article courant dans la langue cible, avec bascule simultanée du corps du texte et de l’interface.
Liste des langues prises en charge
Le site propose actuellement 10 langues, dont le chinois simplifié est la langue par défaut :
| Langue | Nom de la langue | Préfixe URL | Abréviation dans l’interface |
|---|---|---|---|
| 简体中文 | Chinois simplifié (par défaut) | sans préfixe | ZH |
| 繁體中文 | Chinois traditionnel | /zh-tw/ | TW |
| English | anglais | /en/ | EN |
| 日本語 | japonais | /ja/ | JA |
| 한국어 | coréen | /ko/ | KO |
| Español | espagnol | /es/ | ES |
| Français | français | /fr/ | FR |
| Deutsch | allemand | /de/ | DE |
| Русский | russe | /ru/ | RU |
| Português | portugais | /pt/ | PT |
La liste des langues est définie dans SUPPORTED_LANGUAGES du fichier src/utils/i18n.ts, et le routage des langues est enregistré dans la configuration locales de astro.config.mjs ; les deux doivent rester cohérents.
Comment changer de langue
- Repérez le bouton de langue à droite de la barre de navigation en haut de la page (il affiche l’abréviation de la langue courante, par exemple
ZH) ; - Cliquez sur le bouton : un menu déroulant liste les 10 langues disponibles ;
- Cliquez sur la langue cible (par exemple
Englishou日本語) ; - Le navigateur charge la version de l’article courant dans la langue cible ; la navigation, la barre latérale, la table des matières et le corps du texte passent tous dans la langue cible.

Figure : rendu annoté réel après un clic sur le bouton de langue depuis la page « Prise en charge multilingue et changement de langue ». ① bouton de changement de langue à droite de la barre supérieure ; ② menu déroulant déployé listant les 10 langues (liste défilable) ; ③ langue actuellement active (marquée d’une coche).
Figure : déroulement du changement de langue. Au build, un jeu de pages statiques est généré pour chaque langue ; un clic sur le bouton de langue redirige vers le même article dans la langue correspondante ; lorsqu’il manque la traduction d’une page, le contenu en chinois est affiché automatiquement par repli.
Règles d’URL
Les pages de chaque langue possèdent un préfixe d’URL qui leur est propre ; un même article ne diffère d’une langue à l’autre que par ce préfixe :
/canvas/i18n/ → chinois simplifié (langue par défaut, sans préfixe)/en/canvas/i18n/ → anglais/ja/canvas/i18n/ → japonais/zh-tw/canvas/i18n/ → chinois traditionnel- L’information de langue est encodée directement dans l’URL ; une page obtenue après changement de langue peut être mise en favori et partagée telle quelle, et les moteurs de recherche peuvent indexer chaque langue séparément ;
- Les liens internes du site présents dans une page (navigation, barre latérale, liens recommandés dans le corps du texte) se voient ajouter automatiquement le préfixe de la langue courante : un lecteur qui enchaîne plusieurs articles dans une même langue ne retombe pas sur une page en chinois ;
- Chaque version linguistique est un jeu de pages statiques indépendantes généré au build ; l’attribut
<html lang>de la page correspond à la langue, ce qui permet aux lecteurs d’écran et aux outils de traduction de l’identifier correctement.
Que se passe-t-il en cas de traduction manquante ?
Le système applique une stratégie de repli sur la langue par défaut pour les traductions manquantes : lorsqu’un document n’a pas encore de traduction dans une langue donnée, la page de cette langue affiche le contenu par défaut en chinois simplifié, tandis que le reste de la page (navigation, barre latérale, textes d’interface) reste dans la langue cible ; aucune erreur 404 ni page blanche n’apparaît.
L’avantage de cette stratégie : lors de l’ajout d’un document, il n’est pas nécessaire d’attendre que les traductions dans toutes les langues soient prêtes ; on publie d’abord la version chinoise, puis il suffit de relancer le build une fois les traductions complétées.
Principe de mise en œuvre
La capacité multilingue repose sur le mécanisme d’internationalisation d’Astro et de Starlight ; le processus de build est le suivant :
- Répertoires de contenu répartis par langue : les documents de la langue par défaut sont placés dans
src/content/docs/(chinois simplifié), ceux des autres langues danssrc/content/docs/<langue>/; l’arborescence correspond exactement à celle du chinois — par exemple, la version anglaise de « Prise en charge multilingue et changement de langue » se trouve danssrc/content/docs/en/canvas/i18n.md; - Génération des pages de toutes les langues au build :
astro buildlit la configurationlocalesdeastro.config.mjset génère un jeu complet de pages statiques pour chaque langue ; - Rendu des libellés d’interface par langue : les textes d’interface (navigation de la barre supérieure, aides à la recherche, titres de la table des matières, etc.) sont produits au build directement dans la langue correspondante par les composants via
getTranslation(key, lang); la page ne contient aucun script de substitution à l’exécution ; - Localisation automatique des liens internes du corps du texte : le plugin
rehypeLocalizeInternalLinksde la chaîne de build ajoute automatiquement le préfixe de la langue courante aux liens internes de type/canvas/xxxprésents dans le corps du texte des traductions ; - Recherche plein texte isolée par langue : Pagefind construit un index indépendant pour chaque langue ; une recherche effectuée sur une page anglaise ne renvoie que des résultats en anglais.
- Les images du corps se résolvent par langue : le plugin
rehypeLocalizeDiagramImagesréécrit/images/canvas/<fichier>des traductions en/images/canvas/<langue>/<fichier>, les fichiers de chaque langue étant rangés danspublic/images/canvas/<langue>/; sans fichier du même nom, l’original est conservé, une nouvelle image n’a donc pas à exister dans les 10 langues d’un coup ; - Encadrés et notes de bas de page suivent la langue de la page :
rehypeLocalizeAsidesetrehypeLocalizeFootnotesréécrivent les titres des encadrés et les notes à partir du répertoire de langue du fichier source — Starlight déduit la langue via le chemin absolu à l’étape remark, alors que le build local lui transmet un chemin relatif, sans quoi tout retomberait en chinois ; - hreflang et page 404 : à la fin du build,
hreflangXDefault()ajoute à chaque page unhreflang="x-default"pointant vers la version en chinois simplifié, etsrc/pages/404.astroréutilise le même dictionnaire pour afficher son message dans la langue du navigateur, son menu de langues renvoyant à l’accueil de chaque langue.
Développeurs : comment ajouter une langue ?
Exemple avec l’ajout de l’italien (Italiano, code it) :
- Enregistrer la route de la langue : ajouter
it: { label: 'Italiano', lang: 'it' }danslocalesdeastro.config.mjs; - Compléter les textes de la barre latérale : dans
SIDEBAR_I18Ndu même fichier, ajouter les traductionsitpour tous les groupes et entrées ; - Compléter les libellés d’interface : enregistrer la langue (code, nom, abréviation, préfixe URL) dans
SUPPORTED_LANGUAGESdesrc/utils/i18n.ts, et compléter les libellés d’interface de cette langue dansUI_TRANSLATIONS; - Traduire le contenu des documents : créer le répertoire
src/content/docs/it/et y placer les traductions en respectant l’arborescence de la version chinoise. Les pages non traduites affichent d’abord le contenu chinois par repli ; elles peuvent être complétées progressivement ; Pour traduire aussi captures d’écran et schémas, créezpublic/images/canvas/it/avec des fichiers du même nom : les pages les reprennent automatiquement. - Relancer le build : exécuter
pnpm run build; les pages de la nouvelle langue et les index de recherche sont alors générés. Après le build, lanceznode scripts/audit-i18n.mjsetnode scripts/check-localized-images.mjspour contrôler la structure des traductions et les références d’images ; ces deux vérifications sont obligatoires en CI.
Développeurs : comment ajouter ou modifier un libellé d’interface ?
Lors de l’ajout d’un élément d’interface, complétez les libellés dans UI_TRANSLATIONS de src/utils/i18n.ts :
// Le dictionnaire est organisé en deux niveaux « langue → clé d'entrée », dans l'ordre de lecture de getTranslationexport const UI_TRANSLATIONS: Record<string, Record<string, string>> = { // Étape 1 : ajouter les textes dans la langue par défaut zh-CN (à défaut, l'interface affiche le nom de la clé) 'zh-CN': { 'nav.plugins': '插件生态', // ...autres textes déjà présents }, // Étape 2 : compléter la traduction des mêmes clés pour les autres langues ; sans traduction, retour au chinois en: { 'nav.plugins': 'Plugins', }, ja: { 'nav.plugins': 'プラグイン', },};Appelez ensuite getTranslation dans le composant en lui passant la langue courante :
---import { getLangFromLocale, getTranslation } from '../../utils/i18n';const lang = getLangFromLocale(Astro.currentLocale);---
<a href={localizedHref('/plugins/', lang)}>{getTranslation('nav.plugins', lang)}</a>Les libellés sont rendus au build sous forme de texte statique dans la langue correspondante, sans surcoût à l’exécution.