Ajouter des fonctionnalités i18n
Dans cette recette, vous apprendrez à utiliser les collections de contenus et le routage dynamique pour construire votre propre solution d’internationalisation (i18n) et servir votre contenu dans différentes langues.
Dans la version 4.0, Astro a ajouté un support intégré pour le routage i18n permettant de configurer les langues par défaut et prises en charge, mais a aussi inclut des fonctions d’aide précieuses pour vous aider à servir un public international. Si vous souhaitez l’utiliser à la place, consultez notre guide d’internationalisation pour en savoir plus sur ces fonctionnalités.
Cet exemple sert chaque langue dans son propre sous-chemin, par exemple example.com/en/blog
pour l’anglais et example.com/fr/blog
pour le français.
Si vous préférez que la langue par défaut ne soit pas visible dans l’URL contrairement aux autres langues, vous trouverez des instructions pour masquer la langue par défaut ci-dessous.
Méthode
Titre de la section MéthodeCréer des pages pour chaque langue
Titre de la section Créer des pages pour chaque langue-
Créez un répertoire pour chaque langue que vous voulez supporter. Par exemple,
en/
etfr/
si vous supportez l’anglais et le français :Répertoiresrc/
Répertoirepages/
Répertoireen/
- about.astro
- index.astro
Répertoirefr/
- about.astro
- index.astro
- index.astro
-
Configurez
src/pages/index.astro
pour rediriger vers votre langue par défaut.src/pages/index.astro <meta http-equiv="refresh" content="0;url=/en/" />Cette approche utilise un meta refresh et fonctionnera quelle que soit la manière dont vous déployez votre site. Certains hôtes statiques vous permettent également de configurer les redirections du serveur à l’aide d’un fichier de configuration personnalisé. Consultez la documentation de votre plateforme de déploiement pour plus de détails.
Si vous utilisez un adaptateur SSR, vous pouvez utiliser
Astro.redirect
pour rediriger vers la langue par défaut sur le serveur.src/pages/index.astro ---return Astro.redirect('/en/');---
Utiliser des collections pour le contenu traduit
Titre de la section Utiliser des collections pour le contenu traduit-
Créez un dossier dans
src/content/
pour chaque type de contenu que vous voulez inclure et ajoutez des sous-répertoires pour chaque langue supportée. Par exemple, pour prendre en charge les articles de blog en anglais et en français :Répertoiresrc/
Répertoirecontent/
Répertoireblog/
Répertoireen/ Articles de blog en anglais
- post-1.md
- post-2.md
Répertoirefr/ Articles de blog en français
- post-1.md
- post-2.md
-
Créez un fichier
src/content.config.ts
et exporter une collection pour chaque type de contenu.src/content.config.ts import { defineCollection, z } from 'astro:content';const blogCollection = defineCollection({schema: z.object({title: z.string(),author: z.string(),date: z.date()})});export const collections = {'blog': blogCollection};En savoir plus sur les Collections de contenus. -
Utilisez les routes dynammiques pour récupérer et générer le contenu en fonction d’un paramètre
lang
et d’un paramètreslug
.En mode de rendu statique, utilisez
getStaticPaths
pour faire correspondre chaque entrée de contenu à une page :src/pages/[lang]/blog/[...slug].astro ---import { getCollection, render } from 'astro:content';export async function getStaticPaths() {const pages = await getCollection('blog');const paths = pages.map(page => {const [lang, ...slug] = page.id.split('/');return { params: { lang, slug: slug.join('/') || undefined }, props: page };});return paths;}const { lang, slug } = Astro.params;const page = Astro.props;const formattedDate = page.data.date.toLocaleString(lang);const { Content } = await render(page);---<h1>{page.data.title}</h1><p>by {page.data.author} • {formattedDate}</p><Content/>En mode SSR, recherchez directement l’entrée demandée :
src/pages/[lang]/blog/[...slug].astro ---import { getEntry, render } from 'astro:content';const { lang, slug } = Astro.params;const page = await getEntry('blog', `${lang}/${slug}`);if (!page) {return Astro.redirect('/404');}const formattedDate = page.data.date.toLocaleString(lang);const { Content, headings } = await render(page);---<h1>{page.data.title}</h1><p>by {page.data.author} • {formattedDate}</p><Content/>En savoir plus sur les routes dynamiques.L’exemple ci-dessus utilise la méthode intégrée de mise en forme de la date
toLocaleString()
pour créer une chaîne lisible par un humain à partir de la date de la page d’accueil. Cela permet de s’assurer que la date et l’heure sont formatées pour correspondre à la langue de l’utilisateur.
Traduire les chaînes de l’UI
Titre de la section Traduire les chaînes de l’UICréez des dictionnaires de vocabulaire pour traduire les appellations des éléments de l’interface utilisateur de votre site. Cela permet à vos visiteurs de découvrir votre site dans leur langue.
-
Créez un fichier
src/i18n/ui.ts
pour stocker vos chaînes de traduction :src/i18n/ui.ts export const languages = {en: 'English',fr: 'Français',};export const defaultLang = 'en';export const ui = {en: {'nav.home': 'Home','nav.about': 'About','nav.twitter': 'Twitter',},fr: {'nav.home': 'Accueil','nav.about': 'À propos',},} as const; -
Créez deux fonctions d’aide : une pour détecter la langue de la page basée sur l’URL courante, et une pour obtenir les chaînes de traduction pour les différentes parties de l’interface utilisateur dans
src/i18n/utils.ts
:src/i18n/utils.ts import { ui, defaultLang } from './ui';export function getLangFromUrl(url: URL) {const [, lang] = url.pathname.split('/');if (lang in ui) return lang as keyof typeof ui;return defaultLang;}export function useTranslations(lang: keyof typeof ui) {return function t(key: keyof typeof ui[typeof defaultLang]) {return ui[lang][key] || ui[defaultLang][key];}}À l’étape 1, la chaîne
nav.twitter
n’a pas été traduite en français. Il se peut que vous ne souhaitiez pas que tous les mots soient traduits, comme les noms propres ou les expressions courantes de la profession. L’aideuseTranslations
renvoie la valeur de la langue par défaut si une clé n’est pas traduite. Dans cet exemple, les utilisateurs français verront également “Twitter” dans la barre de navigation. -
Importez les aides là où elles sont nécessaires et utilisez-les pour choisir la chaîne de l’interface utilisateur qui correspond à la langue actuelle. Par exemple, un composant de navigation peut ressembler à ce qui suit :
src/components/Nav.astro ---import { getLangFromUrl, useTranslations } from '../i18n/utils';const lang = getLangFromUrl(Astro.url);const t = useTranslations(lang);---<ul><li><a href={`/${lang}/home/`}>{t('nav.home')}</a></li><li><a href={`/${lang}/about/`}>{t('nav.about')}</a></li><li><a href="https://twitter.com/astrodotbuild">{t('nav.twitter')}</a></li></ul> -
Chaque page doit avoir un attribut
lang
sur l’élément<html>
qui correspond à la langue de la page. Dans cet exemple, un layout réutilisable extrait la langue de la route actuelle :src/layouts/Base.astro ---import { getLangFromUrl } from '../i18n/utils';const lang = getLangFromUrl(Astro.url);---<html lang={lang}><head><meta charset="utf-8" /><link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="viewport" content="width=device-width" /><title>Astro</title></head><body><slot /></body></html>