@intlayer/docs 7.3.15 → 7.5.0-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/blog/ar/intlayer_with_i18next.md +2 -0
- package/blog/ar/intlayer_with_next-i18next.md +2 -0
- package/blog/ar/intlayer_with_next-intl.md +2 -0
- package/blog/ar/intlayer_with_react-i18next.md +2 -0
- package/blog/ar/intlayer_with_react-intl.md +2 -0
- package/blog/ar/intlayer_with_vue-i18n.md +2 -0
- package/blog/de/intlayer_with_i18next.md +2 -0
- package/blog/de/intlayer_with_next-i18next.md +1 -0
- package/blog/de/intlayer_with_next-intl.md +2 -0
- package/blog/de/intlayer_with_react-i18next.md +2 -0
- package/blog/de/intlayer_with_react-intl.md +2 -0
- package/blog/de/intlayer_with_vue-i18n.md +2 -0
- package/blog/en/intlayer_with_i18next.md +6 -0
- package/blog/en/intlayer_with_next-i18next.md +3 -0
- package/blog/en/intlayer_with_next-intl.md +3 -0
- package/blog/en/intlayer_with_react-i18next.md +3 -0
- package/blog/en/intlayer_with_react-intl.md +3 -0
- package/blog/en/intlayer_with_vue-i18n.md +3 -0
- package/blog/en-GB/intlayer_with_i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_next-intl.md +2 -0
- package/blog/en-GB/intlayer_with_react-i18next.md +2 -0
- package/blog/en-GB/intlayer_with_react-intl.md +2 -0
- package/blog/en-GB/intlayer_with_vue-i18n.md +2 -0
- package/blog/es/intlayer_with_i18next.md +2 -0
- package/blog/es/intlayer_with_next-i18next.md +2 -0
- package/blog/es/intlayer_with_next-intl.md +2 -0
- package/blog/es/intlayer_with_react-i18next.md +2 -0
- package/blog/es/intlayer_with_react-intl.md +2 -0
- package/blog/es/intlayer_with_vue-i18n.md +2 -0
- package/blog/fr/intlayer_with_i18next.md +2 -0
- package/blog/fr/intlayer_with_next-i18next.md +2 -0
- package/blog/fr/intlayer_with_next-intl.md +2 -0
- package/blog/fr/intlayer_with_react-i18next.md +2 -0
- package/blog/fr/intlayer_with_react-intl.md +2 -0
- package/blog/fr/intlayer_with_vue-i18n.md +2 -0
- package/blog/hi/intlayer_with_i18next.md +2 -0
- package/blog/hi/intlayer_with_next-i18next.md +2 -0
- package/blog/hi/intlayer_with_next-intl.md +2 -0
- package/blog/hi/intlayer_with_react-i18next.md +2 -0
- package/blog/hi/intlayer_with_react-intl.md +2 -0
- package/blog/hi/intlayer_with_vue-i18n.md +2 -0
- package/blog/id/intlayer_with_i18next.md +2 -0
- package/blog/id/intlayer_with_next-i18next.md +2 -0
- package/blog/id/intlayer_with_next-intl.md +2 -0
- package/blog/id/intlayer_with_react-i18next.md +2 -0
- package/blog/id/intlayer_with_react-intl.md +2 -0
- package/blog/id/intlayer_with_vue-i18n.md +2 -0
- package/blog/it/intlayer_with_i18next.md +2 -0
- package/blog/it/intlayer_with_next-i18next.md +2 -0
- package/blog/it/intlayer_with_next-intl.md +2 -0
- package/blog/it/intlayer_with_react-i18next.md +2 -0
- package/blog/it/intlayer_with_react-intl.md +2 -0
- package/blog/it/intlayer_with_vue-i18n.md +2 -0
- package/blog/ja/intlayer_with_i18next.md +2 -0
- package/blog/ja/intlayer_with_next-i18next.md +1 -0
- package/blog/ja/intlayer_with_next-intl.md +2 -0
- package/blog/ja/intlayer_with_react-i18next.md +2 -0
- package/blog/ja/intlayer_with_react-intl.md +2 -0
- package/blog/ja/intlayer_with_vue-i18n.md +2 -0
- package/blog/ko/intlayer_with_i18next.md +2 -0
- package/blog/ko/intlayer_with_next-i18next.md +2 -0
- package/blog/ko/intlayer_with_next-intl.md +2 -0
- package/blog/ko/intlayer_with_react-i18next.md +2 -0
- package/blog/ko/intlayer_with_react-intl.md +2 -0
- package/blog/ko/intlayer_with_vue-i18n.md +2 -0
- package/blog/pl/intlayer_with_i18next.md +2 -0
- package/blog/pl/intlayer_with_next-i18next.md +2 -0
- package/blog/pl/intlayer_with_next-intl.md +2 -0
- package/blog/pl/intlayer_with_react-i18next.md +2 -0
- package/blog/pl/intlayer_with_react-intl.md +2 -0
- package/blog/pl/intlayer_with_vue-i18n.md +2 -0
- package/blog/pt/intlayer_with_i18next.md +2 -0
- package/blog/pt/intlayer_with_next-i18next.md +2 -0
- package/blog/pt/intlayer_with_next-intl.md +2 -0
- package/blog/pt/intlayer_with_react-i18next.md +2 -0
- package/blog/pt/intlayer_with_react-intl.md +2 -0
- package/blog/pt/intlayer_with_vue-i18n.md +2 -0
- package/blog/ru/intlayer_with_i18next.md +2 -0
- package/blog/ru/intlayer_with_next-i18next.md +2 -0
- package/blog/ru/intlayer_with_next-intl.md +2 -0
- package/blog/ru/intlayer_with_react-i18next.md +2 -0
- package/blog/ru/intlayer_with_react-intl.md +2 -0
- package/blog/ru/intlayer_with_vue-i18n.md +2 -0
- package/blog/tr/intlayer_with_i18next.md +2 -0
- package/blog/tr/intlayer_with_next-i18next.md +2 -0
- package/blog/tr/intlayer_with_next-intl.md +2 -0
- package/blog/tr/intlayer_with_react-i18next.md +2 -0
- package/blog/tr/intlayer_with_react-intl.md +2 -0
- package/blog/tr/intlayer_with_vue-i18n.md +2 -0
- package/blog/vi/intlayer_with_i18next.md +2 -0
- package/blog/vi/intlayer_with_next-i18next.md +2 -0
- package/blog/vi/intlayer_with_next-intl.md +2 -0
- package/blog/vi/intlayer_with_react-i18next.md +2 -0
- package/blog/vi/intlayer_with_react-intl.md +2 -0
- package/blog/vi/intlayer_with_vue-i18n.md +2 -0
- package/blog/zh/intlayer_with_i18next.md +2 -0
- package/blog/zh/intlayer_with_next-i18next.md +2 -0
- package/blog/zh/intlayer_with_next-intl.md +2 -0
- package/blog/zh/intlayer_with_react-i18next.md +2 -0
- package/blog/zh/intlayer_with_react-intl.md +2 -0
- package/blog/zh/intlayer_with_vue-i18n.md +2 -0
- package/docs/ar/dictionary/content_file.md +24 -1
- package/docs/ar/intlayer_with_astro.md +1 -1
- package/docs/ar/intlayer_with_express.md +1 -1
- package/docs/ar/intlayer_with_nestjs.md +1 -1
- package/docs/ar/intlayer_with_next-i18next.md +1 -0
- package/docs/ar/intlayer_with_next-intl.md +1 -0
- package/docs/ar/intlayer_with_tanstack.md +122 -3
- package/docs/ar/plugins/sync-json.md +27 -2
- package/docs/de/dictionary/content_file.md +24 -1
- package/docs/de/intlayer_with_astro.md +1 -1
- package/docs/de/intlayer_with_express.md +1 -1
- package/docs/de/intlayer_with_nestjs.md +1 -1
- package/docs/de/intlayer_with_next-i18next.md +1 -0
- package/docs/de/intlayer_with_next-intl.md +1 -0
- package/docs/de/intlayer_with_tanstack.md +122 -3
- package/docs/de/plugins/sync-json.md +27 -2
- package/docs/en/dictionary/content_file.md +24 -1
- package/docs/en/intlayer_with_astro.md +1 -1
- package/docs/en/intlayer_with_express.md +1 -1
- package/docs/en/intlayer_with_nestjs.md +1 -2
- package/docs/en/intlayer_with_next-i18next.md +1 -0
- package/docs/en/intlayer_with_next-intl.md +1 -0
- package/docs/en/intlayer_with_tanstack.md +120 -1
- package/docs/en/plugins/sync-json.md +53 -2
- package/docs/en-GB/dictionary/content_file.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +1 -1
- package/docs/en-GB/intlayer_with_express.md +1 -1
- package/docs/en-GB/intlayer_with_nestjs.md +1 -1
- package/docs/en-GB/intlayer_with_next-i18next.md +1 -0
- package/docs/en-GB/intlayer_with_next-intl.md +1 -0
- package/docs/en-GB/intlayer_with_tanstack.md +121 -2
- package/docs/en-GB/plugins/sync-json.md +26 -1
- package/docs/es/dictionary/content_file.md +24 -1
- package/docs/es/intlayer_with_astro.md +1 -1
- package/docs/es/intlayer_with_express.md +1 -1
- package/docs/es/intlayer_with_nestjs.md +1 -1
- package/docs/es/intlayer_with_next-i18next.md +1 -0
- package/docs/es/intlayer_with_next-intl.md +1 -0
- package/docs/es/intlayer_with_tanstack.md +122 -3
- package/docs/es/plugins/sync-json.md +27 -2
- package/docs/fr/dictionary/content_file.md +24 -1
- package/docs/fr/intlayer_with_astro.md +1 -1
- package/docs/fr/intlayer_with_express.md +1 -1
- package/docs/fr/intlayer_with_nestjs.md +1 -1
- package/docs/fr/intlayer_with_next-i18next.md +1 -0
- package/docs/fr/intlayer_with_next-intl.md +1 -0
- package/docs/fr/intlayer_with_tanstack.md +122 -3
- package/docs/fr/plugins/sync-json.md +27 -2
- package/docs/hi/dictionary/content_file.md +24 -1
- package/docs/hi/intlayer_with_astro.md +1 -1
- package/docs/hi/intlayer_with_express.md +1 -1
- package/docs/hi/intlayer_with_nestjs.md +1 -1
- package/docs/hi/intlayer_with_next-i18next.md +1 -0
- package/docs/hi/intlayer_with_next-intl.md +1 -0
- package/docs/hi/intlayer_with_tanstack.md +122 -3
- package/docs/hi/plugins/sync-json.md +27 -2
- package/docs/id/dictionary/content_file.md +24 -1
- package/docs/id/intlayer_with_astro.md +1 -1
- package/docs/id/intlayer_with_express.md +1 -1
- package/docs/id/intlayer_with_nestjs.md +1 -1
- package/docs/id/intlayer_with_next-i18next.md +1 -0
- package/docs/id/intlayer_with_next-intl.md +1 -0
- package/docs/id/intlayer_with_tanstack.md +122 -3
- package/docs/id/plugins/sync-json.md +27 -2
- package/docs/it/dictionary/content_file.md +24 -1
- package/docs/it/intlayer_with_astro.md +1 -1
- package/docs/it/intlayer_with_express.md +1 -1
- package/docs/it/intlayer_with_nestjs.md +1 -1
- package/docs/it/intlayer_with_next-i18next.md +1 -0
- package/docs/it/intlayer_with_next-intl.md +1 -0
- package/docs/it/intlayer_with_tanstack.md +122 -3
- package/docs/it/plugins/sync-json.md +27 -2
- package/docs/ja/dictionary/content_file.md +24 -1
- package/docs/ja/intlayer_with_astro.md +1 -1
- package/docs/ja/intlayer_with_express.md +1 -1
- package/docs/ja/intlayer_with_nestjs.md +1 -1
- package/docs/ja/intlayer_with_next-i18next.md +1 -0
- package/docs/ja/intlayer_with_next-intl.md +1 -0
- package/docs/ja/intlayer_with_tanstack.md +122 -3
- package/docs/ja/plugins/sync-json.md +27 -2
- package/docs/ko/dictionary/content_file.md +44 -1
- package/docs/ko/intlayer_with_astro.md +1 -1
- package/docs/ko/intlayer_with_express.md +1 -1
- package/docs/ko/intlayer_with_nestjs.md +1 -1
- package/docs/ko/intlayer_with_next-i18next.md +1 -0
- package/docs/ko/intlayer_with_next-intl.md +1 -0
- package/docs/ko/intlayer_with_tanstack.md +122 -3
- package/docs/ko/plugins/sync-json.md +27 -2
- package/docs/pl/dictionary/content_file.md +24 -1
- package/docs/pl/intlayer_with_astro.md +2 -2
- package/docs/pl/intlayer_with_express.md +1 -1
- package/docs/pl/intlayer_with_nestjs.md +1 -1
- package/docs/pl/intlayer_with_next-i18next.md +1 -0
- package/docs/pl/intlayer_with_next-intl.md +1 -0
- package/docs/pl/intlayer_with_tanstack.md +122 -3
- package/docs/pl/plugins/sync-json.md +24 -2
- package/docs/pt/dictionary/content_file.md +24 -1
- package/docs/pt/intlayer_with_astro.md +1 -1
- package/docs/pt/intlayer_with_express.md +1 -1
- package/docs/pt/intlayer_with_nestjs.md +1 -1
- package/docs/pt/intlayer_with_next-i18next.md +1 -0
- package/docs/pt/intlayer_with_next-intl.md +1 -0
- package/docs/pt/intlayer_with_tanstack.md +122 -3
- package/docs/pt/plugins/sync-json.md +27 -2
- package/docs/ru/dictionary/content_file.md +44 -1
- package/docs/ru/intlayer_with_astro.md +1 -1
- package/docs/ru/intlayer_with_express.md +1 -1
- package/docs/ru/intlayer_with_nestjs.md +1 -1
- package/docs/ru/intlayer_with_next-i18next.md +1 -0
- package/docs/ru/intlayer_with_next-intl.md +1 -0
- package/docs/ru/intlayer_with_tanstack.md +122 -3
- package/docs/ru/plugins/sync-json.md +27 -2
- package/docs/tr/dictionary/content_file.md +44 -1
- package/docs/tr/intlayer_with_astro.md +1 -1
- package/docs/tr/intlayer_with_express.md +1 -1
- package/docs/tr/intlayer_with_next-i18next.md +1 -0
- package/docs/tr/intlayer_with_next-intl.md +1 -0
- package/docs/tr/intlayer_with_tanstack.md +122 -3
- package/docs/tr/plugins/sync-json.md +27 -2
- package/docs/vi/dictionary/content_file.md +24 -1
- package/docs/vi/intlayer_with_astro.md +1 -1
- package/docs/vi/intlayer_with_express.md +1 -1
- package/docs/vi/intlayer_with_nestjs.md +1 -1
- package/docs/vi/intlayer_with_next-i18next.md +1 -0
- package/docs/vi/intlayer_with_next-intl.md +1 -0
- package/docs/vi/intlayer_with_tanstack.md +122 -3
- package/docs/vi/plugins/sync-json.md +27 -2
- package/docs/zh/dictionary/content_file.md +44 -1
- package/docs/zh/intlayer_with_astro.md +1 -1
- package/docs/zh/intlayer_with_express.md +1 -1
- package/docs/zh/intlayer_with_nestjs.md +1 -1
- package/docs/zh/intlayer_with_next-i18next.md +1 -0
- package/docs/zh/intlayer_with_next-intl.md +1 -0
- package/docs/zh/intlayer_with_tanstack.md +122 -3
- package/docs/zh/plugins/sync-json.md +27 -2
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-11
|
|
4
4
|
title: Tanstack Start uygulamanızı nasıl çevirirsiniz – i18n rehberi 2025
|
|
5
5
|
description: Tanstack Start uygulamanıza Intlayer kullanarak uluslararasılaştırma (i18n) nasıl eklenir öğrenin. Uygulamanızı yerel dil yönlendirmesi ile çok dilli hale getirmek için bu kapsamlı rehberi takip edin.
|
|
6
6
|
keywords:
|
|
@@ -19,9 +19,12 @@ slugs:
|
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
21
|
history:
|
|
22
|
+
- version: 7.4.0
|
|
23
|
+
date: 2025-12-11
|
|
24
|
+
changes: validatePrefix'i tanıt ve 14. adımı ekle: Yerelleştirilmiş rotalarla 404 sayfalarını ele alma.
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
|
-
changes:
|
|
27
|
+
changes: 13. adımı ekle: Sunucu işlemlerinde locale bilgisini almak (Opsiyonel)
|
|
25
28
|
- version: 6.5.2
|
|
26
29
|
date: 2025-10-03
|
|
27
30
|
changes: Doküman güncellemesi
|
|
@@ -604,7 +607,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
604
607
|
|
|
605
608
|
---
|
|
606
609
|
|
|
607
|
-
### Adım 14:
|
|
610
|
+
### Adım 14: Bulunamayan sayfaları yönetme (İsteğe Bağlı)
|
|
611
|
+
|
|
612
|
+
Bir kullanıcı var olmayan bir sayfayı ziyaret ettiğinde, özel bir bulunamadı sayfası gösterebilirsiniz ve yerel ayar öneki, bulunamadı sayfasının tetiklenme şeklini etkileyebilir.
|
|
613
|
+
|
|
614
|
+
#### TanStack Router'ın Yerel Ayar Önekleriyle 404 İşlemesini Anlama
|
|
615
|
+
|
|
616
|
+
TanStack Router'da yerelleştirilmiş rotalarla 404 sayfalarını işlemek, çok katmanlı bir yaklaşım gerektirir:
|
|
617
|
+
|
|
618
|
+
1. **Özel 404 rotası**: 404 kullanıcı arayüzünü göstermek için özel bir rota
|
|
619
|
+
2. **Rota düzeyinde doğrulama**: Yerel ayar öneklerini doğrular ve geçersiz olanları 404'e yönlendirir
|
|
620
|
+
3. **Catch-all rotası**: Yerel ayar segmenti içindeki eşleşmeyen tüm yolları yakalar
|
|
621
|
+
|
|
622
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
623
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
624
|
+
|
|
625
|
+
// Bu, özel bir /[locale]/404 rotası oluşturur
|
|
626
|
+
// Hem doğrudan bir rota olarak kullanılır hem de diğer dosyalarda bir bileşen olarak içe aktarılır
|
|
627
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
628
|
+
component: NotFoundComponent,
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
// notFoundComponent ve catch-all rotalarında yeniden kullanılabilmesi için ayrı olarak dışa aktarılır
|
|
632
|
+
export function NotFoundComponent() {
|
|
633
|
+
return (
|
|
634
|
+
<div>
|
|
635
|
+
<h1>404</h1>
|
|
636
|
+
</div>
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
642
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
643
|
+
import { validatePrefix } from "intlayer";
|
|
644
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
645
|
+
|
|
646
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
647
|
+
import { NotFoundComponent } from "./404";
|
|
648
|
+
|
|
649
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
650
|
+
// beforeLoad, rota render edilmeden önce çalışır (hem sunucuda hem de istemcide)
|
|
651
|
+
// Yerel ayar önekini doğrulamak için ideal yerdir
|
|
652
|
+
beforeLoad: ({ params }) => {
|
|
653
|
+
// Yerel ayarı rota parametrelerinden al (sunucu başlıklarından değil, çünkü beforeLoad hem istemcide hem de sunucuda çalışır)
|
|
654
|
+
const localeParam = params.locale;
|
|
655
|
+
|
|
656
|
+
// validatePrefix, yerel ayarın intlayer yapılandırmanıza göre geçerli olup olmadığını kontrol eder
|
|
657
|
+
// Döndürür: { isValid: boolean, localePrefix: string }
|
|
658
|
+
// - isValid: önek yapılandırılmış bir yerel ayarla eşleşiyorsa (veya önek isteğe bağlı olduğunda boşsa) true
|
|
659
|
+
// - localePrefix: doğrulanmış önek veya yönlendirmeler için varsayılan yerel ayar öneki
|
|
660
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
661
|
+
|
|
662
|
+
if (isValid) {
|
|
663
|
+
// Yerel ayar geçerli, rotanın normal şekilde render edilmesine izin ver
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// Geçersiz yerel ayar öneki (örn. "xyz" geçerli bir yerel ayar olmadığında /xyz/about)
|
|
668
|
+
// Geçerli bir yerel ayar öneki ile 404 sayfasına yönlendir
|
|
669
|
+
// Bu, 404 sayfasının hala düzgün şekilde yerelleştirildiğini garanti eder
|
|
670
|
+
throw redirect({
|
|
671
|
+
to: "/{-$locale}/404",
|
|
672
|
+
params: { locale: localePrefix },
|
|
673
|
+
});
|
|
674
|
+
},
|
|
675
|
+
component: RouteComponent,
|
|
676
|
+
// notFoundComponent, bir alt rota mevcut olmadığında çağrılır
|
|
677
|
+
// örn. /en/var-olmayan-sayfa bunu /en düzeni içinde tetikler
|
|
678
|
+
notFoundComponent: NotFoundLayout,
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
function RouteComponent() {
|
|
682
|
+
const { defaultLocale } = useLocale();
|
|
683
|
+
const { locale } = Route.useParams();
|
|
684
|
+
|
|
685
|
+
return (
|
|
686
|
+
// Tüm yerel ayar segmentini IntlayerProvider ile sar
|
|
687
|
+
// Yerel ayar parametresi undefined olduğunda defaultLocale'e geri döner (isteğe bağlı önek modu)
|
|
688
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
689
|
+
<Outlet />
|
|
690
|
+
</IntlayerProvider>
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// NotFoundLayout, 404 bileşenini IntlayerProvider ile sarar
|
|
695
|
+
// Bu, çevirilerin 404 sayfasında hala çalışmasını sağlar
|
|
696
|
+
function NotFoundLayout() {
|
|
697
|
+
const { defaultLocale } = useLocale();
|
|
698
|
+
const { locale } = Route.useParams();
|
|
699
|
+
|
|
700
|
+
return (
|
|
701
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
702
|
+
<NotFoundComponent />
|
|
703
|
+
{/* Kullanıcıların 404'te bile dil değiştirebilmesi için LocaleSwitcher'ı dahil et */}
|
|
704
|
+
<LocaleSwitcher />
|
|
705
|
+
</IntlayerProvider>
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
711
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
712
|
+
|
|
713
|
+
import { NotFoundComponent } from "./404";
|
|
714
|
+
|
|
715
|
+
// $ (splat/catch-all) rotası, diğer rotalarla eşleşmeyen herhangi bir yolu eşleştirir
|
|
716
|
+
// örn. /en/bazı/derin/iç içe/geçersiz/yol
|
|
717
|
+
// Bu, bir yerel ayar içindeki TÜM eşleşmeyen yolların 404 sayfasını göstermesini sağlar
|
|
718
|
+
// Bu olmadan, eşleşmeyen derin yollar boş bir sayfa veya hata gösterebilir
|
|
719
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
720
|
+
component: NotFoundComponent,
|
|
721
|
+
});
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
### Adım 15: TypeScript Yapılandırması (İsteğe Bağlı)
|
|
608
727
|
|
|
609
728
|
Intlayer, TypeScript'in avantajlarından yararlanmak ve kod tabanınızı daha güçlü hale getirmek için modül genişletme (module augmentation) kullanır.
|
|
610
729
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: JSON Senkronizasyon Eklentisi
|
|
5
5
|
description: Intlayer sözlüklerini üçüncü taraf i18n JSON dosyalarıyla (i18next, next-intl, react-intl, vue-i18n ve daha fazlası) senkronize edin. Mevcut i18n yapınızı koruyarak Intlayer ile mesajlarınızı yönetin, çevirin ve test edin.
|
|
6
6
|
keywords:
|
|
@@ -24,12 +24,15 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 7.5.0
|
|
28
|
+
date: 2025-12-13
|
|
29
|
+
changes: ICU ve i18next format desteği eklendi
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: İlk JSON Senkronizasyon Eklentisi dokümantasyonu
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
# JSON Senkronizasyonu (i18n köprüleri)
|
|
35
|
+
# JSON Senkronizasyonu (i18n köprüleri) - ICU / i18next desteği ile JSON Senkronizasyonu
|
|
33
36
|
|
|
34
37
|
<iframe title="JSON çevirilerinizi Intlayer ile nasıl senkronize tutarsınız" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
38
|
|
|
@@ -105,9 +108,27 @@ syncJSON({
|
|
|
105
108
|
source: ({ key, locale }) => string, // zorunlu
|
|
106
109
|
location?: string, // isteğe bağlı etiket, varsayılan: "plugin"
|
|
107
110
|
priority?: number, // isteğe bağlı öncelik, çakışma çözümü için, varsayılan: 0
|
|
111
|
+
format?: 'intlayer' | 'icu' | 'i18next', // isteğe bağlı formatlayıcı, varsayılan: 'intlayer'
|
|
108
112
|
});
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
116
|
+
|
|
117
|
+
JSON dosyalarını senkronize ederken sözlük içeriği için kullanılacak formatlayıcıyı belirtir. Bu, çeşitli i18n kütüphaneleriyle uyumlu farklı mesaj formatlama sözdizimlerini kullanmanıza olanak tanır.
|
|
118
|
+
|
|
119
|
+
- `'intlayer'`: Varsayılan Intlayer formatlayıcısı (varsayılan).
|
|
120
|
+
- `'icu'`: ICU mesaj formatlamasını kullanır (react-intl, vue-i18n gibi kütüphanelerle uyumlu).
|
|
121
|
+
- `'i18next'`: i18next mesaj formatlamasını kullanır (i18next, next-i18next, Solid-i18next ile uyumlu).
|
|
122
|
+
|
|
123
|
+
**Örnek:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
syncJSON({
|
|
127
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
128
|
+
format: "i18next", // Uyumluluk için i18next formatlaması kullan
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
111
132
|
## Birden fazla JSON kaynağı ve öncelik
|
|
112
133
|
|
|
113
134
|
Farklı JSON kaynaklarını senkronize etmek için birden fazla `syncJSON` eklentisi ekleyebilirsiniz. Bu, projenizde birden fazla i18n kütüphanesi veya farklı JSON yapıları olduğunda faydalıdır.
|
|
@@ -135,6 +156,7 @@ export default defineConfig({
|
|
|
135
156
|
plugins: [
|
|
136
157
|
// Birincil JSON kaynağı (en yüksek öncelik)
|
|
137
158
|
syncJSON({
|
|
159
|
+
format: "i18next",
|
|
138
160
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
139
161
|
location: "main-translations",
|
|
140
162
|
priority: 10,
|
|
@@ -142,6 +164,7 @@ export default defineConfig({
|
|
|
142
164
|
|
|
143
165
|
// Yedek JSON kaynağı (daha düşük öncelik)
|
|
144
166
|
syncJSON({
|
|
167
|
+
format: "i18next",
|
|
145
168
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
146
169
|
location: "fallback-translations",
|
|
147
170
|
priority: 5,
|
|
@@ -149,6 +172,7 @@ export default defineConfig({
|
|
|
149
172
|
|
|
150
173
|
// Eski JSON kaynağı (en düşük öncelik)
|
|
151
174
|
syncJSON({
|
|
175
|
+
format: "i18next",
|
|
152
176
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
153
177
|
location: "legacy-translations",
|
|
154
178
|
priority: 1,
|
|
@@ -179,6 +203,7 @@ import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
|
179
203
|
export default {
|
|
180
204
|
plugins: [
|
|
181
205
|
syncJSON({
|
|
206
|
+
format: "i18next",
|
|
182
207
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
183
208
|
}),
|
|
184
209
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Tệp Nội Dung
|
|
5
5
|
description: Tìm hiểu cách tùy chỉnh các phần mở rộng cho các tệp khai báo nội dung của bạn. Theo dõi tài liệu này để triển khai các điều kiện một cách hiệu quả trong dự án của bạn.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: Thêm hỗ trợ định dạng ICU và i18next
|
|
15
18
|
- version: 7.0.0
|
|
16
19
|
date: 2025-10-23
|
|
17
20
|
changes: Đổi tên `autoFill` thành `fill`
|
|
@@ -387,6 +390,26 @@ Mảng các chuỗi dùng để phân loại và tổ chức các từ điển.
|
|
|
387
390
|
}
|
|
388
391
|
```
|
|
389
392
|
|
|
393
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
394
|
+
|
|
395
|
+
Chỉ định bộ định dạng để sử dụng cho nội dung từ điển. Điều này cho phép sử dụng các cú pháp định dạng thông báo khác nhau.
|
|
396
|
+
|
|
397
|
+
- `'intlayer'`: Bộ định dạng Intlayer mặc định.
|
|
398
|
+
- `'icu'`: Sử dụng định dạng thông báo ICU.
|
|
399
|
+
- `'i18next'`: Sử dụng định dạng thông báo i18next.
|
|
400
|
+
|
|
401
|
+
**Ví dụ:**
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
{
|
|
405
|
+
key: "my-dictionary",
|
|
406
|
+
format: "icu",
|
|
407
|
+
content: {
|
|
408
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
390
413
|
#### `locale` (LocalesValues)
|
|
391
414
|
|
|
392
415
|
Chuyển đổi từ điển thành từ điển theo từng locale, trong đó mỗi trường được khai báo trong nội dung sẽ tự động được chuyển thành một nút dịch. Khi thuộc tính này được thiết lập:
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2024-03-07
|
|
3
3
|
updatedAt: 2025-10-03
|
|
4
4
|
title: Cách dịch ứng dụng Astro của bạn – Hướng dẫn i18n 2025
|
|
5
|
-
description: Tìm hiểu cách thêm quốc tế hóa (i18n) vào
|
|
5
|
+
description: Tìm hiểu cách thêm quốc tế hóa (i18n) vào trang web Astro của bạn bằng Intlayer. Làm theo hướng dẫn này để làm cho trang web của bạn đa ngôn ngữ.
|
|
6
6
|
keywords:
|
|
7
7
|
- Quốc tế hóa
|
|
8
8
|
- Tài liệu
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-08-23
|
|
3
3
|
updatedAt: 2025-08-23
|
|
4
4
|
title: Cách dịch backend Express của bạn – Hướng dẫn i18n 2025
|
|
5
|
-
description: Khám phá cách làm cho backend
|
|
5
|
+
description: Khám phá cách làm cho backend Express của bạn đa ngôn ngữ. Theo dõi tài liệu để quốc tế hóa (i18n) và dịch nó.
|
|
6
6
|
keywords:
|
|
7
7
|
- Quốc tế hóa
|
|
8
8
|
- Tài liệu
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
3
|
updatedAt: 2025-09-09
|
|
4
4
|
title: Cách dịch backend Nest của bạn – Hướng dẫn i18n 2025
|
|
5
|
-
description: Khám phá cách làm cho backend
|
|
5
|
+
description: Khám phá cách làm cho backend NestJS của bạn đa ngôn ngữ. Theo dõi tài liệu để quốc tế hóa (i18n) và dịch nó.
|
|
6
6
|
keywords:
|
|
7
7
|
- Quốc tế hóa
|
|
8
8
|
- Tài liệu
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-09
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-11
|
|
4
4
|
title: Cách dịch ứng dụng Tanstack Start của bạn – hướng dẫn i18n 2025
|
|
5
5
|
description: Tìm hiểu cách thêm quốc tế hóa (i18n) vào ứng dụng Tanstack Start của bạn bằng cách sử dụng Intlayer. Theo dõi hướng dẫn toàn diện này để làm cho ứng dụng của bạn đa ngôn ngữ với định tuyến nhận biết locale.
|
|
6
6
|
keywords:
|
|
@@ -19,9 +19,12 @@ slugs:
|
|
|
19
19
|
applicationTemplate: https://github.com/aymericzip/intlayer-tanstack-start-template
|
|
20
20
|
youtubeVideo: https://www.youtube.com/watch?v=_XTdKVWaeqg
|
|
21
21
|
history:
|
|
22
|
+
- version: 7.4.0
|
|
23
|
+
date: 2025-12-11
|
|
24
|
+
changes: Giới thiệu validatePrefix và thêm bước 14: Xử lý trang 404 với các tuyến đường được bản địa hóa.
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
|
-
changes:
|
|
27
|
+
changes: Thêm bước 13: Lấy locale trong server actions của bạn (Tùy chọn)
|
|
25
28
|
- version: 6.5.2
|
|
26
29
|
date: 2025-10-03
|
|
27
30
|
changes: Cập nhật tài liệu
|
|
@@ -600,7 +603,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
600
603
|
|
|
601
604
|
---
|
|
602
605
|
|
|
603
|
-
### Bước 14:
|
|
606
|
+
### Bước 14: Quản lý trang không tìm thấy (Tùy chọn)
|
|
607
|
+
|
|
608
|
+
Khi người dùng truy cập một trang không tồn tại, bạn có thể hiển thị một trang không tìm thấy tùy chỉnh và tiền tố locale có thể ảnh hưởng đến cách trang không tìm thấy được kích hoạt.
|
|
609
|
+
|
|
610
|
+
#### Hiểu về xử lý 404 của TanStack Router với tiền tố locale
|
|
611
|
+
|
|
612
|
+
Trong TanStack Router, xử lý các trang 404 với các route đã được bản địa hóa yêu cầu một cách tiếp cận nhiều lớp:
|
|
613
|
+
|
|
614
|
+
1. **Route 404 chuyên dụng**: Một route cụ thể để hiển thị giao diện 404
|
|
615
|
+
2. **Xác thực cấp route**: Xác thực các tiền tố locale và chuyển hướng các tiền tố không hợp lệ đến 404
|
|
616
|
+
3. **Route catch-all**: Bắt tất cả các đường dẫn không khớp trong phân đoạn locale
|
|
617
|
+
|
|
618
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
619
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
620
|
+
|
|
621
|
+
// Điều này tạo một tuyến đường /[locale]/404 chuyên dụng
|
|
622
|
+
// Nó được sử dụng cả như một tuyến đường trực tiếp và được nhập như một thành phần trong các tệp khác
|
|
623
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
624
|
+
component: NotFoundComponent,
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
// Xuất riêng để có thể tái sử dụng trong notFoundComponent và các tuyến catch-all
|
|
628
|
+
export function NotFoundComponent() {
|
|
629
|
+
return (
|
|
630
|
+
<div>
|
|
631
|
+
<h1>404</h1>
|
|
632
|
+
</div>
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
638
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
639
|
+
import { validatePrefix } from "intlayer";
|
|
640
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
641
|
+
|
|
642
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
643
|
+
import { NotFoundComponent } from "./404";
|
|
644
|
+
|
|
645
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
646
|
+
// beforeLoad chạy trước khi tuyến đường được kết xuất (trên cả máy chủ và máy khách)
|
|
647
|
+
// Đây là nơi lý tưởng để xác thực tiền tố locale
|
|
648
|
+
beforeLoad: ({ params }) => {
|
|
649
|
+
// Lấy locale từ tham số tuyến đường (không phải từ tiêu đề máy chủ, vì beforeLoad chạy trên cả máy khách và máy chủ)
|
|
650
|
+
const localeParam = params.locale;
|
|
651
|
+
|
|
652
|
+
// validatePrefix kiểm tra xem locale có hợp lệ theo cấu hình intlayer của bạn không
|
|
653
|
+
// Trả về: { isValid: boolean, localePrefix: string }
|
|
654
|
+
// - isValid: true nếu tiền tố khớp với locale đã cấu hình (hoặc trống khi tiền tố là tùy chọn)
|
|
655
|
+
// - localePrefix: tiền tố đã được xác thực hoặc tiền tố locale mặc định để chuyển hướng
|
|
656
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
657
|
+
|
|
658
|
+
if (isValid) {
|
|
659
|
+
// Locale hợp lệ, cho phép tuyến đường kết xuất bình thường
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Tiền tố locale không hợp lệ (ví dụ: /xyz/about trong đó "xyz" không phải là locale hợp lệ)
|
|
664
|
+
// Chuyển hướng đến trang 404 với tiền tố locale hợp lệ
|
|
665
|
+
// Điều này đảm bảo trang 404 vẫn được bản địa hóa đúng cách
|
|
666
|
+
throw redirect({
|
|
667
|
+
to: "/{-$locale}/404",
|
|
668
|
+
params: { locale: localePrefix },
|
|
669
|
+
});
|
|
670
|
+
},
|
|
671
|
+
component: RouteComponent,
|
|
672
|
+
// notFoundComponent được gọi khi một tuyến đường con không tồn tại
|
|
673
|
+
// ví dụ: /en/trang-khong-ton-tai kích hoạt điều này trong bố cục /en
|
|
674
|
+
notFoundComponent: NotFoundLayout,
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
function RouteComponent() {
|
|
678
|
+
const { defaultLocale } = useLocale();
|
|
679
|
+
const { locale } = Route.useParams();
|
|
680
|
+
|
|
681
|
+
return (
|
|
682
|
+
// Bọc toàn bộ phân đoạn locale bằng IntlayerProvider
|
|
683
|
+
// Quay lại defaultLocale khi tham số locale là undefined (chế độ tiền tố tùy chọn)
|
|
684
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
685
|
+
<Outlet />
|
|
686
|
+
</IntlayerProvider>
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// NotFoundLayout bọc thành phần 404 bằng IntlayerProvider
|
|
691
|
+
// Điều này đảm bảo bản dịch vẫn hoạt động trên trang 404
|
|
692
|
+
function NotFoundLayout() {
|
|
693
|
+
const { defaultLocale } = useLocale();
|
|
694
|
+
const { locale } = Route.useParams();
|
|
695
|
+
|
|
696
|
+
return (
|
|
697
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
698
|
+
<NotFoundComponent />
|
|
699
|
+
{/* Bao gồm LocaleSwitcher để người dùng có thể thay đổi ngôn ngữ ngay cả trên 404 */}
|
|
700
|
+
<LocaleSwitcher />
|
|
701
|
+
</IntlayerProvider>
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
707
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
708
|
+
|
|
709
|
+
import { NotFoundComponent } from "./404";
|
|
710
|
+
|
|
711
|
+
// Tuyến đường $ (splat/catch-all) khớp với bất kỳ đường dẫn nào không khớp với các tuyến đường khác
|
|
712
|
+
// ví dụ: /en/mot/duong/dan/sau/long/khong-hop-le
|
|
713
|
+
// Điều này đảm bảo TẤT CẢ các đường dẫn không khớp trong một locale hiển thị trang 404
|
|
714
|
+
// Nếu không có điều này, các đường dẫn sâu không khớp có thể hiển thị trang trống hoặc lỗi
|
|
715
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
716
|
+
component: NotFoundComponent,
|
|
717
|
+
});
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
### Bước 15: Cấu hình TypeScript (Tùy chọn)
|
|
604
723
|
|
|
605
724
|
Intlayer sử dụng module augmentation để tận dụng các lợi ích của TypeScript và làm cho codebase của bạn mạnh mẽ hơn.
|
|
606
725
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: Plugin Đồng bộ JSON
|
|
5
5
|
description: Đồng bộ từ điển Intlayer với các tệp JSON i18n của bên thứ ba (i18next, next-intl, react-intl, vue-i18n và nhiều hơn nữa). Giữ nguyên i18n hiện có của bạn trong khi sử dụng Intlayer để quản lý, dịch và kiểm tra các thông điệp của bạn.
|
|
6
6
|
keywords:
|
|
@@ -24,12 +24,15 @@ slugs:
|
|
|
24
24
|
- sync-json
|
|
25
25
|
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
26
26
|
history:
|
|
27
|
+
- version: 7.5.0
|
|
28
|
+
date: 2025-12-13
|
|
29
|
+
changes: Thêm hỗ trợ định dạng ICU và i18next
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: Tài liệu Plugin Đồng bộ JSON ban đầu
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
# Đồng bộ JSON (cầu nối i18n)
|
|
35
|
+
# Đồng bộ JSON (cầu nối i18n) - Đồng bộ JSON với hỗ trợ ICU / i18next
|
|
33
36
|
|
|
34
37
|
<iframe title="Cách giữ bản dịch JSON của bạn đồng bộ với Intlayer" class="m-auto aspect-[16/9] w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/MpGMxniDHNg?autoplay=0&origin=http://intlayer.org&controls=0&rel=1"/>
|
|
35
38
|
|
|
@@ -105,9 +108,27 @@ syncJSON({
|
|
|
105
108
|
source: ({ key, locale }) => string, // bắt buộc
|
|
106
109
|
location?: string, // nhãn tùy chọn, mặc định: "plugin"
|
|
107
110
|
priority?: number, // ưu tiên tùy chọn để giải quyết xung đột, mặc định: 0
|
|
111
|
+
format?: 'intlayer' | 'icu' | 'i18next', // bộ định dạng tùy chọn, mặc định: 'intlayer'
|
|
108
112
|
});
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
116
|
+
|
|
117
|
+
Chỉ định bộ định dạng sẽ được sử dụng cho nội dung từ điển khi đồng bộ hóa các tệp JSON. Điều này cho phép sử dụng các cú pháp định dạng thông báo khác nhau tương thích với các thư viện i18n khác nhau.
|
|
118
|
+
|
|
119
|
+
- `'intlayer'`: Bộ định dạng Intlayer mặc định (mặc định).
|
|
120
|
+
- `'icu'`: Sử dụng định dạng thông báo ICU (tương thích với các thư viện như react-intl, vue-i18n).
|
|
121
|
+
- `'i18next'`: Sử dụng định dạng thông báo i18next (tương thích với i18next, next-i18next, Solid-i18next).
|
|
122
|
+
|
|
123
|
+
**Ví dụ:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
syncJSON({
|
|
127
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
128
|
+
format: "i18next", // Sử dụng định dạng i18next để tương thích
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
111
132
|
## Nhiều nguồn JSON và ưu tiên
|
|
112
133
|
|
|
113
134
|
Bạn có thể thêm nhiều plugin `syncJSON` để đồng bộ các nguồn JSON khác nhau. Điều này hữu ích khi bạn có nhiều thư viện i18n hoặc các cấu trúc JSON khác nhau trong dự án của mình.
|
|
@@ -134,6 +155,7 @@ export default defineConfig({
|
|
|
134
155
|
plugins: [
|
|
135
156
|
// Nguồn JSON chính (ưu tiên cao nhất)
|
|
136
157
|
syncJSON({
|
|
158
|
+
format: "i18next",
|
|
137
159
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
138
160
|
location: "main-translations",
|
|
139
161
|
priority: 10,
|
|
@@ -141,6 +163,7 @@ export default defineConfig({
|
|
|
141
163
|
|
|
142
164
|
// Nguồn JSON dự phòng (ưu tiên thấp hơn)
|
|
143
165
|
syncJSON({
|
|
166
|
+
format: "i18next",
|
|
144
167
|
source: ({ locale }) => `./fallback-locales/${locale}.json`,
|
|
145
168
|
location: "fallback-translations",
|
|
146
169
|
priority: 5,
|
|
@@ -148,6 +171,7 @@ export default defineConfig({
|
|
|
148
171
|
|
|
149
172
|
// Nguồn JSON kế thừa (ưu tiên thấp nhất)
|
|
150
173
|
syncJSON({
|
|
174
|
+
format: "i18next",
|
|
151
175
|
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`,
|
|
152
176
|
location: "legacy-translations",
|
|
153
177
|
priority: 1,
|
|
@@ -178,6 +202,7 @@ import { syncJSON } from "@intlayer/sync-json-plugin";
|
|
|
178
202
|
export default {
|
|
179
203
|
plugins: [
|
|
180
204
|
syncJSON({
|
|
205
|
+
format: "i18next",
|
|
181
206
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`, // nguồn tệp JSON đồng bộ theo khóa và ngôn ngữ
|
|
182
207
|
}),
|
|
183
208
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: 内容文件
|
|
5
5
|
description: 学习如何自定义内容声明文件的扩展。按照本指南高效地在项目中实现条件。
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 7.5.0
|
|
16
|
+
date: 2025-12-13
|
|
17
|
+
changes: 添加 ICU 和 i18next 格式支持
|
|
15
18
|
- version: 6.0.0
|
|
16
19
|
date: 2025-09-20
|
|
17
20
|
changes: 添加字段文档
|
|
@@ -386,6 +389,46 @@ Intlayer 中的字典由 `Dictionary` 类型定义,包含多个控制其行为
|
|
|
386
389
|
}
|
|
387
390
|
```
|
|
388
391
|
|
|
392
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
393
|
+
|
|
394
|
+
指定用于字典内容的格式化器。这允许使用不同的消息格式化语法。
|
|
395
|
+
|
|
396
|
+
- `'intlayer'`: 默认的 Intlayer 格式化器。
|
|
397
|
+
- `'icu'`: 使用 ICU 消息格式化。
|
|
398
|
+
- `'i18next'`: 使用 i18next 消息格式化。
|
|
399
|
+
|
|
400
|
+
**示例:**
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
{
|
|
404
|
+
key: "my-dictionary",
|
|
405
|
+
format: "icu",
|
|
406
|
+
content: {
|
|
407
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
413
|
+
|
|
414
|
+
指定用于字典内容的格式化器。这允许使用不同的消息格式化语法。
|
|
415
|
+
|
|
416
|
+
- `'intlayer'`: 默认的 Intlayer 格式化器。
|
|
417
|
+
- `'icu'`: 使用 ICU 消息格式化。
|
|
418
|
+
- `'i18next'`: 使用 i18next 消息格式化。
|
|
419
|
+
|
|
420
|
+
**示例:**
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
{
|
|
424
|
+
key: "my-dictionary",
|
|
425
|
+
format: "icu",
|
|
426
|
+
content: {
|
|
427
|
+
message: "Hello {name}, you have {count, plural, one {# message} other {# messages}}"
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
389
432
|
#### `locale` (LocalesValues)
|
|
390
433
|
|
|
391
434
|
将字典转换为按语言区域划分的字典,其中内容中声明的每个字段将自动转换为翻译节点。当设置此属性时:
|