@intlayer/docs 8.0.0 → 8.0.1-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/generated/docs.entry.cjs +160 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +160 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +8 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/intlayer_with_adonisjs.md +394 -0
- package/docs/ar/intlayer_with_hono.md +223 -0
- package/docs/ar/intlayer_with_vite+preact.md +317 -675
- package/docs/ar/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ar/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ar/packages/adonis-intlayer/t.md +149 -0
- package/docs/ar/packages/hono-intlayer/exports.md +59 -0
- package/docs/ar/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ar/packages/hono-intlayer/t.md +268 -0
- package/docs/de/intlayer_with_adonisjs.md +392 -0
- package/docs/de/intlayer_with_hono.md +418 -0
- package/docs/de/intlayer_with_vite+preact.md +272 -632
- package/docs/de/packages/adonis-intlayer/exports.md +50 -0
- package/docs/de/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/de/packages/adonis-intlayer/t.md +149 -0
- package/docs/de/packages/hono-intlayer/exports.md +59 -0
- package/docs/de/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/de/packages/hono-intlayer/t.md +316 -0
- package/docs/en/index.md +8 -0
- package/docs/en/intlayer_with_adonisjs.md +388 -0
- package/docs/en/intlayer_with_hono.md +418 -0
- package/docs/en/intlayer_with_vite+preact.md +171 -556
- package/docs/en/introduction.md +1 -0
- package/docs/en/packages/adonis-intlayer/exports.md +50 -0
- package/docs/en/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/en/packages/adonis-intlayer/t.md +149 -0
- package/docs/en/packages/hono-intlayer/exports.md +59 -0
- package/docs/en/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/en/packages/hono-intlayer/t.md +316 -0
- package/docs/en-GB/intlayer_with_adonisjs.md +394 -0
- package/docs/en-GB/intlayer_with_hono.md +418 -0
- package/docs/en-GB/intlayer_with_vite+preact.md +236 -583
- package/docs/en-GB/packages/adonis-intlayer/exports.md +50 -0
- package/docs/en-GB/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/en-GB/packages/adonis-intlayer/t.md +149 -0
- package/docs/en-GB/packages/hono-intlayer/exports.md +59 -0
- package/docs/en-GB/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/en-GB/packages/hono-intlayer/t.md +316 -0
- package/docs/es/intlayer_with_adonisjs.md +388 -0
- package/docs/es/intlayer_with_hono.md +418 -0
- package/docs/es/intlayer_with_vite+preact.md +286 -650
- package/docs/es/packages/adonis-intlayer/exports.md +50 -0
- package/docs/es/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/es/packages/adonis-intlayer/t.md +149 -0
- package/docs/es/packages/hono-intlayer/exports.md +59 -0
- package/docs/es/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/es/packages/hono-intlayer/t.md +316 -0
- package/docs/fr/intlayer_with_adonisjs.md +388 -0
- package/docs/fr/intlayer_with_hono.md +418 -0
- package/docs/fr/intlayer_with_vite+preact.md +274 -614
- package/docs/fr/packages/adonis-intlayer/exports.md +50 -0
- package/docs/fr/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/fr/packages/adonis-intlayer/t.md +149 -0
- package/docs/fr/packages/hono-intlayer/exports.md +59 -0
- package/docs/fr/packages/hono-intlayer/intlayer.md +59 -0
- package/docs/fr/packages/hono-intlayer/t.md +316 -0
- package/docs/hi/intlayer_with_adonisjs.md +394 -0
- package/docs/hi/intlayer_with_hono.md +227 -0
- package/docs/hi/intlayer_with_vite+preact.md +304 -680
- package/docs/hi/packages/adonis-intlayer/exports.md +50 -0
- package/docs/hi/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/hi/packages/adonis-intlayer/t.md +149 -0
- package/docs/hi/packages/hono-intlayer/exports.md +59 -0
- package/docs/hi/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/hi/packages/hono-intlayer/t.md +268 -0
- package/docs/id/intlayer_with_adonisjs.md +394 -0
- package/docs/id/intlayer_with_hono.md +227 -0
- package/docs/id/intlayer_with_vite+preact.md +297 -697
- package/docs/id/packages/adonis-intlayer/exports.md +50 -0
- package/docs/id/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/id/packages/adonis-intlayer/t.md +149 -0
- package/docs/id/packages/hono-intlayer/exports.md +59 -0
- package/docs/id/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/id/packages/hono-intlayer/t.md +268 -0
- package/docs/it/intlayer_with_adonisjs.md +394 -0
- package/docs/it/intlayer_with_hono.md +227 -0
- package/docs/it/intlayer_with_vite+preact.md +290 -659
- package/docs/it/packages/adonis-intlayer/exports.md +50 -0
- package/docs/it/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/it/packages/adonis-intlayer/t.md +149 -0
- package/docs/it/packages/hono-intlayer/exports.md +59 -0
- package/docs/it/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/it/packages/hono-intlayer/t.md +268 -0
- package/docs/ja/intlayer_with_adonisjs.md +394 -0
- package/docs/ja/intlayer_with_hono.md +227 -0
- package/docs/ja/intlayer_with_vite+preact.md +307 -662
- package/docs/ja/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ja/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ja/packages/adonis-intlayer/t.md +149 -0
- package/docs/ja/packages/hono-intlayer/exports.md +59 -0
- package/docs/ja/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ja/packages/hono-intlayer/t.md +268 -0
- package/docs/ko/intlayer_with_adonisjs.md +394 -0
- package/docs/ko/intlayer_with_hono.md +227 -0
- package/docs/ko/intlayer_with_vite+preact.md +303 -703
- package/docs/ko/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ko/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ko/packages/adonis-intlayer/t.md +149 -0
- package/docs/ko/packages/hono-intlayer/exports.md +59 -0
- package/docs/ko/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ko/packages/hono-intlayer/t.md +268 -0
- package/docs/pl/intlayer_with_adonisjs.md +394 -0
- package/docs/pl/intlayer_with_hono.md +227 -0
- package/docs/pl/intlayer_with_vite+preact.md +289 -690
- package/docs/pl/packages/adonis-intlayer/exports.md +50 -0
- package/docs/pl/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/pl/packages/adonis-intlayer/t.md +149 -0
- package/docs/pl/packages/hono-intlayer/exports.md +59 -0
- package/docs/pl/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/pl/packages/hono-intlayer/t.md +268 -0
- package/docs/pt/intlayer_with_adonisjs.md +394 -0
- package/docs/pt/intlayer_with_hono.md +227 -0
- package/docs/pt/intlayer_with_vite+preact.md +275 -637
- package/docs/pt/packages/adonis-intlayer/exports.md +50 -0
- package/docs/pt/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/pt/packages/adonis-intlayer/t.md +149 -0
- package/docs/pt/packages/hono-intlayer/exports.md +59 -0
- package/docs/pt/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/pt/packages/hono-intlayer/t.md +268 -0
- package/docs/ru/intlayer_with_adonisjs.md +393 -0
- package/docs/ru/intlayer_with_hono.md +223 -0
- package/docs/ru/intlayer_with_vite+preact.md +319 -683
- package/docs/ru/packages/adonis-intlayer/exports.md +50 -0
- package/docs/ru/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/ru/packages/adonis-intlayer/t.md +149 -0
- package/docs/ru/packages/hono-intlayer/exports.md +59 -0
- package/docs/ru/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/ru/packages/hono-intlayer/t.md +268 -0
- package/docs/tr/intlayer_with_adonisjs.md +394 -0
- package/docs/tr/intlayer_with_hono.md +227 -0
- package/docs/tr/intlayer_with_vite+preact.md +332 -665
- package/docs/tr/packages/adonis-intlayer/exports.md +50 -0
- package/docs/tr/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/tr/packages/adonis-intlayer/t.md +149 -0
- package/docs/tr/packages/hono-intlayer/exports.md +59 -0
- package/docs/tr/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/tr/packages/hono-intlayer/t.md +268 -0
- package/docs/uk/intlayer_with_adonisjs.md +394 -0
- package/docs/uk/intlayer_with_hono.md +227 -0
- package/docs/uk/intlayer_with_vite+preact.md +228 -626
- package/docs/uk/packages/adonis-intlayer/exports.md +50 -0
- package/docs/uk/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/uk/packages/adonis-intlayer/t.md +149 -0
- package/docs/uk/packages/hono-intlayer/exports.md +59 -0
- package/docs/uk/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/uk/packages/hono-intlayer/t.md +268 -0
- package/docs/vi/intlayer_with_adonisjs.md +394 -0
- package/docs/vi/intlayer_with_hono.md +227 -0
- package/docs/vi/intlayer_with_vite+preact.md +294 -679
- package/docs/vi/packages/adonis-intlayer/exports.md +50 -0
- package/docs/vi/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/vi/packages/adonis-intlayer/t.md +149 -0
- package/docs/vi/packages/hono-intlayer/exports.md +59 -0
- package/docs/vi/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/vi/packages/hono-intlayer/t.md +268 -0
- package/docs/zh/intlayer_with_adonisjs.md +393 -0
- package/docs/zh/intlayer_with_hono.md +418 -0
- package/docs/zh/intlayer_with_vite+preact.md +338 -743
- package/docs/zh/packages/adonis-intlayer/exports.md +50 -0
- package/docs/zh/packages/adonis-intlayer/intlayer.md +54 -0
- package/docs/zh/packages/adonis-intlayer/t.md +149 -0
- package/docs/zh/packages/hono-intlayer/exports.md +59 -0
- package/docs/zh/packages/hono-intlayer/intlayer.md +60 -0
- package/docs/zh/packages/hono-intlayer/t.md +294 -0
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +160 -0
|
@@ -92,8 +92,6 @@ bun add vite-intlayer --dev
|
|
|
92
92
|
bunx intlayer init
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
- **intlayer**
|
|
96
|
-
|
|
97
95
|
- **intlayer**
|
|
98
96
|
|
|
99
97
|
Le paquet principal qui fournit des outils d'internationalisation pour la gestion de la configuration, la traduction, la [déclaration de contenu](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/get_started.md), la transpilation, et les [commandes CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_cli.md).
|
|
@@ -121,6 +119,10 @@ const config: IntlayerConfig = {
|
|
|
121
119
|
],
|
|
122
120
|
defaultLocale: Locales.ENGLISH,
|
|
123
121
|
},
|
|
122
|
+
routing: {
|
|
123
|
+
mode: "prefix-no-default", // Par défaut : préfixe toutes les locales sauf la locale par défaut
|
|
124
|
+
storage: ["cookie", "header"], // Par défaut : stocker la locale dans un cookie et détecter via l'en-tête
|
|
125
|
+
},
|
|
124
126
|
};
|
|
125
127
|
|
|
126
128
|
export default config;
|
|
@@ -140,6 +142,10 @@ const config = {
|
|
|
140
142
|
],
|
|
141
143
|
defaultLocale: Locales.ENGLISH,
|
|
142
144
|
},
|
|
145
|
+
routing: {
|
|
146
|
+
mode: "prefix-no-default", // Par défaut : préfixe toutes les locales sauf la locale par défaut
|
|
147
|
+
storage: ["cookie", "header"], // Par défaut : stocker la locale dans un cookie et détecter via l'en-tête
|
|
148
|
+
},
|
|
143
149
|
};
|
|
144
150
|
|
|
145
151
|
export default config;
|
|
@@ -159,12 +165,16 @@ const config = {
|
|
|
159
165
|
],
|
|
160
166
|
defaultLocale: Locales.ENGLISH,
|
|
161
167
|
},
|
|
168
|
+
routing: {
|
|
169
|
+
mode: "prefix-no-default", // Par défaut : préfixe toutes les locales sauf la locale par défaut
|
|
170
|
+
storage: ["cookie", "header"], // Par défaut : stocker la locale dans un cookie et détecter via l'en-tête
|
|
171
|
+
},
|
|
162
172
|
};
|
|
163
173
|
|
|
164
174
|
module.exports = config;
|
|
165
175
|
```
|
|
166
176
|
|
|
167
|
-
> Grâce à ce fichier de configuration, vous pouvez configurer des URL localisées,
|
|
177
|
+
> Grâce à ce fichier de configuration, vous pouvez configurer des URL localisées, les modes de routage, les options de stockage, les noms des cookies, l'emplacement et l'extension de vos déclarations de contenu, désactiver les logs Intlayer dans la console, et bien plus encore. Pour une liste complète des paramètres disponibles, consultez la [documentation de configuration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/configuration.md).
|
|
168
178
|
|
|
169
179
|
### Étape 3 : Intégrer Intlayer dans votre configuration Vite
|
|
170
180
|
|
|
@@ -300,7 +310,7 @@ const appContent = {
|
|
|
300
310
|
readTheDocs: t({
|
|
301
311
|
en: "Click on the Vite and Preact logos to learn more",
|
|
302
312
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
303
|
-
es: "Haga clic en los logotipos de Vite
|
|
313
|
+
es: "Haga clic en los logotipos de Vite et Preact pour obtenir plus d'informations",
|
|
304
314
|
}),
|
|
305
315
|
},
|
|
306
316
|
};
|
|
@@ -344,7 +354,7 @@ const appContent = {
|
|
|
344
354
|
readTheDocs: t({
|
|
345
355
|
en: "Click on the Vite and Preact logos to learn more",
|
|
346
356
|
fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
347
|
-
es: "Haga clic en los logotipos de Vite
|
|
357
|
+
es: "Haga clic en los logotipos de Vite et Preact pour en savoir plus",
|
|
348
358
|
}),
|
|
349
359
|
},
|
|
350
360
|
};
|
|
@@ -402,7 +412,7 @@ module.exports = appContent;
|
|
|
402
412
|
"translation": {
|
|
403
413
|
"en": "Click on the Vite and Preact logos to learn more",
|
|
404
414
|
"fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
|
|
405
|
-
"es": "Haga clic en los logotipos de Vite y Preact para
|
|
415
|
+
"es": "Haga clic en los logotipos de Vite y Preact para obtenir plus d'informations"
|
|
406
416
|
}
|
|
407
417
|
}
|
|
408
418
|
}
|
|
@@ -453,6 +463,12 @@ const AppContent: FunctionalComponent = () => {
|
|
|
453
463
|
</button>
|
|
454
464
|
<p>{content.edit}</p>
|
|
455
465
|
</div>
|
|
466
|
+
{/* Contenu Markdown */}
|
|
467
|
+
<div>{content.myMarkdownContent}</div>
|
|
468
|
+
|
|
469
|
+
{/* Contenu HTML */}
|
|
470
|
+
<div>{content.myHtmlContent}</div>
|
|
471
|
+
|
|
456
472
|
<p class="read-the-docs">{content.readTheDocs}</p>
|
|
457
473
|
</>
|
|
458
474
|
);
|
|
@@ -631,7 +647,7 @@ module.exports = LocaleSwitcher;
|
|
|
631
647
|
|
|
632
648
|
### (Optionnel) Étape 7 : Ajouter un routage localisé à votre application
|
|
633
649
|
|
|
634
|
-
|
|
650
|
+
L'objectif de cette étape est de créer des routes uniques pour chaque langue. Ceci est utile pour le SEO et les URL conviviales.
|
|
635
651
|
Exemple :
|
|
636
652
|
|
|
637
653
|
```plaintext
|
|
@@ -640,396 +656,96 @@ Exemple :
|
|
|
640
656
|
- https://example.com/fr/about
|
|
641
657
|
```
|
|
642
658
|
|
|
643
|
-
> Par défaut, les routes ne sont pas préfixées pour la
|
|
644
|
-
|
|
645
|
-
Pour ajouter un routage localisé à votre application, vous pouvez créer un composant `LocaleRouter` qui enveloppe les routes de votre application et gère le routage basé sur la locale. Voici un exemple utilisant [preact-iso](https://github.com/preactjs/preact-iso) :
|
|
659
|
+
> Par défaut, les routes ne sont pas préfixées pour la langue par défaut. Si vous souhaitez préfixer la langue par défaut, vous pouvez définir l'option `routing.mode` sur `"prefix-all"` dans votre configuration. Voir la [documentation de configuration](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/configuration.md) pour plus d'informations.
|
|
646
660
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
```bash packageManager="npm"
|
|
650
|
-
npm install preact-iso
|
|
651
|
-
npx intlayer init
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
```bash packageManager="pnpm"
|
|
655
|
-
pnpm add preact-iso
|
|
656
|
-
pnpm intlayer init
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
```bash packageManager="yarn"
|
|
660
|
-
yarn add preact-iso
|
|
661
|
-
```
|
|
661
|
+
Pour ajouter un routage localisé à votre application, vous pouvez créer un composant `LocaleRouter` qui enveloppe les routes de votre application et gère le routage basé sur la langue. Voici un exemple utilisant [preact-iso](https://github.com/preactjs/preact-iso) :
|
|
662
662
|
|
|
663
663
|
```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
|
|
664
|
-
import {
|
|
665
|
-
import { ComponentChildren, FunctionalComponent } from "preact";
|
|
664
|
+
import { localeMap } from "intlayer";
|
|
666
665
|
import { IntlayerProvider } from "preact-intlayer";
|
|
667
|
-
import { LocationProvider,
|
|
668
|
-
import {
|
|
669
|
-
|
|
670
|
-
const { internationalization, middleware } = configuration;
|
|
671
|
-
const { locales, defaultLocale } = internationalization;
|
|
672
|
-
|
|
673
|
-
const Navigate: FunctionalComponent<{ to: string; replace?: boolean }> = ({
|
|
674
|
-
to,
|
|
675
|
-
replace,
|
|
676
|
-
}) => {
|
|
677
|
-
const { route } = useLocation();
|
|
678
|
-
useEffect(() => {
|
|
679
|
-
route(to, replace);
|
|
680
|
-
}, [to, replace, route]);
|
|
681
|
-
return null;
|
|
682
|
-
};
|
|
683
|
-
|
|
684
|
-
/**
|
|
685
|
-
/**
|
|
686
|
-
* Un composant qui gère la localisation et enveloppe les enfants avec le contexte de langue approprié.
|
|
687
|
-
* Il gère la détection et la validation de la langue basée sur l'URL.
|
|
688
|
-
*/
|
|
689
|
-
const AppLocalized: FunctionalComponent<{
|
|
690
|
-
children: ComponentChildren;
|
|
691
|
-
locale?: Locales;
|
|
692
|
-
}> = ({ children, locale }) => {
|
|
693
|
-
const { path: pathname, url } = useLocation();
|
|
694
|
-
|
|
695
|
-
if (!url) {
|
|
696
|
-
return null;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
const search = url.substring(pathname.length);
|
|
700
|
-
|
|
701
|
-
// Détermine la langue courante, en revenant à la langue par défaut si elle n'est pas fournie
|
|
702
|
-
const currentLocale = locale ?? defaultLocale;
|
|
703
|
-
|
|
704
|
-
// Supprime le préfixe de langue du chemin pour construire un chemin de base
|
|
705
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
706
|
-
pathname // Chemin URL actuel
|
|
707
|
-
);
|
|
708
|
-
|
|
709
|
-
/**
|
|
710
|
-
* Si middleware.prefixDefault est vrai, la locale par défaut doit toujours être préfixée.
|
|
711
|
-
*/
|
|
712
|
-
if (middleware.prefixDefault) {
|
|
713
|
-
// Valider la locale
|
|
714
|
-
if (!locale || !locales.includes(locale)) {
|
|
715
|
-
// Rediriger vers la locale par défaut avec le chemin mis à jour
|
|
716
|
-
return (
|
|
717
|
-
<Navigate
|
|
718
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
719
|
-
replace // Remplacer l'entrée actuelle de l'historique par la nouvelle
|
|
720
|
-
/>
|
|
721
|
-
);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
// Envelopper les enfants avec IntlayerProvider et définir la locale actuelle
|
|
725
|
-
return (
|
|
726
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
727
|
-
);
|
|
728
|
-
} else {
|
|
729
|
-
/**
|
|
730
|
-
* Lorsque middleware.prefixDefault est faux, la locale par défaut n'est pas préfixée.
|
|
731
|
-
* Assurez-vous que la locale actuelle est valide et n'est pas la locale par défaut.
|
|
732
|
-
*/
|
|
733
|
-
if (
|
|
734
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
735
|
-
!locales
|
|
736
|
-
.filter(
|
|
737
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Exclure la locale par défaut
|
|
738
|
-
)
|
|
739
|
-
.includes(currentLocale) // Vérifier si la locale actuelle est dans la liste des locales valides
|
|
740
|
-
) {
|
|
741
|
-
// Rediriger vers le chemin sans préfixe de locale
|
|
742
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// Envelopper les enfants avec IntlayerProvider et définir la locale actuelle
|
|
746
|
-
return (
|
|
747
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
|
|
752
|
-
const RouterContent: FunctionalComponent<{
|
|
753
|
-
children: ComponentChildren;
|
|
754
|
-
}> = ({ children }) => {
|
|
755
|
-
const { path } = useLocation();
|
|
756
|
-
|
|
757
|
-
if (!path) {
|
|
758
|
-
return null;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
const pathLocale = path.split("/")[1] as Locales;
|
|
762
|
-
|
|
763
|
-
const isLocaleRoute = locales
|
|
764
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
765
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
766
|
-
|
|
767
|
-
if (isLocaleRoute) {
|
|
768
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
return (
|
|
772
|
-
<AppLocalized
|
|
773
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
774
|
-
>
|
|
775
|
-
{children}
|
|
776
|
-
</AppLocalized>
|
|
777
|
-
);
|
|
778
|
-
};
|
|
666
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
667
|
+
import type { ComponentChildren, FunctionalComponent } from "preact";
|
|
779
668
|
|
|
780
669
|
/**
|
|
781
|
-
* Un composant de routeur qui configure des routes spécifiques à la
|
|
782
|
-
* Il utilise preact-iso pour gérer la navigation et
|
|
670
|
+
* Un composant de routeur qui configure des routes spécifiques à la langue.
|
|
671
|
+
* Il utilise preact-iso pour gérer la navigation et afficher des composants localisés.
|
|
783
672
|
*/
|
|
784
673
|
export const LocaleRouter: FunctionalComponent<{
|
|
785
674
|
children: ComponentChildren;
|
|
786
675
|
}> = ({ children }) => (
|
|
787
676
|
<LocationProvider>
|
|
788
|
-
<
|
|
677
|
+
<Router>
|
|
678
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
679
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
680
|
+
.map(({ locale, urlPrefix }) => (
|
|
681
|
+
<Route
|
|
682
|
+
key={locale}
|
|
683
|
+
path={`${urlPrefix}/:rest*`}
|
|
684
|
+
component={() => (
|
|
685
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
686
|
+
)}
|
|
687
|
+
/>
|
|
688
|
+
))}
|
|
689
|
+
</Router>
|
|
789
690
|
</LocationProvider>
|
|
790
691
|
);
|
|
791
692
|
```
|
|
792
693
|
|
|
793
694
|
```jsx fileName="src/components/LocaleRouter.jsx" codeFormat="esm"
|
|
794
|
-
|
|
795
|
-
import { configuration, getPathWithoutLocale } from "intlayer";
|
|
695
|
+
import { localeMap } from "intlayer";
|
|
796
696
|
import { IntlayerProvider } from "preact-intlayer";
|
|
797
|
-
import { LocationProvider,
|
|
798
|
-
import { useEffect } from "preact/hooks";
|
|
799
|
-
import { h } from "preact"; // Requis pour JSX
|
|
800
|
-
|
|
801
|
-
// Déstructuration de la configuration depuis Intlayer
|
|
802
|
-
const { internationalization, middleware } = configuration;
|
|
803
|
-
const { locales, defaultLocale } = internationalization;
|
|
804
|
-
|
|
805
|
-
const Navigate = ({ to, replace }) => {
|
|
806
|
-
const { route } = useLocation();
|
|
807
|
-
useEffect(() => {
|
|
808
|
-
route(to, replace);
|
|
809
|
-
}, [to, replace, route]);
|
|
810
|
-
return null;
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
/**
|
|
814
|
-
* Un composant qui gère la localisation et enveloppe les enfants avec le contexte de locale approprié.
|
|
815
|
-
* Il gère la détection et la validation de la locale basée sur l'URL.
|
|
816
|
-
*/
|
|
817
|
-
const AppLocalized = ({ children, locale }) => {
|
|
818
|
-
const { path: pathname, url } = useLocation();
|
|
819
|
-
|
|
820
|
-
if (!url) {
|
|
821
|
-
return null;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
const search = url.substring(pathname.length);
|
|
825
|
-
|
|
826
|
-
// Détermine la locale actuelle, en revenant à la locale par défaut si aucune n'est fournie
|
|
827
|
-
const currentLocale = locale ?? defaultLocale;
|
|
828
|
-
|
|
829
|
-
// Supprime le préfixe de la locale du chemin pour construire un chemin de base
|
|
830
|
-
const pathWithoutLocale = getPathWithoutLocale(
|
|
831
|
-
pathname // Chemin URL actuel
|
|
832
|
-
);
|
|
833
|
-
|
|
834
|
-
/**
|
|
835
|
-
* Si middleware.prefixDefault est vrai, la locale par défaut doit toujours être préfixée.
|
|
836
|
-
*/
|
|
837
|
-
if (middleware.prefixDefault) {
|
|
838
|
-
// Valider la locale
|
|
839
|
-
if (!locale || !locales.includes(locale)) {
|
|
840
|
-
// Rediriger vers la locale par défaut avec le chemin mis à jour
|
|
841
|
-
return (
|
|
842
|
-
<Navigate
|
|
843
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
844
|
-
replace // Remplacer l'entrée actuelle de l'historique par la nouvelle
|
|
845
|
-
/>
|
|
846
|
-
);
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
// Envelopper les enfants avec IntlayerProvider et définir la locale actuelle
|
|
850
|
-
return (
|
|
851
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
852
|
-
);
|
|
853
|
-
} else {
|
|
854
|
-
/**
|
|
855
|
-
* Lorsque middleware.prefixDefault est faux, la locale par défaut n'est pas préfixée.
|
|
856
|
-
* Assurez-vous que la locale actuelle est valide et n'est pas la locale par défaut.
|
|
857
|
-
*/
|
|
858
|
-
if (
|
|
859
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
860
|
-
!locales
|
|
861
|
-
.filter(
|
|
862
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Exclure la locale par défaut
|
|
863
|
-
)
|
|
864
|
-
.includes(currentLocale) // Vérifier si la locale actuelle est dans la liste des locales valides
|
|
865
|
-
) {
|
|
866
|
-
// Rediriger vers le chemin sans préfixe de locale
|
|
867
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
// Envelopper les enfants avec IntlayerProvider et définir la locale actuelle
|
|
871
|
-
return (
|
|
872
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
873
|
-
);
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
|
|
877
|
-
const RouterContent = ({ children }) => {
|
|
878
|
-
const { path } = useLocation();
|
|
879
|
-
|
|
880
|
-
if (!path) {
|
|
881
|
-
return null;
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
const pathLocale = path.split("/")[1];
|
|
885
|
-
|
|
886
|
-
const isLocaleRoute = locales
|
|
887
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
888
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
889
|
-
|
|
890
|
-
if (isLocaleRoute) {
|
|
891
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
return (
|
|
895
|
-
<AppLocalized
|
|
896
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
897
|
-
>
|
|
898
|
-
{children}
|
|
899
|
-
</AppLocalized>
|
|
900
|
-
);
|
|
901
|
-
};
|
|
697
|
+
import { LocationProvider, Router, Route } from "preact-iso";
|
|
902
698
|
|
|
903
699
|
/**
|
|
904
|
-
* Un composant de routeur qui configure des routes spécifiques à
|
|
905
|
-
* Il utilise preact-iso pour gérer la navigation et
|
|
700
|
+
* Un composant de routeur qui configure des routes spécifiques à la langue.
|
|
701
|
+
* Il utilise preact-iso pour gérer la navigation et afficher des composants localisés.
|
|
906
702
|
*/
|
|
907
703
|
export const LocaleRouter = ({ children }) => (
|
|
908
704
|
<LocationProvider>
|
|
909
|
-
<
|
|
705
|
+
<Router>
|
|
706
|
+
{localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
707
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
708
|
+
.map(({ locale, urlPrefix }) => (
|
|
709
|
+
<Route
|
|
710
|
+
key={locale}
|
|
711
|
+
path={`${urlPrefix}/:rest*`}
|
|
712
|
+
component={() => (
|
|
713
|
+
<IntlayerProvider locale={locale}>{children}</IntlayerProvider>
|
|
714
|
+
)}
|
|
715
|
+
/>
|
|
716
|
+
))}
|
|
717
|
+
</Router>
|
|
910
718
|
</LocationProvider>
|
|
911
719
|
);
|
|
912
720
|
```
|
|
913
721
|
|
|
914
722
|
```jsx fileName="src/components/LocaleRouter.cjsx" codeFormat="commonjs"
|
|
915
|
-
|
|
916
|
-
const { configuration, getPathWithoutLocale } = require("intlayer");
|
|
723
|
+
const { localeMap } = require("intlayer");
|
|
917
724
|
const { IntlayerProvider } = require("preact-intlayer");
|
|
918
|
-
const { LocationProvider,
|
|
919
|
-
const { useEffect } = require("preact/hooks");
|
|
920
|
-
const { h } = require("preact"); // Requis pour JSX
|
|
921
|
-
|
|
922
|
-
// Déstructuration de la configuration depuis Intlayer
|
|
923
|
-
const { internationalization, middleware } = configuration;
|
|
924
|
-
const { locales, defaultLocale } = internationalization;
|
|
925
|
-
|
|
926
|
-
const Navigate = ({ to, replace }) => {
|
|
927
|
-
const { route } = useLocation();
|
|
928
|
-
useEffect(() => {
|
|
929
|
-
route(to, replace);
|
|
930
|
-
}, [to, replace, route]);
|
|
931
|
-
return null;
|
|
932
|
-
};
|
|
725
|
+
const { LocationProvider, Router, Route } = require("preact-iso");
|
|
933
726
|
|
|
934
727
|
/**
|
|
935
|
-
* Un composant
|
|
936
|
-
* Il
|
|
728
|
+
* Un composant de routeur qui configure des routes spécifiques à la langue.
|
|
729
|
+
* Il utilise preact-iso pour gérer la navigation et afficher des composants localisés.
|
|
937
730
|
*/
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
);
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Si middleware.prefixDefault est vrai, la locale par défaut doit toujours être préfixée.
|
|
957
|
-
*/
|
|
958
|
-
if (middleware.prefixDefault) {
|
|
959
|
-
// Valider la locale
|
|
960
|
-
if (!locale || !locales.includes(locale)) {
|
|
961
|
-
// Rediriger vers la locale par défaut avec le chemin mis à jour
|
|
962
|
-
return (
|
|
963
|
-
<Navigate
|
|
964
|
-
to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
|
|
965
|
-
replace // Remplace l'entrée actuelle de l'historique par la nouvelle
|
|
966
|
-
/>
|
|
967
|
-
);
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
// Envelopper les enfants avec IntlayerProvider et définir la locale actuelle
|
|
971
|
-
return (
|
|
972
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
973
|
-
);
|
|
974
|
-
} else {
|
|
975
|
-
/**
|
|
976
|
-
* Lorsque middleware.prefixDefault est faux, la locale par défaut n'est pas préfixée.
|
|
977
|
-
* Assurez-vous que la locale actuelle est valide et n'est pas la locale par défaut.
|
|
978
|
-
*/
|
|
979
|
-
if (
|
|
980
|
-
currentLocale.toString() !== defaultLocale.toString() &&
|
|
981
|
-
!locales
|
|
982
|
-
.filter(
|
|
983
|
-
(loc) => loc.toString() !== defaultLocale.toString() // Exclure la locale par défaut
|
|
731
|
+
const LocaleRouter = ({ children }) =>
|
|
732
|
+
h(
|
|
733
|
+
LocationProvider,
|
|
734
|
+
{},
|
|
735
|
+
h(
|
|
736
|
+
Router,
|
|
737
|
+
{},
|
|
738
|
+
localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
|
|
739
|
+
.sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
|
|
740
|
+
.map(({ locale, urlPrefix }) =>
|
|
741
|
+
h(Route, {
|
|
742
|
+
key: locale,
|
|
743
|
+
path: `${urlPrefix}/:rest*`,
|
|
744
|
+
component: () => h(IntlayerProvider, { locale }, children),
|
|
745
|
+
})
|
|
984
746
|
)
|
|
985
|
-
|
|
986
|
-
) {
|
|
987
|
-
// Redirige vers le chemin sans préfixe de locale
|
|
988
|
-
return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
// Enveloppe les enfants avec IntlayerProvider et définit la locale actuelle
|
|
992
|
-
return (
|
|
993
|
-
<IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
|
|
994
|
-
);
|
|
995
|
-
}
|
|
996
|
-
};
|
|
997
|
-
|
|
998
|
-
const RouterContent = ({ children }) => {
|
|
999
|
-
const { path } = useLocation();
|
|
1000
|
-
|
|
1001
|
-
if (!path) {
|
|
1002
|
-
return null;
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
const pathLocale = path.split("/")[1];
|
|
1006
|
-
|
|
1007
|
-
const isLocaleRoute = locales
|
|
1008
|
-
.filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
|
|
1009
|
-
.some((locale) => locale.toString() === pathLocale);
|
|
1010
|
-
|
|
1011
|
-
if (isLocaleRoute) {
|
|
1012
|
-
return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
return (
|
|
1016
|
-
<AppLocalized
|
|
1017
|
-
locale={!middleware.prefixDefault ? defaultLocale : undefined}
|
|
1018
|
-
>
|
|
1019
|
-
{children}
|
|
1020
|
-
</AppLocalized>
|
|
747
|
+
)
|
|
1021
748
|
);
|
|
1022
|
-
};
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* Un composant de routeur qui configure des routes spécifiques à la locale.
|
|
1026
|
-
* Il utilise preact-iso pour gérer la navigation et rendre des composants localisés.
|
|
1027
|
-
*/
|
|
1028
|
-
const LocaleRouter = ({ children }) => (
|
|
1029
|
-
<LocationProvider>
|
|
1030
|
-
<RouterContent>{children}</RouterContent>
|
|
1031
|
-
</LocationProvider>
|
|
1032
|
-
);
|
|
1033
749
|
|
|
1034
750
|
module.exports = { LocaleRouter };
|
|
1035
751
|
```
|
|
@@ -1039,7 +755,8 @@ Ensuite, vous pouvez utiliser le composant `LocaleRouter` dans votre application
|
|
|
1039
755
|
```tsx fileName="src/app.tsx" codeFormat="typescript"
|
|
1040
756
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1041
757
|
import type { FunctionalComponent } from "preact";
|
|
1042
|
-
|
|
758
|
+
|
|
759
|
+
// ... Votre composant AppContent
|
|
1043
760
|
|
|
1044
761
|
const App: FunctionalComponent = () => (
|
|
1045
762
|
<LocaleRouter>
|
|
@@ -1052,7 +769,8 @@ export default App;
|
|
|
1052
769
|
|
|
1053
770
|
```jsx fileName="src/app.jsx" codeFormat="esm"
|
|
1054
771
|
import { LocaleRouter } from "./components/LocaleRouter";
|
|
1055
|
-
|
|
772
|
+
|
|
773
|
+
// ... Votre composant AppContent
|
|
1056
774
|
|
|
1057
775
|
const App = () => (
|
|
1058
776
|
<LocaleRouter>
|
|
@@ -1065,7 +783,8 @@ export default App;
|
|
|
1065
783
|
|
|
1066
784
|
```jsx fileName="src/app.cjsx" codeFormat="commonjs"
|
|
1067
785
|
const { LocaleRouter } = require("./components/LocaleRouter");
|
|
1068
|
-
|
|
786
|
+
|
|
787
|
+
// ... Votre composant AppContent
|
|
1069
788
|
|
|
1070
789
|
const App = () => (
|
|
1071
790
|
<LocaleRouter>
|
|
@@ -1076,47 +795,12 @@ const App = () => (
|
|
|
1076
795
|
module.exports = App;
|
|
1077
796
|
```
|
|
1078
797
|
|
|
1079
|
-
En parallèle, vous pouvez également utiliser le `intlayerProxy` pour ajouter un routage côté serveur à votre application. Ce plugin détectera automatiquement la locale actuelle en fonction de l'URL et définira le cookie de locale approprié. Si aucune locale n'est spécifiée, le plugin déterminera la locale la plus appropriée en fonction des préférences linguistiques du navigateur de l'utilisateur. Si aucune locale n'est détectée, il redirigera vers la locale par défaut.
|
|
1080
|
-
|
|
1081
|
-
```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
|
|
1082
|
-
import { defineConfig } from "vite";
|
|
1083
|
-
import preact from "@preact/preset-vite";
|
|
1084
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1085
|
-
|
|
1086
|
-
// https://vitejs.dev/config/
|
|
1087
|
-
export default defineConfig({
|
|
1088
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1089
|
-
});
|
|
1090
|
-
```
|
|
1091
|
-
|
|
1092
|
-
```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
|
|
1093
|
-
import { defineConfig } from "vite";
|
|
1094
|
-
import preact from "@preact/preset-vite";
|
|
1095
|
-
import { intlayer, intlayerProxy } from "vite-intlayer";
|
|
1096
|
-
|
|
1097
|
-
// https://vitejs.dev/config/
|
|
1098
|
-
export default defineConfig({
|
|
1099
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1100
|
-
});
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
|
|
1104
|
-
const { defineConfig } = require("vite");
|
|
1105
|
-
const preact = require("@preact/preset-vite");
|
|
1106
|
-
const { intlayer, intlayerProxy } = require("vite-intlayer");
|
|
1107
|
-
|
|
1108
|
-
// https://vitejs.dev/config/
|
|
1109
|
-
module.exports = defineConfig({
|
|
1110
|
-
plugins: [preact(), intlayer(), intlayerProxy()],
|
|
1111
|
-
});
|
|
1112
|
-
```
|
|
1113
|
-
|
|
1114
798
|
### (Optionnel) Étape 8 : Changer l'URL lorsque la langue change
|
|
1115
799
|
|
|
1116
|
-
Pour changer l'URL lorsque la langue change, vous pouvez utiliser la propriété `onLocaleChange` fournie par le hook `useLocale`.
|
|
800
|
+
Pour changer l'URL lorsque la langue change, vous pouvez utiliser la propriété `onLocaleChange` fournie par le hook `useLocale`. En parallèle, vous pouvez utiliser la méthode `route` de `useLocation` de `preact-iso` pour mettre à jour le chemin de l'URL.
|
|
1117
801
|
|
|
1118
802
|
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
|
|
1119
|
-
import { useLocation
|
|
803
|
+
import { useLocation } from "preact-iso";
|
|
1120
804
|
import {
|
|
1121
805
|
Locales,
|
|
1122
806
|
getHTMLTextDir,
|
|
@@ -1127,13 +811,12 @@ import { useLocale } from "preact-intlayer";
|
|
|
1127
811
|
import type { FunctionalComponent } from "preact";
|
|
1128
812
|
|
|
1129
813
|
const LocaleSwitcher: FunctionalComponent = () => {
|
|
1130
|
-
const
|
|
814
|
+
const { url, route } = useLocation();
|
|
1131
815
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1132
816
|
onLocaleChange: (newLocale) => {
|
|
1133
|
-
|
|
1134
|
-
// Construire l'URL avec la locale mise à jour
|
|
817
|
+
// Construire l'URL avec la langue mise à jour
|
|
1135
818
|
// Exemple : /es/about?foo=bar
|
|
1136
|
-
const pathWithLocale = getLocalizedUrl(
|
|
819
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1137
820
|
|
|
1138
821
|
// Mettre à jour le chemin de l'URL
|
|
1139
822
|
route(pathWithLocale, true); // true pour remplacer
|
|
@@ -1146,7 +829,7 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
1146
829
|
<div id="localePopover" popover="auto">
|
|
1147
830
|
{availableLocales.map((localeItem) => (
|
|
1148
831
|
<a
|
|
1149
|
-
href={getLocalizedUrl(
|
|
832
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1150
833
|
hreflang={localeItem}
|
|
1151
834
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1152
835
|
onClick={(e) => {
|
|
@@ -1161,11 +844,11 @@ const LocaleSwitcher: FunctionalComponent = () => {
|
|
|
1161
844
|
{localeItem}
|
|
1162
845
|
</span>
|
|
1163
846
|
<span>
|
|
1164
|
-
{/* Langue dans sa propre
|
|
847
|
+
{/* Langue dans sa propre langue - ex. Français */}
|
|
1165
848
|
{getLocaleName(localeItem, localeItem)}
|
|
1166
849
|
</span>
|
|
1167
850
|
<span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
|
|
1168
|
-
{/* Langue dans la
|
|
851
|
+
{/* Langue dans la langue actuelle - ex. Francés avec la langue actuelle définie sur Locales.SPANISH */}
|
|
1169
852
|
{getLocaleName(localeItem, locale)}
|
|
1170
853
|
</span>
|
|
1171
854
|
<span dir="ltr" lang={Locales.ENGLISH}>
|
|
@@ -1183,7 +866,7 @@ export default LocaleSwitcher;
|
|
|
1183
866
|
```
|
|
1184
867
|
|
|
1185
868
|
```jsx fileName="src/components/LocaleSwitcher.jsx" codeFormat="esm"
|
|
1186
|
-
import { useLocation
|
|
869
|
+
import { useLocation } from "preact-iso";
|
|
1187
870
|
import {
|
|
1188
871
|
Locales,
|
|
1189
872
|
getHTMLTextDir,
|
|
@@ -1191,14 +874,12 @@ import {
|
|
|
1191
874
|
getLocalizedUrl,
|
|
1192
875
|
} from "intlayer";
|
|
1193
876
|
import { useLocale } from "preact-intlayer";
|
|
1194
|
-
import { h } from "preact"; // Pour JSX
|
|
1195
877
|
|
|
1196
878
|
const LocaleSwitcher = () => {
|
|
1197
|
-
const
|
|
879
|
+
const { url, route } = useLocation();
|
|
1198
880
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1199
881
|
onLocaleChange: (newLocale) => {
|
|
1200
|
-
const
|
|
1201
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
882
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1202
883
|
route(pathWithLocale, true);
|
|
1203
884
|
},
|
|
1204
885
|
});
|
|
@@ -1209,7 +890,7 @@ const LocaleSwitcher = () => {
|
|
|
1209
890
|
<div id="localePopover" popover="auto">
|
|
1210
891
|
{availableLocales.map((localeItem) => (
|
|
1211
892
|
<a
|
|
1212
|
-
href={getLocalizedUrl(
|
|
893
|
+
href={getLocalizedUrl(url, localeItem)}
|
|
1213
894
|
hreflang={localeItem}
|
|
1214
895
|
aria-current={locale === localeItem ? "page" : undefined}
|
|
1215
896
|
onClick={(e) => {
|
|
@@ -1237,7 +918,7 @@ export default LocaleSwitcher;
|
|
|
1237
918
|
```
|
|
1238
919
|
|
|
1239
920
|
```jsx fileName="src/components/LocaleSwitcher.cjsx" codeFormat="commonjs"
|
|
1240
|
-
const { useLocation
|
|
921
|
+
const { useLocation } = require("preact-iso");
|
|
1241
922
|
const {
|
|
1242
923
|
Locales,
|
|
1243
924
|
getHTMLTextDir,
|
|
@@ -1245,45 +926,51 @@ const {
|
|
|
1245
926
|
getLocalizedUrl,
|
|
1246
927
|
} = require("intlayer");
|
|
1247
928
|
const { useLocale } = require("preact-intlayer");
|
|
1248
|
-
const { h } = require("preact"); // Pour JSX
|
|
1249
929
|
|
|
1250
930
|
const LocaleSwitcher = () => {
|
|
1251
|
-
const
|
|
931
|
+
const { url, route } = useLocation();
|
|
1252
932
|
const { locale, availableLocales, setLocale } = useLocale({
|
|
1253
933
|
onLocaleChange: (newLocale) => {
|
|
1254
|
-
const
|
|
1255
|
-
const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
|
|
934
|
+
const pathWithLocale = getLocalizedUrl(url, newLocale);
|
|
1256
935
|
route(pathWithLocale, true);
|
|
1257
936
|
},
|
|
1258
937
|
});
|
|
1259
938
|
|
|
1260
|
-
return (
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
939
|
+
return h(
|
|
940
|
+
"div",
|
|
941
|
+
{},
|
|
942
|
+
h("button", { popovertarget: "localePopover" }, getLocaleName(locale)),
|
|
943
|
+
h(
|
|
944
|
+
"div",
|
|
945
|
+
{ id: "localePopover", popover: "auto" },
|
|
946
|
+
availableLocales.map((localeItem) =>
|
|
947
|
+
h(
|
|
948
|
+
"a",
|
|
949
|
+
{
|
|
950
|
+
href: getLocalizedUrl(url, localeItem),
|
|
951
|
+
hreflang: localeItem,
|
|
952
|
+
"aria-current": locale === localeItem ? "page" : undefined,
|
|
953
|
+
onClick: (e) => {
|
|
1270
954
|
e.preventDefault();
|
|
1271
955
|
setLocale(localeItem);
|
|
1272
|
-
}
|
|
1273
|
-
key
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
956
|
+
},
|
|
957
|
+
key: localeItem,
|
|
958
|
+
},
|
|
959
|
+
h("span", {}, localeItem),
|
|
960
|
+
h("span", {}, getLocaleName(localeItem, localeItem)),
|
|
961
|
+
h(
|
|
962
|
+
"span",
|
|
963
|
+
{ dir: getHTMLTextDir(localeItem), lang: localeItem },
|
|
964
|
+
getLocaleName(localeItem, locale)
|
|
965
|
+
),
|
|
966
|
+
h(
|
|
967
|
+
"span",
|
|
968
|
+
{ dir: "ltr", lang: Locales.ENGLISH },
|
|
969
|
+
getLocaleName(localeItem, Locales.ENGLISH)
|
|
970
|
+
)
|
|
971
|
+
)
|
|
972
|
+
)
|
|
973
|
+
)
|
|
1287
974
|
);
|
|
1288
975
|
};
|
|
1289
976
|
|
|
@@ -1292,25 +979,21 @@ module.exports = LocaleSwitcher;
|
|
|
1292
979
|
|
|
1293
980
|
> Références de la documentation :
|
|
1294
981
|
>
|
|
1295
|
-
> > - [
|
|
1296
|
-
|
|
1297
|
-
Voici la mise à jour de l’**Étape 9** avec des explications supplémentaires et des exemples de code affinés :
|
|
1298
|
-
|
|
1299
|
-
---
|
|
982
|
+
> > - [Hook `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/packages/react-intlayer/useLocale.md) (l'API est similaire pour `preact-intlayer`)> - [Hook `getLocaleName`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/packages/intlayer/getLocaleName.md)> - [Hook `getLocalizedUrl`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/packages/intlayer/getLocalizedUrl.md)> - [Hook `getHTMLTextDir`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/packages/intlayer/getHTMLTextDir.md)> - [Attribut `hreflang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [Attribut `lang`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/lang)> - [Attribut `dir`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/dir)> - [Attribut `aria-current`](https://developer.mozilla.org/fr/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [API Popover](https://developer.mozilla.org/fr/docs/Web/API/Popover_API)
|
|
1300
983
|
|
|
1301
984
|
### (Optionnel) Étape 9 : Modifier les attributs de langue et de direction du HTML
|
|
1302
985
|
|
|
1303
|
-
Lorsque votre application prend en charge plusieurs langues, il est crucial de mettre à jour les attributs `lang` et `dir` de la balise `<html>` pour qu
|
|
986
|
+
Lorsque votre application prend en charge plusieurs langues, il est crucial de mettre à jour les attributs `lang` et `dir` de la balise `<html>` pour qu'ils correspondent à la langue actuelle. Cela garantit :
|
|
1304
987
|
|
|
1305
|
-
- **Accessibilité** : Les lecteurs d
|
|
1306
|
-
- **Rendu du texte** : L
|
|
1307
|
-
- **SEO** : Les moteurs de recherche utilisent l'attribut `lang` pour déterminer la langue de votre page, ce qui
|
|
988
|
+
- **Accessibilité** : Les lecteurs d'écran et les technologies d'assistance s'appuient sur l'attribut `lang` correct pour prononcer et interpréter le contenu avec précision.
|
|
989
|
+
- **Rendu du texte** : L'attribut `dir` (direction) garantit que le texte est rendu dans le bon ordre (par exemple, de gauche à droite pour l'anglais, de droite à gauche pour l'arabe ou l'hébreu), ce qui est essentiel pour la lisibilité.
|
|
990
|
+
- **SEO** : Les moteurs de recherche utilisent l'attribut `lang` pour déterminer la langue de votre page, ce qui aide à servir le bon contenu localisé dans les résultats de recherche.
|
|
1308
991
|
|
|
1309
|
-
En mettant à jour ces attributs dynamiquement lorsque la
|
|
992
|
+
En mettant à jour ces attributs dynamiquement lorsque la langue change, vous garantissez une expérience cohérente et accessible pour les utilisateurs dans toutes les langues prises en charge.
|
|
1310
993
|
|
|
1311
994
|
#### Implémentation du Hook
|
|
1312
995
|
|
|
1313
|
-
Créez un hook personnalisé pour gérer les attributs HTML.
|
|
996
|
+
Créez un hook personnalisé pour gérer les attributs HTML. Le hook écoute les changements de langue et met à jour les attributs en conséquence :
|
|
1314
997
|
|
|
1315
998
|
```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
|
|
1316
999
|
import { useEffect } from "preact/hooks";
|
|
@@ -1318,20 +1001,20 @@ import { useLocale } from "preact-intlayer";
|
|
|
1318
1001
|
import { getHTMLTextDir } from "intlayer";
|
|
1319
1002
|
|
|
1320
1003
|
/**
|
|
1321
|
-
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la
|
|
1004
|
+
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la langue actuelle.
|
|
1322
1005
|
* - `lang` : Informe les navigateurs et les moteurs de recherche de la langue de la page.
|
|
1323
1006
|
* - `dir` : Assure l'ordre de lecture correct (par exemple, 'ltr' pour l'anglais, 'rtl' pour l'arabe).
|
|
1324
1007
|
*
|
|
1325
|
-
* Cette mise à jour dynamique est essentielle pour
|
|
1008
|
+
* Cette mise à jour dynamique est essentielle pour le rendu correct du texte, l'accessibilité et le SEO.
|
|
1326
1009
|
*/
|
|
1327
1010
|
export const useI18nHTMLAttributes = () => {
|
|
1328
1011
|
const { locale } = useLocale();
|
|
1329
1012
|
|
|
1330
1013
|
useEffect(() => {
|
|
1331
|
-
//
|
|
1014
|
+
// Mettre à jour l'attribut de langue avec la langue actuelle.
|
|
1332
1015
|
document.documentElement.lang = locale;
|
|
1333
1016
|
|
|
1334
|
-
//
|
|
1017
|
+
// Définir la direction du texte en fonction de la langue actuelle.
|
|
1335
1018
|
document.documentElement.dir = getHTMLTextDir(locale);
|
|
1336
1019
|
}, [locale]);
|
|
1337
1020
|
};
|
|
@@ -1343,7 +1026,7 @@ import { useLocale } from "preact-intlayer";
|
|
|
1343
1026
|
import { getHTMLTextDir } from "intlayer";
|
|
1344
1027
|
|
|
1345
1028
|
/**
|
|
1346
|
-
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la
|
|
1029
|
+
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la langue actuelle.
|
|
1347
1030
|
*/
|
|
1348
1031
|
export const useI18nHTMLAttributes = () => {
|
|
1349
1032
|
const { locale } = useLocale();
|
|
@@ -1361,7 +1044,7 @@ const { useLocale } = require("preact-intlayer");
|
|
|
1361
1044
|
const { getHTMLTextDir } = require("intlayer");
|
|
1362
1045
|
|
|
1363
1046
|
/**
|
|
1364
|
-
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la
|
|
1047
|
+
* Met à jour les attributs `lang` et `dir` de l'élément HTML <html> en fonction de la langue actuelle.
|
|
1365
1048
|
*/
|
|
1366
1049
|
const useI18nHTMLAttributes = () => {
|
|
1367
1050
|
const { locale } = useLocale();
|
|
@@ -1375,9 +1058,9 @@ const useI18nHTMLAttributes = () => {
|
|
|
1375
1058
|
module.exports = { useI18nHTMLAttributes };
|
|
1376
1059
|
```
|
|
1377
1060
|
|
|
1378
|
-
#### Utilisation du Hook dans
|
|
1061
|
+
#### Utilisation du Hook dans Votre Application
|
|
1379
1062
|
|
|
1380
|
-
Intégrez le hook dans votre composant principal afin que les attributs HTML
|
|
1063
|
+
Intégrez le hook dans votre composant principal afin que les attributs HTML se mettent à jour chaque fois que la langue change :
|
|
1381
1064
|
|
|
1382
1065
|
```tsx fileName="src/app.tsx" codeFormat="typescript"
|
|
1383
1066
|
import type { FunctionalComponent } from "preact";
|
|
@@ -1387,10 +1070,10 @@ import "./app.css";
|
|
|
1387
1070
|
// Définition de AppContent depuis l'étape 5
|
|
1388
1071
|
|
|
1389
1072
|
const AppWithHooks: FunctionalComponent = () => {
|
|
1390
|
-
// Appliquer le hook pour mettre à jour les attributs lang et dir de la balise <html> en fonction de la
|
|
1073
|
+
// Appliquer le hook pour mettre à jour les attributs lang et dir de la balise <html> en fonction de la langue.
|
|
1391
1074
|
useI18nHTMLAttributes();
|
|
1392
1075
|
|
|
1393
|
-
// En supposant que AppContent est votre composant principal d'affichage
|
|
1076
|
+
// En supposant que AppContent est votre composant principal d'affichage de contenu de l'étape 5
|
|
1394
1077
|
return <AppContent />;
|
|
1395
1078
|
};
|
|
1396
1079
|
|
|
@@ -1407,7 +1090,7 @@ export default App;
|
|
|
1407
1090
|
import { IntlayerProvider } from "preact-intlayer";
|
|
1408
1091
|
import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
|
|
1409
1092
|
import "./app.css";
|
|
1410
|
-
// Définition de AppContent depuis l'
|
|
1093
|
+
// Définition de AppContent depuis l'étape 5
|
|
1411
1094
|
|
|
1412
1095
|
const AppWithHooks = () => {
|
|
1413
1096
|
useI18nHTMLAttributes();
|
|
@@ -1427,7 +1110,7 @@ export default App;
|
|
|
1427
1110
|
const { IntlayerProvider } = require("preact-intlayer");
|
|
1428
1111
|
const { useI18nHTMLAttributes } = require("./hooks/useI18nHTMLAttributes");
|
|
1429
1112
|
require("./app.css");
|
|
1430
|
-
// Définition de AppContent depuis l'
|
|
1113
|
+
// Définition de AppContent depuis l'étape 5
|
|
1431
1114
|
|
|
1432
1115
|
const AppWithHooks = () => {
|
|
1433
1116
|
useI18nHTMLAttributes();
|
|
@@ -1443,209 +1126,186 @@ const App = () => (
|
|
|
1443
1126
|
module.exports = App;
|
|
1444
1127
|
```
|
|
1445
1128
|
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
- Assurer que l'attribut **langue** (`lang`) reflète correctement la locale actuelle, ce qui est important pour le SEO et le comportement du navigateur.
|
|
1449
|
-
- Ajuster la **direction du texte** (`dir`) en fonction de la locale, améliorant la lisibilité et l'utilisabilité pour les langues avec des ordres de lecture différents.
|
|
1450
|
-
- Offrir une expérience plus **accessible**, car les technologies d'assistance dépendent de ces attributs pour fonctionner de manière optimale.
|
|
1129
|
+
### (Optionnel) Étape 10 : Création d'un Composant de Lien Localisé
|
|
1451
1130
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
Pour garantir que la navigation de votre application respecte la locale actuelle, vous pouvez créer un composant `Link` personnalisé. Ce composant préfixe automatiquement les URL internes avec la langue courante.
|
|
1131
|
+
Pour s'assurer que la navigation de votre application respecte la langue actuelle, vous pouvez créer un composant `Link` personnalisé. Ce composant préfixe automatiquement les URL internes avec la langue actuelle.
|
|
1455
1132
|
|
|
1456
1133
|
Ce comportement est utile pour plusieurs raisons :
|
|
1457
1134
|
|
|
1458
|
-
- **SEO et
|
|
1459
|
-
- **Cohérence** : En utilisant un lien localisé dans toute votre application, vous garantissez que la navigation reste dans la
|
|
1460
|
-
- **Maintenabilité** : Centraliser la logique de localisation dans un seul composant simplifie la gestion des
|
|
1135
|
+
- **SEO et Expérience Utilisateur** : Les URL localisées aident les moteurs de recherche à indexer correctement les pages spécifiques à une langue et fournissent aux utilisateurs du contenu dans leur langue préférée.
|
|
1136
|
+
- **Cohérence** : En utilisant un lien localisé dans toute votre application, vous garantissez que la navigation reste dans la langue actuelle, évitant ainsi des changements de langue inattendus.
|
|
1137
|
+
- **Maintenabilité** : Centraliser la logique de localisation dans un seul composant simplifie la gestion des URL.
|
|
1461
1138
|
|
|
1462
|
-
|
|
1139
|
+
Voici l'implémentation d'un composant `Link` localisé dans Preact :
|
|
1463
1140
|
|
|
1464
|
-
```tsx fileName="src/components/
|
|
1141
|
+
```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
|
|
1465
1142
|
import { getLocalizedUrl } from "intlayer";
|
|
1466
|
-
import { useLocale
|
|
1467
|
-
|
|
1468
|
-
import type { JSX } from "preact";
|
|
1469
|
-
import { forwardRef } from "preact/compat"; // Pour le passage des refs
|
|
1143
|
+
import { useLocale } from "preact-intlayer";
|
|
1144
|
+
import { forwardRef } from "preact/compat";
|
|
1145
|
+
import type { JSX } from "preact";
|
|
1470
1146
|
|
|
1471
|
-
export interface
|
|
1147
|
+
export interface LinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
|
|
1472
1148
|
href: string;
|
|
1473
|
-
replace?: boolean; // Optionnel : pour remplacer l'état de l'historique
|
|
1474
1149
|
}
|
|
1475
1150
|
|
|
1476
1151
|
/**
|
|
1477
1152
|
* Fonction utilitaire pour vérifier si une URL donnée est externe.
|
|
1478
|
-
* Si l'URL commence par http://
|
|
1153
|
+
* Si l'URL commence par http:// or https://, elle est considérée comme externe.
|
|
1479
1154
|
*/
|
|
1480
1155
|
export const checkIsExternalLink = (href?: string): boolean =>
|
|
1481
1156
|
/^https?:\/\//.test(href ?? "");
|
|
1482
1157
|
|
|
1483
1158
|
/**
|
|
1484
|
-
* Un composant Link personnalisé qui adapte l'attribut href en fonction de la
|
|
1485
|
-
* Pour les liens internes, il utilise `getLocalizedUrl` pour préfixer l'URL avec la
|
|
1486
|
-
* Cela garantit que la navigation reste dans le même contexte de
|
|
1487
|
-
* Il utilise une balise <a> standard mais peut déclencher une navigation côté client en utilisant `route` de preact-iso.
|
|
1159
|
+
* Un composant Link personnalisé qui adapte l'attribut href en fonction de la langue actuelle.
|
|
1160
|
+
* Pour les liens internes, il utilise `getLocalizedUrl` pour préfixer l'URL avec la langue (ex: /fr/about).
|
|
1161
|
+
* Cela garantit que la navigation reste dans le même contexte de langue.
|
|
1488
1162
|
*/
|
|
1489
|
-
export const
|
|
1490
|
-
({ href, children,
|
|
1163
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
1164
|
+
({ href, children, ...props }, ref) => {
|
|
1491
1165
|
const { locale } = useLocale();
|
|
1492
|
-
const location = useLocation(); // depuis preact-iso
|
|
1493
1166
|
const isExternalLink = checkIsExternalLink(href);
|
|
1494
1167
|
|
|
1168
|
+
// Si le lien est interne et qu'un href valide est fourni, obtenir l'URL localisée.
|
|
1495
1169
|
const hrefI18n =
|
|
1496
1170
|
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1497
1171
|
|
|
1498
|
-
const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
|
|
1499
|
-
if (onClick) {
|
|
1500
|
-
onClick(event);
|
|
1501
|
-
}
|
|
1502
|
-
if (
|
|
1503
|
-
!isExternalLink &&
|
|
1504
|
-
href && // Assurer que href est défini
|
|
1505
|
-
event.button === 0 && // Clic gauche
|
|
1506
|
-
!event.metaKey &&
|
|
1507
|
-
!event.ctrlKey &&
|
|
1508
|
-
!event.shiftKey &&
|
|
1509
|
-
!event.altKey && // Vérification des modificateurs standards
|
|
1510
|
-
!props.target // Ne cible pas un nouvel onglet/fenêtre
|
|
1511
|
-
) {
|
|
1512
|
-
event.preventDefault();
|
|
1513
|
-
if (location.url !== hrefI18n) {
|
|
1514
|
-
// Naviguer uniquement si l'URL est différente
|
|
1515
|
-
route(hrefI18n, replace); // Utiliser la route de preact-iso
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
};
|
|
1519
|
-
|
|
1520
1172
|
return (
|
|
1521
|
-
<a href={hrefI18n} ref={ref}
|
|
1173
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1522
1174
|
{children}
|
|
1523
1175
|
</a>
|
|
1524
1176
|
);
|
|
1525
1177
|
}
|
|
1526
1178
|
);
|
|
1179
|
+
|
|
1180
|
+
Link.displayName = "Link";
|
|
1527
1181
|
```
|
|
1528
1182
|
|
|
1529
|
-
```jsx fileName="src/components/
|
|
1183
|
+
```jsx fileName="src/components/Link.jsx" codeFormat="esm"
|
|
1530
1184
|
import { getLocalizedUrl } from "intlayer";
|
|
1531
1185
|
import { useLocale } from "preact-intlayer";
|
|
1532
|
-
import { useLocation, route } from "preact-iso"; // Import depuis preact-iso
|
|
1533
1186
|
import { forwardRef } from "preact/compat";
|
|
1534
|
-
import { h } from "preact"; // Pour JSX
|
|
1535
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Fonction utilitaire pour vérifier si une URL donnée est externe.
|
|
1190
|
+
* Si l'URL commence par http:// or https://, elle est considérée comme externe.
|
|
1191
|
+
*/
|
|
1536
1192
|
export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1537
1193
|
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1194
|
+
/**
|
|
1195
|
+
* Un composant Link personnalisé qui adapte l'attribut href en fonction de la langue actuelle.
|
|
1196
|
+
* Pour les liens internes, il utilise `getLocalizedUrl` pour préfixer l'URL avec la langue (ex: /fr/about).
|
|
1197
|
+
* Cela garantit que la navigation reste dans le même contexte de langue.
|
|
1198
|
+
*/
|
|
1199
|
+
export const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1200
|
+
const { locale } = useLocale();
|
|
1201
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1543
1202
|
|
|
1544
|
-
|
|
1545
|
-
|
|
1203
|
+
// Si le lien est interne et qu'un href valide est fourni, obtenir l'URL localisée.
|
|
1204
|
+
const hrefI18n =
|
|
1205
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1546
1206
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
href &&
|
|
1554
|
-
event.button === 0 &&
|
|
1555
|
-
!event.metaKey &&
|
|
1556
|
-
!event.ctrlKey &&
|
|
1557
|
-
!event.shiftKey &&
|
|
1558
|
-
!event.altKey &&
|
|
1559
|
-
!props.target
|
|
1560
|
-
) {
|
|
1561
|
-
event.preventDefault();
|
|
1562
|
-
if (location.url !== hrefI18n) {
|
|
1563
|
-
route(hrefI18n, replace);
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
};
|
|
1207
|
+
return (
|
|
1208
|
+
<a href={hrefI18n} ref={ref} {...props}>
|
|
1209
|
+
{children}
|
|
1210
|
+
</a>
|
|
1211
|
+
);
|
|
1212
|
+
});
|
|
1567
1213
|
|
|
1568
|
-
|
|
1569
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1570
|
-
{children}
|
|
1571
|
-
</a>
|
|
1572
|
-
);
|
|
1573
|
-
}
|
|
1574
|
-
);
|
|
1214
|
+
Link.displayName = "Link";
|
|
1575
1215
|
```
|
|
1576
1216
|
|
|
1577
|
-
```jsx fileName="src/components/
|
|
1217
|
+
```jsx fileName="src/components/Link.cjsx" codeFormat="commonjs"
|
|
1578
1218
|
const { getLocalizedUrl } = require("intlayer");
|
|
1579
1219
|
const { useLocale } = require("preact-intlayer");
|
|
1580
|
-
const { useLocation, route } = require("preact-iso"); // Import depuis preact-iso
|
|
1581
1220
|
const { forwardRef } = require("preact/compat");
|
|
1582
|
-
const { h } = require("preact"); // Pour JSX
|
|
1583
1221
|
|
|
1222
|
+
/**
|
|
1223
|
+
* Fonction utilitaire pour vérifier si une URL donnée est externe.
|
|
1224
|
+
* Si l'URL commence par http:// or https://, elle est considérée comme externe.
|
|
1225
|
+
*/
|
|
1584
1226
|
const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
|
|
1585
1227
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
!props.target
|
|
1610
|
-
) {
|
|
1611
|
-
event.preventDefault();
|
|
1612
|
-
if (location.url !== hrefI18n) {
|
|
1613
|
-
route(hrefI18n, replace);
|
|
1614
|
-
}
|
|
1615
|
-
}
|
|
1616
|
-
};
|
|
1228
|
+
/**
|
|
1229
|
+
* Un composant Link personnalisé qui adapte l'attribut href en fonction de la langue actuelle.
|
|
1230
|
+
* Pour les liens internes, il utilise `getLocalizedUrl` pour préfixer l'URL avec la langue (ex: /fr/about).
|
|
1231
|
+
* Cela garantit que la navigation reste dans le même contexte de langue.
|
|
1232
|
+
*/
|
|
1233
|
+
const Link = forwardRef(({ href, children, ...props }, ref) => {
|
|
1234
|
+
const { locale } = useLocale();
|
|
1235
|
+
const isExternalLink = checkIsExternalLink(href);
|
|
1236
|
+
|
|
1237
|
+
// Si le lien est interne et qu'un href valide est fourni, obtenir l'URL localisée.
|
|
1238
|
+
const hrefI18n =
|
|
1239
|
+
href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
|
|
1240
|
+
|
|
1241
|
+
return h(
|
|
1242
|
+
"a",
|
|
1243
|
+
{
|
|
1244
|
+
href: hrefI18n,
|
|
1245
|
+
ref: ref,
|
|
1246
|
+
...props,
|
|
1247
|
+
},
|
|
1248
|
+
children
|
|
1249
|
+
);
|
|
1250
|
+
});
|
|
1617
1251
|
|
|
1618
|
-
|
|
1619
|
-
<a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
|
|
1620
|
-
{children}
|
|
1621
|
-
</a>
|
|
1622
|
-
);
|
|
1623
|
-
}
|
|
1624
|
-
);
|
|
1252
|
+
Link.displayName = "Link";
|
|
1625
1253
|
|
|
1626
|
-
module.exports = {
|
|
1254
|
+
module.exports = { Link, checkIsExternalLink };
|
|
1627
1255
|
```
|
|
1628
1256
|
|
|
1629
1257
|
#### Comment ça fonctionne
|
|
1630
1258
|
|
|
1631
|
-
- **Détection des
|
|
1632
|
-
La fonction utilitaire `checkIsExternalLink` détermine si une URL est externe. Les liens externes
|
|
1633
|
-
- **Récupération de la
|
|
1634
|
-
Le hook `useLocale` fournit la
|
|
1259
|
+
- **Détection des Liens Externes** :
|
|
1260
|
+
La fonction utilitaire `checkIsExternalLink` détermine si une URL est externe. Les liens externes sont laissés inchangés car ils n'ont pas besoin de localisation.
|
|
1261
|
+
- **Récupération de la Langue Actuelle** :
|
|
1262
|
+
Le hook `useLocale` fournit la langue actuelle (ex : `fr` pour le français).
|
|
1635
1263
|
- **Localisation de l'URL** :
|
|
1636
|
-
Pour les liens internes, `getLocalizedUrl`
|
|
1637
|
-
- **
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1264
|
+
Pour les liens internes (c'est-à-dire non externes), `getLocalizedUrl` est utilisé pour préfixer automatiquement l'URL avec la langue actuelle. Cela signifie que si votre utilisateur est en français, passer `/about` comme `href` le transformera en `/fr/about`.
|
|
1265
|
+
- **Retour du Lien** :
|
|
1266
|
+
Le composant retourne un élément `<a>` avec l'URL localisée, garantissant que la navigation est cohérente avec la langue.
|
|
1267
|
+
|
|
1268
|
+
### (Optionnel) Étape 11 : Rendre le Markdown et l'HTML
|
|
1269
|
+
|
|
1270
|
+
Intlayer prend en charge le rendu du contenu Markdown et HTML dans Preact.
|
|
1271
|
+
|
|
1272
|
+
Vous pouvez personnaliser le rendu du contenu Markdown et HTML en utilisant la méthode `.use()`. Cette méthode vous permet de surcharger le rendu par défaut de balises spécifiques.
|
|
1273
|
+
|
|
1274
|
+
```tsx
|
|
1275
|
+
import { useIntlayer } from "preact-intlayer";
|
|
1276
|
+
|
|
1277
|
+
const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
|
|
1278
|
+
|
|
1279
|
+
// ...
|
|
1280
|
+
|
|
1281
|
+
return (
|
|
1282
|
+
<div>
|
|
1283
|
+
{/* Rendu de base */}
|
|
1284
|
+
{myMarkdownContent}
|
|
1285
|
+
|
|
1286
|
+
{/* Rendu personnalisé pour le Markdown */}
|
|
1287
|
+
{myMarkdownContent.use({
|
|
1288
|
+
h1: (props) => <h1 style={{ color: "red" }} {...props} />,
|
|
1289
|
+
})}
|
|
1290
|
+
|
|
1291
|
+
{/* Rendu de base pour l'HTML */}
|
|
1292
|
+
{myHtmlContent}
|
|
1293
|
+
|
|
1294
|
+
{/* Rendu personnalisé pour l'HTML */}
|
|
1295
|
+
{myHtmlContent.use({
|
|
1296
|
+
b: (props) => <strong style={{ color: "blue" }} {...props} />,
|
|
1297
|
+
})}
|
|
1298
|
+
</div>
|
|
1299
|
+
);
|
|
1300
|
+
```
|
|
1641
1301
|
|
|
1642
1302
|
### Configurer TypeScript
|
|
1643
1303
|
|
|
1644
1304
|
Intlayer utilise l'augmentation de module pour tirer parti de TypeScript et renforcer votre base de code.
|
|
1645
1305
|
|
|
1646
|
-

|
|
1647
1307
|
|
|
1648
|
-

|
|
1649
1309
|
|
|
1650
1310
|
Assurez-vous que votre configuration TypeScript inclut les types générés automatiquement.
|
|
1651
1311
|
|
|
@@ -1680,23 +1340,23 @@ Pour ce faire, vous pouvez ajouter les instructions suivantes à votre fichier `
|
|
|
1680
1340
|
|
|
1681
1341
|
### Extension VS Code
|
|
1682
1342
|
|
|
1683
|
-
Pour améliorer votre expérience de développement avec Intlayer, vous pouvez installer l
|
|
1343
|
+
Pour améliorer votre expérience de développement avec Intlayer, vous pouvez installer l'**extension officielle Intlayer pour VS Code**.
|
|
1684
1344
|
|
|
1685
1345
|
[Installer depuis le Marketplace VS Code](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
|
|
1686
1346
|
|
|
1687
1347
|
Cette extension offre :
|
|
1688
1348
|
|
|
1689
1349
|
- **Autocomplétion** pour les clés de traduction.
|
|
1690
|
-
- **Détection d
|
|
1350
|
+
- **Détection d'erreurs en temps réel** pour les traductions manquantes.
|
|
1691
1351
|
- **Aperçus en ligne** du contenu traduit.
|
|
1692
1352
|
- **Actions rapides** pour créer et mettre à jour facilement les traductions.
|
|
1693
1353
|
|
|
1694
|
-
Pour plus de détails sur l
|
|
1354
|
+
Pour plus de détails sur l'utilisation de l'extension, consultez la [documentation de l'extension Intlayer pour VS Code](https://intlayer.org/doc/vs-code-extension).
|
|
1695
1355
|
|
|
1696
1356
|
---
|
|
1697
1357
|
|
|
1698
1358
|
### Aller plus loin
|
|
1699
1359
|
|
|
1700
|
-
Pour aller plus loin, vous pouvez implémenter l
|
|
1360
|
+
Pour aller plus loin, vous pouvez implémenter l'[éditeur visuel](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_visual_editor.md) ou externaliser votre contenu en utilisant le [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_CMS.md).
|
|
1701
1361
|
|
|
1702
1362
|
---
|