From 58d648e075bddd5fe724d1d253e5dac3345ce463 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 13 Jul 2026 11:36:07 +0200 Subject: [PATCH] i18n(fr): update `recipes/i18n.mdx` See #14213 --- src/content/docs/fr/recipes/i18n.mdx | 469 ++++++++++++++------------- 1 file changed, 240 insertions(+), 229 deletions(-) diff --git a/src/content/docs/fr/recipes/i18n.mdx b/src/content/docs/fr/recipes/i18n.mdx index 196cbaee1d245..49402d51d00ad 100644 --- a/src/content/docs/fr/recipes/i18n.mdx +++ b/src/content/docs/fr/recipes/i18n.mdx @@ -85,23 +85,21 @@ Si vous préférez que la langue par défaut ne soit pas visible dans l'URL cont 2. Créez un fichier `src/content.config.ts` et exporter une collection pour chaque type de contenu. - ```ts - //src/content.config.ts - import { defineCollection } from 'astro:content'; - import { z } from 'astro/zod'; + ```ts title="src/content.config.ts" + import { defineCollection } from "astro:content"; + import { z } from "astro/zod"; const blogCollection = defineCollection({ schema: z.object({ title: z.string(), author: z.string(), - date: z.date() - }) + date: z.date(), + }), }); export const collections = { - 'blog': blogCollection + blog: blogCollection, }; - ``` En savoir plus sur les [Collections de contenus](/fr/guides/content-collections/). @@ -110,62 +108,62 @@ Si vous préférez que la langue par défaut ne soit pas visible dans l'URL cont - En mode de rendu statique, utilisez `getStaticPaths` pour faire correspondre chaque entrée de contenu à une page : - - ```astro - //src/pages/[lang]/blog/[...slug].astro - --- - import { getCollection, render } from 'astro:content'; + En mode de rendu statique, utilisez `getStaticPaths` pour associer chaque entrée de contenu à une page : - 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); - --- -

{page.data.title}

-

par {page.data.author} • {formattedDate}

- - ``` -
- - - En [mode SSR](/fr/guides/on-demand-rendering/), recherchez directement l'entrée demandée : - - ```astro - //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'); - } + ```astro title="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); + --- + +

{page.data.title}

+

par {page.data.author} • {formattedDate}

+ + ``` +
- const formattedDate = page.data.date.toLocaleString(lang); - const { Content, headings } = await render(page); - --- -

{page.data.title}

-

par {page.data.author} • {formattedDate}

- - ``` - + + En [mode SSR](/fr/guides/on-demand-rendering/), récupérez directement l'entrée demandée : + + ```astro title="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); + --- + +

{page.data.title}

+

par {page.data.author} • {formattedDate}

+ + ``` +
En savoir plus sur les [routes dynamiques](/fr/guides/routing/#routes-dynamiques). - + :::tip[Mise en forme de la date] L'exemple ci-dessus utilise la méthode intégrée de mise en forme de la date [`toLocaleString()`](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/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. @@ -179,44 +177,43 @@ Créez des dictionnaires de vocabulaire pour traduire les appellations des élé 1. Créez un fichier `src/i18n/ui.ts` pour stocker vos chaînes de traduction : - ```ts - // src/i18n/ui.ts + ```ts title="src/i18n/ui.ts" export const languages = { - en: 'English', - fr: 'Français', + en: "English", + fr: "Français", }; - export const defaultLang = 'en'; - + export const defaultLang = "en"; + export const ui = { en: { - 'nav.home': 'Home', - 'nav.about': 'About', - 'nav.twitter': 'Twitter', + "nav.home": "Home", + "nav.about": "About", + "nav.twitter": "Twitter", }, fr: { - 'nav.home': 'Accueil', - 'nav.about': 'À propos', + "nav.home": "Accueil", + "nav.about": "À propos", }, } as const; ``` 2. 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` : - ```js - // src/i18n/utils.ts - import { ui, defaultLang } from './ui'; - + ```ts title="src/i18n/utils.ts" + import { ui, defaultLang } from "./ui"; + export function getLangFromUrl(url: URL) { - const [, lang] = url.pathname.split('/'); + 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]; - } + const localizedUI: Record = ui[lang]; + return function t(key: keyof (typeof ui)[typeof defaultLang]) { + return key in localizedUI ? localizedUI[key] : ui[defaultLang][key]; + }; } ``` @@ -226,66 +223,65 @@ Créez des dictionnaires de vocabulaire pour traduire les appellations des élé 3. 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 : - ```astro + ```astro title="src/components/Nav.astro" --- - // src/components/Nav.astro - import { getLangFromUrl, useTranslations } from '../i18n/utils'; - + import { getLangFromUrl, useTranslations } from "../i18n/utils"; + const lang = getLangFromUrl(Astro.url); const t = useTranslations(lang); --- + ``` 4. Chaque page doit avoir un attribut `lang` sur l'élément `` qui correspond à la langue de la page. Dans cet exemple, une [mise en page réutilisable](/fr/basics/layouts/) extrait la langue de la route actuelle : - ```astro + ```astro title="src/layouts/Base.astro" --- - // src/layouts/Base.astro - - import { getLangFromUrl } from '../i18n/utils'; - + import { getLangFromUrl } from "../i18n/utils"; + const lang = getLangFromUrl(Astro.url); --- + - - - - - Astro - - - - + + + + + Astro + + + + ``` Vous pouvez ensuite utiliser cette mise en page de base pour garantir que les pages utilisent automatiquement l'attribut `lang` correct. - ```astro + ```astro title="src/pages/en/about.astro" --- - // src/pages/en/about.astro - import Base from '../../layouts/Base.astro'; + import Base from "../../layouts/Base.astro"; --- + -

À propos de moi

- ... +

About me

+ ... ```
@@ -297,43 +293,45 @@ Créez des liens vers les différentes langues que vous prenez en charge afin qu 1. Créez un composant pour afficher un lien pour chaque langue : - ```astro + ```astro title="src/components/LanguagePicker.astro" --- - // src/components/LanguagePicker.astro - import { languages } from '../i18n/ui'; + import { languages } from "../i18n/ui"; --- + ``` 2. Ajoutez `` à votre site pour qu'il apparaisse sur chaque page. L'exemple ci-dessous l'ajoute au pied de page du site dans une mise en page de base : - ```astro ins={3,17-19} + ```astro ins={2,17-19} title="src/layouts/Base.astro" --- - // src/layouts/Base.astro - import LanguagePicker from '../components/LanguagePicker.astro'; - import { getLangFromUrl } from '../i18n/utils'; - + import LanguagePicker from "../components/LanguagePicker.astro"; + import { getLangFromUrl } from "../i18n/utils"; + const lang = getLangFromUrl(Astro.url); --- + - - - - - Astro - - - -
- -
- + + + + + Astro + + + +
+ +
+ ```
@@ -355,71 +353,75 @@ Créez des liens vers les différentes langues que vous prenez en charge afin qu 2. Ajoutez une autre ligne au fichier `src/i18n/ui.ts` pour activer our désactiver la fonctionnalité : - ```ts - // src/i18n/ui.ts - export const showDefaultLang = false; - ``` + ```ts title="src/i18n/ui.ts" + export const showDefaultLang = false; + ``` 3. Ajoutez une fonction d'aide à `src/i18n/utils.ts`, pour traduire les chemins en fonction de la langue courante : - - ```js - // src/i18n/utils.ts - import { ui, defaultLang, showDefaultLang } from './ui'; - - export function useTranslatedPath(lang: keyof typeof ui) { - return function translatePath(path: string, l: string = lang) { - return !showDefaultLang && l === defaultLang ? path : `/${l}${path}` - } - } - ``` + + ```ts title="src/i18n/utils.ts" + import { ui, defaultLang, showDefaultLang } from "./ui"; + + export function useTranslatedPath(lang: keyof typeof ui) { + return function translatePath(path: string, l: string = lang) { + return !showDefaultLang && l === defaultLang ? path : `/${l}${path}`; + }; + } + ``` 4. Importez l'aide là où c'est nécessaire. Par exemple, un composant `nav` peut ressembler à ceci : - ```astro + ```astro title="src/components/Nav.astro" --- - // src/components/Nav.astro - import { getLangFromUrl, useTranslations, useTranslatedPath } from '../i18n/utils'; - + import { + getLangFromUrl, + useTranslations, + useTranslatedPath, + } from "../i18n/utils"; + const lang = getLangFromUrl(Astro.url); const t = useTranslations(lang); const translatePath = useTranslatedPath(lang); --- + ``` 5. La fonction d'aide peut également être utilisée pour traduire des chemins d'accès dans une langue spécifique. Par exemple, lorsque les utilisateurs passent d'une langue à l'autre : - ```astro + ```astro title="src/components/LanguagePicker.astro" --- - // src/components/LanguagePicker.astro - import { languages } from '../i18n/ui'; - import { getLangFromUrl, useTranslatedPath } from '../i18n/utils'; - + import { languages } from "../i18n/ui"; + import { getLangFromUrl, useTranslatedPath } from "../i18n/utils"; + const lang = getLangFromUrl(Astro.url); const translatePath = useTranslatedPath(lang); --- + ``` @@ -431,90 +433,99 @@ Traduisez les routes de vos pages pour chaque langue. 1. Ajouter les associations de routes dans `src/i18n/ui.ts` : - ```ts - // src/i18n/ui.ts + ```ts title="src/i18n/ui.ts" export const routes = { de: { - 'services': 'leistungen', + services: "leistungen", }, fr: { - 'services': 'prestations-de-service', + services: "prestations-de-service", }, - } + }; ``` 2. Mettre à jour la fonction d'aide `useTranslatedPath` dans `src/i18n/utils.ts` pour ajouter la logique de traduction du routeur. - ```js - // src/i18n/utils.ts - import { ui, defaultLang, showDefaultLang, routes } from './ui'; + ```ts title="src/i18n/utils.ts" + import { ui, defaultLang, showDefaultLang, routes } from "./ui"; export function useTranslatedPath(lang: keyof typeof ui) { return function translatePath(path: string, l: string = lang) { - const pathName = path.replaceAll('/', '') - const hasTranslation = defaultLang !== l && routes[l] !== undefined && routes[l][pathName] !== undefined - const translatedPath = hasTranslation ? '/' + routes[l][pathName] : path - - return !showDefaultLang && l === defaultLang ? translatedPath : `/${l}${translatedPath}` - } + const pathName = path.replaceAll("/", ""); + const routeMap: Record | undefined = + l !== defaultLang && l in routes + ? routes[l as keyof typeof routes] + : undefined; + const translatedPath = routeMap?.[pathName] + ? "/" + routeMap[pathName] + : path; + + return !showDefaultLang && l === defaultLang + ? translatedPath + : `/${l}${translatedPath}`; + }; } ``` 3. Créer une fonction d'aide pour obtenir la route, si elle existe en fonction de l'URL actuelle, dans `src/i18n/utils.ts` : - ```js - // src/i18n/utils.ts - import { ui, defaultLang, showDefaultLang, routes } from './ui'; - + ```ts title="src/i18n/utils.ts" + import { ui, defaultLang, showDefaultLang, routes } from "./ui"; + export function getRouteFromUrl(url: URL): string | undefined { const pathname = new URL(url).pathname; - const parts = pathname?.split('/'); + const parts = pathname?.split("/"); const path = parts.pop() || parts.pop(); - + if (path === undefined) { return undefined; } - + const currentLang = getLangFromUrl(url); - + if (defaultLang === currentLang) { - const route = Object.values(routes)[0]; - return route[path] !== undefined ? route[path] : undefined; - } - - const getKeyByValue = (obj: Record, value: string): string | undefined => { - return Object.keys(obj).find((key) => obj[key] === value); + const route = Object.values(routes)[0] as Record; + return route[path]; } - + + const getKeyByValue = ( + obj: Record, + value: string, + ): string | undefined => { + return Object.keys(obj).find((key) => obj[key] === value); + }; + const reversedKey = getKeyByValue(routes[currentLang], path); - + if (reversedKey !== undefined) { return reversedKey; } - + return undefined; } ``` 4. La fonction d'aide peut être utilisée pour obtenir une route traduite. Par exemple, si aucune route traduite n'est définie, l'utilisateur sera redirigé vers la page d'accueil : - ```astro + ```astro title="src/components/LanguagePicker.astro" --- - // src/components/LanguagePicker.astro - import { languages } from '../i18n/ui'; - import { getRouteFromUrl, useTranslatedPath } from '../i18n/utils'; + import { languages } from "../i18n/ui"; + import { getRouteFromUrl, useTranslatedPath } from "../i18n/utils"; const route = getRouteFromUrl(Astro.url); --- +
    - {Object.entries(languages).map(([lang, label]) => { - const translatePath = useTranslatedPath(lang); - return ( -
  • - {label} -
  • - ) - })} + { + Object.entries(languages).map(([lang, label]) => { + const translatePath = useTranslatedPath(lang); + return ( +
  • + {label} +
  • + ); + }) + }
```