@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应用 – i18n指南 2025
|
|
5
5
|
description: 学习如何使用 Intlayer 为您的 Tanstack Start 应用添加国际化 (i18n)。按照本综合指南,使您的应用支持多语言并具备基于区域设置的路由功能。
|
|
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 并添加步骤 14: 处理带有本地化路由的 404 页面。
|
|
22
25
|
- version: 7.3.9
|
|
23
26
|
date: 2025-12-05
|
|
24
|
-
changes:
|
|
27
|
+
changes: 添加步骤 13: 在您的 server actions 中获取 locale (可选)
|
|
25
28
|
- version: 5.8.1
|
|
26
29
|
date: 2025-09-09
|
|
27
30
|
changes: 为 Tanstack Start 添加支持
|
|
@@ -591,7 +594,123 @@ export const getLocaleServer = createServerFn().handler(async () => {
|
|
|
591
594
|
|
|
592
595
|
---
|
|
593
596
|
|
|
594
|
-
### 第14
|
|
597
|
+
### 第14步:管理未找到的页面(可选)
|
|
598
|
+
|
|
599
|
+
当用户访问不存在的页面时,您可以显示自定义的未找到页面,并且区域设置前缀可能会影响未找到页面的触发方式。
|
|
600
|
+
|
|
601
|
+
#### 了解 TanStack Router 使用区域设置前缀的 404 处理
|
|
602
|
+
|
|
603
|
+
在 TanStack Router 中,使用本地化路由处理 404 页面需要采用多层方法:
|
|
604
|
+
|
|
605
|
+
1. **专用 404 路由**:用于显示 404 UI 的特定路由
|
|
606
|
+
2. **路由级验证**:验证区域设置前缀并将无效的前缀重定向到 404
|
|
607
|
+
3. **捕获所有路由**:捕获区域设置段内任何不匹配的路径
|
|
608
|
+
|
|
609
|
+
```tsx fileName="src/routes/{-$locale}/404.tsx"
|
|
610
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
611
|
+
|
|
612
|
+
// 这将创建一个专用的 /[locale]/404 路由
|
|
613
|
+
// 它既作为直接路由使用,也可以在其他文件中作为组件导入
|
|
614
|
+
export const Route = createFileRoute("/{-$locale}/404")({
|
|
615
|
+
component: NotFoundComponent,
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
// 单独导出,以便可以在 notFoundComponent 和 catch-all 路由中重用
|
|
619
|
+
export function NotFoundComponent() {
|
|
620
|
+
return (
|
|
621
|
+
<div>
|
|
622
|
+
<h1>404</h1>
|
|
623
|
+
</div>
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
```tsx fileName="src/routes/{-$locale}/route.tsx"
|
|
629
|
+
import { createFileRoute, Outlet, redirect } from "@tanstack/react-router";
|
|
630
|
+
import { validatePrefix } from "intlayer";
|
|
631
|
+
import { IntlayerProvider, useLocale } from "react-intlayer";
|
|
632
|
+
|
|
633
|
+
import { LocaleSwitcher } from "@/components/locale-switcher";
|
|
634
|
+
import { NotFoundComponent } from "./404";
|
|
635
|
+
|
|
636
|
+
export const Route = createFileRoute("/{-$locale}")({
|
|
637
|
+
// beforeLoad 在路由渲染之前运行(在服务器和客户端上)
|
|
638
|
+
// 这是验证区域设置前缀的理想位置
|
|
639
|
+
beforeLoad: ({ params }) => {
|
|
640
|
+
// 从路由参数获取区域设置(不是从服务器标头,因为 beforeLoad 在客户端和服务器上都会运行)
|
|
641
|
+
const localeParam = params.locale;
|
|
642
|
+
|
|
643
|
+
// validatePrefix 检查区域设置是否根据您的 intlayer 配置有效
|
|
644
|
+
// 返回: { isValid: boolean, localePrefix: string }
|
|
645
|
+
// - isValid: 如果前缀匹配配置的区域设置(或当前缀可选时为空),则为 true
|
|
646
|
+
// - localePrefix: 已验证的前缀或用于重定向的默认区域设置前缀
|
|
647
|
+
const { isValid, localePrefix } = validatePrefix(localeParam);
|
|
648
|
+
|
|
649
|
+
if (isValid) {
|
|
650
|
+
// 区域设置有效,允许路由正常渲染
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// 无效的区域设置前缀(例如,/xyz/about 其中 "xyz" 不是有效的区域设置)
|
|
655
|
+
// 重定向到具有有效区域设置前缀的 404 页面
|
|
656
|
+
// 这确保 404 页面仍然正确本地化
|
|
657
|
+
throw redirect({
|
|
658
|
+
to: "/{-$locale}/404",
|
|
659
|
+
params: { locale: localePrefix },
|
|
660
|
+
});
|
|
661
|
+
},
|
|
662
|
+
component: RouteComponent,
|
|
663
|
+
// notFoundComponent 在子路由不存在时被调用
|
|
664
|
+
// 例如,/en/不存在的页面 在 /en 布局内触发此操作
|
|
665
|
+
notFoundComponent: NotFoundLayout,
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
function RouteComponent() {
|
|
669
|
+
const { defaultLocale } = useLocale();
|
|
670
|
+
const { locale } = Route.useParams();
|
|
671
|
+
|
|
672
|
+
return (
|
|
673
|
+
// 用 IntlayerProvider 包装整个区域设置段
|
|
674
|
+
// 当区域设置参数为 undefined 时回退到 defaultLocale(可选前缀模式)
|
|
675
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
676
|
+
<Outlet />
|
|
677
|
+
</IntlayerProvider>
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// NotFoundLayout 用 IntlayerProvider 包装 404 组件
|
|
682
|
+
// 这确保翻译在 404 页面上仍然有效
|
|
683
|
+
function NotFoundLayout() {
|
|
684
|
+
const { defaultLocale } = useLocale();
|
|
685
|
+
const { locale } = Route.useParams();
|
|
686
|
+
|
|
687
|
+
return (
|
|
688
|
+
<IntlayerProvider locale={locale ?? defaultLocale}>
|
|
689
|
+
<NotFoundComponent />
|
|
690
|
+
{/* 包含 LocaleSwitcher,以便用户即使在 404 页面上也可以更改语言 */}
|
|
691
|
+
<LocaleSwitcher />
|
|
692
|
+
</IntlayerProvider>
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
```tsx fileName="src/routes/{-$locale}/$.tsx"
|
|
698
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
699
|
+
|
|
700
|
+
import { NotFoundComponent } from "./404";
|
|
701
|
+
|
|
702
|
+
// $ (splat/catch-all) 路由匹配任何与其他路由不匹配的路径
|
|
703
|
+
// 例如,/en/某个/深度/嵌套/无效/路径
|
|
704
|
+
// 这确保区域设置内所有不匹配的路径都显示 404 页面
|
|
705
|
+
// 没有这个,不匹配的深层路径可能会显示空白页面或错误
|
|
706
|
+
export const Route = createFileRoute("/{-$locale}/$")({
|
|
707
|
+
component: NotFoundComponent,
|
|
708
|
+
});
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
713
|
+
### 第15步:配置 TypeScript(可选)
|
|
595
714
|
|
|
596
715
|
Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库更健壮。
|
|
597
716
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-03-13
|
|
3
|
-
updatedAt: 2025-
|
|
3
|
+
updatedAt: 2025-12-13
|
|
4
4
|
title: 同步 JSON 插件
|
|
5
5
|
description: 将 Intlayer 字典与第三方 i18n JSON 文件(如 i18next、next-intl、react-intl、vue-i18n 等)同步。保持您现有的 i18n,同时使用 Intlayer 管理、翻译和测试您的消息。
|
|
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 和 i18next 格式支持
|
|
27
30
|
- version: 6.1.6
|
|
28
31
|
date: 2025-10-05
|
|
29
32
|
changes: 初始同步 JSON 插件文档
|
|
30
33
|
---
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
# 同步 JSON(i18n 桥接)- 支持 ICU / i18next 的同步 JSON
|
|
33
36
|
|
|
34
37
|
<iframe title="如何保持您的 JSON 翻译与 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, // 必填
|
|
106
109
|
location?: string, // 可选标签,默认值:"plugin"
|
|
107
110
|
priority?: number, // 可选优先级,用于冲突解决,默认值:0
|
|
111
|
+
format?: 'intlayer' | 'icu' | 'i18next', // 可选格式化器,默认值:'intlayer'
|
|
108
112
|
});
|
|
109
113
|
```
|
|
110
114
|
|
|
115
|
+
#### `format` ('intlayer' | 'icu' | 'i18next')
|
|
116
|
+
|
|
117
|
+
指定在同步 JSON 文件时用于字典内容的格式化器。这允许使用与各种 i18n 库兼容的不同消息格式化语法。
|
|
118
|
+
|
|
119
|
+
- `'intlayer'`: 默认的 Intlayer 格式化器(默认值)。
|
|
120
|
+
- `'icu'`: 使用 ICU 消息格式化(与 react-intl、vue-i18n 等库兼容)。
|
|
121
|
+
- `'i18next'`: 使用 i18next 消息格式化(与 i18next、next-i18next、Solid-i18next 兼容)。
|
|
122
|
+
|
|
123
|
+
**示例:**
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
syncJSON({
|
|
127
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
128
|
+
format: "i18next", // 使用 i18next 格式化以保持兼容性
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
111
132
|
## 多个 JSON 源和优先级
|
|
112
133
|
|
|
113
134
|
你可以添加多个 `syncJSON` 插件来同步不同的 JSON 源。当你的项目中使用多个 i18n 库或有不同的 JSON 结构时,这非常有用。
|
|
@@ -134,6 +155,7 @@ export default defineConfig({
|
|
|
134
155
|
plugins: [
|
|
135
156
|
// 主要 JSON 源(最高优先级)
|
|
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
|
// 备用 JSON 源(较低优先级)
|
|
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
|
// 旧版 JSON 源(最低优先级)
|
|
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`,
|
|
182
207
|
}),
|
|
183
208
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/docs",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0-canary.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Intlayer documentation",
|
|
6
6
|
"keywords": [
|
|
@@ -73,13 +73,13 @@
|
|
|
73
73
|
"watch": "webpack --config ./webpack.config.ts --watch"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
|
-
"@intlayer/config": "7.
|
|
77
|
-
"@intlayer/core": "7.
|
|
78
|
-
"@intlayer/types": "7.
|
|
76
|
+
"@intlayer/config": "7.5.0-canary.0",
|
|
77
|
+
"@intlayer/core": "7.5.0-canary.0",
|
|
78
|
+
"@intlayer/types": "7.5.0-canary.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@intlayer/api": "7.
|
|
82
|
-
"@intlayer/cli": "7.
|
|
81
|
+
"@intlayer/api": "7.5.0-canary.0",
|
|
82
|
+
"@intlayer/cli": "7.5.0-canary.0",
|
|
83
83
|
"@types/node": "24.10.1",
|
|
84
84
|
"@utils/ts-config": "1.0.4",
|
|
85
85
|
"@utils/ts-config-types": "1.0.4",
|