@intlayer/docs 7.3.14 → 7.3.15

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.
Files changed (159) hide show
  1. package/blog/ar/intlayer_with_i18next.md +3 -0
  2. package/blog/ar/intlayer_with_next-i18next.md +3 -0
  3. package/blog/ar/intlayer_with_next-intl.md +3 -0
  4. package/blog/ar/intlayer_with_react-i18next.md +3 -0
  5. package/blog/ar/intlayer_with_react-intl.md +3 -0
  6. package/blog/ar/intlayer_with_vue-i18n.md +3 -0
  7. package/blog/de/intlayer_with_i18next.md +3 -0
  8. package/blog/de/intlayer_with_next-i18next.md +3 -0
  9. package/blog/de/intlayer_with_next-intl.md +3 -0
  10. package/blog/de/intlayer_with_react-i18next.md +3 -0
  11. package/blog/de/intlayer_with_react-intl.md +3 -0
  12. package/blog/de/intlayer_with_vue-i18n.md +3 -0
  13. package/blog/en/intlayer_with_i18next.md +7 -0
  14. package/blog/en/intlayer_with_next-i18next.md +3 -0
  15. package/blog/en/intlayer_with_next-intl.md +7 -0
  16. package/blog/en/intlayer_with_react-i18next.md +3 -0
  17. package/blog/en/intlayer_with_react-intl.md +3 -0
  18. package/blog/en/intlayer_with_vue-i18n.md +3 -0
  19. package/blog/en-GB/intlayer_with_i18next.md +3 -0
  20. package/blog/en-GB/intlayer_with_next-i18next.md +3 -0
  21. package/blog/en-GB/intlayer_with_next-intl.md +3 -0
  22. package/blog/en-GB/intlayer_with_react-i18next.md +3 -0
  23. package/blog/en-GB/intlayer_with_react-intl.md +3 -0
  24. package/blog/en-GB/intlayer_with_vue-i18n.md +3 -0
  25. package/blog/es/intlayer_with_i18next.md +3 -0
  26. package/blog/es/intlayer_with_next-i18next.md +3 -0
  27. package/blog/es/intlayer_with_next-intl.md +3 -0
  28. package/blog/es/intlayer_with_react-i18next.md +3 -0
  29. package/blog/es/intlayer_with_react-intl.md +3 -0
  30. package/blog/es/intlayer_with_vue-i18n.md +3 -0
  31. package/blog/fr/intlayer_with_i18next.md +3 -0
  32. package/blog/fr/intlayer_with_next-i18next.md +3 -0
  33. package/blog/fr/intlayer_with_next-intl.md +3 -0
  34. package/blog/fr/intlayer_with_react-i18next.md +3 -0
  35. package/blog/fr/intlayer_with_react-intl.md +3 -0
  36. package/blog/fr/intlayer_with_vue-i18n.md +3 -0
  37. package/blog/hi/intlayer_with_i18next.md +3 -0
  38. package/blog/hi/intlayer_with_next-i18next.md +3 -0
  39. package/blog/hi/intlayer_with_next-intl.md +3 -0
  40. package/blog/hi/intlayer_with_react-i18next.md +3 -0
  41. package/blog/hi/intlayer_with_react-intl.md +3 -0
  42. package/blog/hi/intlayer_with_vue-i18n.md +3 -0
  43. package/blog/id/intlayer_with_i18next.md +3 -0
  44. package/blog/id/intlayer_with_next-i18next.md +3 -0
  45. package/blog/id/intlayer_with_next-intl.md +3 -0
  46. package/blog/id/intlayer_with_react-i18next.md +3 -0
  47. package/blog/id/intlayer_with_react-intl.md +3 -0
  48. package/blog/id/intlayer_with_vue-i18n.md +3 -0
  49. package/blog/it/intlayer_with_i18next.md +3 -0
  50. package/blog/it/intlayer_with_next-i18next.md +3 -0
  51. package/blog/it/intlayer_with_next-intl.md +3 -0
  52. package/blog/it/intlayer_with_react-i18next.md +3 -0
  53. package/blog/it/intlayer_with_react-intl.md +3 -0
  54. package/blog/it/intlayer_with_vue-i18n.md +3 -0
  55. package/blog/ja/intlayer_with_i18next.md +3 -0
  56. package/blog/ja/intlayer_with_next-i18next.md +3 -0
  57. package/blog/ja/intlayer_with_next-intl.md +3 -0
  58. package/blog/ja/intlayer_with_react-i18next.md +3 -0
  59. package/blog/ja/intlayer_with_react-intl.md +3 -0
  60. package/blog/ja/intlayer_with_vue-i18n.md +3 -0
  61. package/blog/ko/intlayer_with_i18next.md +3 -0
  62. package/blog/ko/intlayer_with_next-i18next.md +3 -0
  63. package/blog/ko/intlayer_with_next-intl.md +3 -0
  64. package/blog/ko/intlayer_with_react-i18next.md +3 -0
  65. package/blog/ko/intlayer_with_react-intl.md +3 -0
  66. package/blog/ko/intlayer_with_vue-i18n.md +3 -0
  67. package/blog/pl/intlayer_with_i18next.md +3 -0
  68. package/blog/pl/intlayer_with_next-i18next.md +3 -0
  69. package/blog/pl/intlayer_with_next-intl.md +3 -0
  70. package/blog/pl/intlayer_with_react-i18next.md +3 -0
  71. package/blog/pl/intlayer_with_react-intl.md +3 -0
  72. package/blog/pl/intlayer_with_vue-i18n.md +3 -0
  73. package/blog/pt/intlayer_with_i18next.md +3 -0
  74. package/blog/pt/intlayer_with_next-i18next.md +3 -0
  75. package/blog/pt/intlayer_with_next-intl.md +3 -0
  76. package/blog/pt/intlayer_with_react-i18next.md +3 -0
  77. package/blog/pt/intlayer_with_react-intl.md +3 -0
  78. package/blog/pt/intlayer_with_vue-i18n.md +3 -0
  79. package/blog/ru/intlayer_with_i18next.md +3 -0
  80. package/blog/ru/intlayer_with_next-i18next.md +3 -0
  81. package/blog/ru/intlayer_with_next-intl.md +3 -0
  82. package/blog/ru/intlayer_with_react-i18next.md +3 -0
  83. package/blog/ru/intlayer_with_react-intl.md +3 -0
  84. package/blog/ru/intlayer_with_vue-i18n.md +3 -0
  85. package/blog/tr/intlayer_with_i18next.md +3 -0
  86. package/blog/tr/intlayer_with_next-i18next.md +3 -0
  87. package/blog/tr/intlayer_with_next-intl.md +3 -0
  88. package/blog/tr/intlayer_with_react-i18next.md +3 -0
  89. package/blog/tr/intlayer_with_vue-i18n.md +3 -0
  90. package/blog/vi/intlayer_with_i18next.md +3 -0
  91. package/blog/vi/intlayer_with_next-i18next.md +3 -0
  92. package/blog/vi/intlayer_with_next-intl.md +3 -0
  93. package/blog/vi/intlayer_with_react-i18next.md +3 -0
  94. package/blog/vi/intlayer_with_react-intl.md +3 -0
  95. package/blog/vi/intlayer_with_vue-i18n.md +3 -0
  96. package/blog/zh/intlayer_with_i18next.md +3 -0
  97. package/blog/zh/intlayer_with_next-i18next.md +3 -0
  98. package/blog/zh/intlayer_with_next-intl.md +3 -0
  99. package/blog/zh/intlayer_with_react-i18next.md +3 -0
  100. package/blog/zh/intlayer_with_react-intl.md +3 -0
  101. package/blog/zh/intlayer_with_vue-i18n.md +3 -0
  102. package/docs/ar/intlayer_with_lynx+react.md +1 -1
  103. package/docs/ar/intlayer_with_vite+react.md +99 -331
  104. package/docs/ar/plugins/sync-json.md +3 -0
  105. package/docs/de/intlayer_with_lynx+react.md +1 -1
  106. package/docs/de/intlayer_with_vite+react.md +116 -380
  107. package/docs/de/plugins/sync-json.md +3 -0
  108. package/docs/en/intlayer_with_vite+react.md +6 -10
  109. package/docs/en/plugins/sync-json.md +3 -0
  110. package/docs/en-GB/intlayer_with_vite+react.md +62 -74
  111. package/docs/en-GB/plugins/sync-json.md +3 -0
  112. package/docs/es/intlayer_with_vite+react.md +101 -333
  113. package/docs/es/plugins/sync-json.md +3 -0
  114. package/docs/fr/intlayer_with_vite+react.md +101 -357
  115. package/docs/fr/plugins/sync-json.md +3 -0
  116. package/docs/hi/intlayer_with_vite+react.md +120 -333
  117. package/docs/hi/plugins/sync-json.md +3 -0
  118. package/docs/id/intlayer_with_vite+react.md +7 -13
  119. package/docs/id/plugins/sync-json.md +3 -0
  120. package/docs/it/intlayer_with_lynx+react.md +1 -1
  121. package/docs/it/intlayer_with_vite+react.md +121 -393
  122. package/docs/it/plugins/sync-json.md +3 -0
  123. package/docs/ja/intlayer_with_vite+react.md +106 -378
  124. package/docs/ja/plugins/sync-json.md +3 -0
  125. package/docs/ko/intlayer_with_lynx+react.md +1 -1
  126. package/docs/ko/intlayer_with_vite+react.md +90 -322
  127. package/docs/ko/plugins/sync-json.md +3 -0
  128. package/docs/pl/intlayer_with_vite+react.md +25 -21
  129. package/docs/pl/plugins/sync-json.md +3 -0
  130. package/docs/pt/intlayer_with_vite+react.md +96 -328
  131. package/docs/pt/plugins/sync-json.md +3 -0
  132. package/docs/ru/intlayer_with_lynx+react.md +1 -1
  133. package/docs/ru/intlayer_with_vite+react.md +109 -362
  134. package/docs/ru/plugins/sync-json.md +3 -0
  135. package/docs/tr/intlayer_with_vite+react.md +132 -366
  136. package/docs/tr/plugins/sync-json.md +3 -0
  137. package/docs/vi/intlayer_with_vite+react.md +16 -19
  138. package/docs/vi/plugins/sync-json.md +3 -0
  139. package/docs/zh/intlayer_with_tanstack.md +1 -1
  140. package/docs/zh/intlayer_with_vite+react.md +91 -374
  141. package/docs/zh/plugins/sync-json.md +3 -0
  142. package/frequent_questions/ar/customized_locale_list.md +1 -1
  143. package/frequent_questions/de/customized_locale_list.md +1 -1
  144. package/frequent_questions/en/customized_locale_list.md +1 -1
  145. package/frequent_questions/en-GB/customized_locale_list.md +1 -1
  146. package/frequent_questions/es/customized_locale_list.md +1 -1
  147. package/frequent_questions/fr/customized_locale_list.md +1 -1
  148. package/frequent_questions/hi/customized_locale_list.md +1 -1
  149. package/frequent_questions/id/customized_locale_list.md +1 -1
  150. package/frequent_questions/it/customized_locale_list.md +1 -1
  151. package/frequent_questions/ja/customized_locale_list.md +1 -1
  152. package/frequent_questions/ko/customized_locale_list.md +1 -1
  153. package/frequent_questions/pl/customized_locale_list.md +1 -1
  154. package/frequent_questions/pt/customized_locale_list.md +1 -1
  155. package/frequent_questions/ru/customized_locale_list.md +1 -1
  156. package/frequent_questions/tr/customized_locale_list.md +1 -1
  157. package/frequent_questions/vi/customized_locale_list.md +1 -1
  158. package/frequent_questions/zh/customized_locale_list.md +1 -1
  159. package/package.json +6 -6
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  createdAt: 2024-03-07
3
- updatedAt: 2024-03-07
4
- title: 如何翻译您的Vite and React应用 – i18n指南 2025
3
+ updatedAt: 2025-12-10
4
+ title: 如何翻译您的 Vite React 应用 – 2025 年 i18n 指南
5
5
  description: 学习如何使用 Intlayer 为您的 Vite 和 React 应用添加国际化 (i18n)。按照本指南使您的应用支持多语言。
6
6
  keywords:
7
7
  - 国际化
@@ -16,26 +16,22 @@ slugs:
16
16
  - environment
17
17
  - vite-and-react
18
18
  applicationTemplate: https://github.com/aymericzip/intlayer-vite-react-template
19
- youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4---
19
+ youtubeVideo: https://www.youtube.com/watch?v=dS9L7uJeak4
20
20
  history:
21
21
  - version: 5.5.10
22
22
  date: 2025-06-29
23
23
  changes: 初始化历史
24
24
  ---
25
25
 
26
- # 使用 Intlayer 结合 Vite 和 React 开始国际化 (i18n)
26
+ # 使用 Intlayer 翻译您的 Vite 和 React 网站 | 国际化 (i18n)
27
27
 
28
28
  ## 目录
29
29
 
30
30
  <TOC/>
31
31
 
32
- <iframe title="The best i18n solution for Vite and React? Discover 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/dS9L7uJeak4?si=VaKmrYMmXjo3xpk2"/>
33
-
34
- 请参阅 GitHub 上的[应用模板](https://github.com/aymericzip/intlayer-vite-react-template)。
35
-
36
32
  ## 什么是 Intlayer?
37
33
 
38
- **Intlayer** 是一个创新的开源国际化 (i18n) 库,旨在简化现代 Web 应用的多语言支持。
34
+ **Intlayer** 是一个创新的开源国际化 (i18n) 库,旨在简化现代 Web 应用中的多语言支持。
39
35
 
40
36
  使用 Intlayer,您可以:
41
37
 
@@ -48,6 +44,27 @@ history:
48
44
 
49
45
  ## 在 Vite 和 React 应用中设置 Intlayer 的分步指南
50
46
 
47
+ <Tab defaultTab="video">
48
+ <TabItem label="视频" value="video">
49
+
50
+ <iframe title="Vite 和 React 最佳的国际化解决方案?探索 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/dS9L7uJeak4?si=VaKmrYMmXjo3xpk2"/>
51
+
52
+ </TabItem>
53
+ <TabItem label="代码" value="code">
54
+
55
+ <iframe
56
+ src="https://stackblitz.com/github/aymericzip/intlayer-vite-react-template?embed=1&ctl=1&file=intlayer.config.ts"
57
+ className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
58
+ title="演示 CodeSandbox - 如何使用 Intlayer 国际化您的应用程序"
59
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
60
+ loading="lazy"
61
+ />
62
+
63
+ </TabItem>
64
+ </Tab>
65
+
66
+ 请参阅 GitHub 上的 [Application Template](https://github.com/aymericzip/intlayer-vite-react-template)。
67
+
51
68
  ### 第一步:安装依赖
52
69
 
53
70
  使用 npm 安装所需的包:
@@ -69,13 +86,13 @@ yarn add vite-intlayer --save-dev
69
86
 
70
87
  - **intlayer**
71
88
 
72
- 核心包,提供用于配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)、转译和[CLI命令](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_cli.md)的国际化工具。
89
+ 核心包,提供用于配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)、转译和[CLI命令](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/cli/index.md)的国际化工具。
73
90
 
74
91
  - **react-intlayer**
75
92
  将 Intlayer 集成到 React 应用中的包。它提供了用于 React 国际化的上下文提供者和钩子。
76
93
 
77
94
  - **vite-intlayer**
78
- 包含用于将 Intlayer 集成到[Vite 打包工具](https://vite.dev/guide/why.html#why-bundle-for-production)的 Vite 插件,以及用于检测用户首选语言环境、管理 Cookie 和处理 URL 重定向的中间件。
95
+ 包含用于将 Intlayer 集成到 [Vite 打包工具](https://vite.dev/guide/why.html#why-bundle-for-production) 的 Vite 插件,以及用于检测用户首选语言环境、管理 Cookie 和处理 URL 重定向的中间件。
79
96
 
80
97
  ### 第2步:配置您的项目
81
98
 
@@ -417,9 +434,9 @@ module.exports = appContent;
417
434
  }
418
435
  ```
419
436
 
420
- > 您的内容声明可以定义在应用程序中的任何位置,只要它们被包含在 `contentDir` 目录中(默认是 `./src`)。并且匹配内容声明文件的扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
437
+ > 您的内容声明可以定义在应用程序中的任何位置,只要它们被包含在 `contentDir` 目录中(默认是 `./src`),并且匹配内容声明文件的扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
421
438
 
422
- > 更多详情,请参阅[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)。
439
+ > 更多详情,请参阅[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)。
423
440
 
424
441
  > 如果您的内容文件包含 TSX 代码,您应考虑在内容文件中导入 `import React from "react";`。
425
442
 
@@ -638,82 +655,10 @@ const LocaleSwitcher = () => {
638
655
  要为您的应用添加本地化路由,您可以创建一个 `LocaleRouter` 组件,包裹应用的路由并处理基于语言的路由。以下是使用 [React Router](https://reactrouter.com/home) 的示例:
639
656
 
640
657
  ```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
641
- // 导入必要的依赖和函数
642
- import { type Locales, configuration, getPathWithoutLocale } from "intlayer"; // 来自 'intlayer' 的实用函数和类型
658
+ import { localeMap } from "intlayer"; // 来自 'intlayer' 的实用函数和类型
643
659
  import type { FC, PropsWithChildren } from "react"; // React 中函数组件和属性的类型
644
660
  import { IntlayerProvider } from "react-intlayer"; // 国际化上下文提供者
645
- import {
646
- BrowserRouter,
647
- Routes,
648
- Route,
649
- Navigate,
650
- useLocation,
651
- } from "react-router-dom"; // 用于管理导航的路由组件
652
-
653
- // 从 Intlayer 中解构配置
654
- const { internationalization, middleware } = configuration;
655
- const { locales, defaultLocale } = internationalization;
656
-
657
- /**
658
- * 一个处理本地化的组件,使用适当的语言环境上下文包裹子组件。
659
- * 它管理基于 URL 的语言环境检测和验证。
660
- */
661
- const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
662
- children,
663
- locale,
664
- }) => {
665
- const { pathname, search } = useLocation(); // 获取当前的URL路径
666
-
667
- // 确定当前的语言环境,如果未提供则回退到默认语言环境
668
- const currentLocale = locale ?? defaultLocale;
669
-
670
- // 移除路径中的语言环境前缀以构建基础路径
671
- const pathWithoutLocale = getPathWithoutLocale(
672
- pathname // 当前的URL路径
673
- );
674
-
675
- /**
676
- * 如果 middleware.prefixDefault 为 true,则默认语言环境应始终带有前缀。
677
- */
678
- if (middleware.prefixDefault) {
679
- // 验证语言环境
680
- if (!locale || !locales.includes(locale)) {
681
- // 重定向到带有更新路径的默认语言环境
682
- return (
683
- <Navigate
684
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
685
- replace // 替换当前的历史记录条目为新的条目
686
- />
687
- );
688
- }
689
-
690
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
691
- return (
692
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
693
- );
694
- } else {
695
- /**
696
- * 当 middleware.prefixDefault 为 false 时,默认语言环境不带前缀。
697
- * 确保当前语言环境有效且不是默认语言环境。
698
- */
699
- if (
700
- currentLocale.toString() !== defaultLocale.toString() &&
701
- !locales
702
- .filter(
703
- (locale) => locale.toString() !== defaultLocale.toString() // 排除默认语言环境
704
- )
705
- .includes(currentLocale) // 检查当前语言环境是否在有效语言列表中
706
- ) {
707
- // 重定向到无语言前缀的路径
708
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
709
- }
710
-
711
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
712
- return (
713
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
714
- );
715
- }
716
- };
661
+ import { BrowserRouter, Route, Routes } from "react-router-dom"; // 用于管理导航的路由组件
717
662
 
718
663
  /**
719
664
  * 一个设置特定语言路由的路由组件。
@@ -722,257 +667,81 @@ const AppLocalized: FC<PropsWithChildren<{ locale: Locales }>> = ({
722
667
  export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
723
668
  <BrowserRouter>
724
669
  <Routes>
725
- {locales
726
- .filter(
727
- (locale) => middleware.prefixDefault || locale !== defaultLocale
728
- )
729
- .map((locale) => (
730
- <Route
731
- // 路由模式用于捕获语言环境(例如 /en/,/fr/)并匹配所有后续路径
732
- path={`/${locale}/*`}
733
- key={locale}
734
- element={<AppLocalized locale={locale}>{children}</AppLocalized>} // 使用语言环境管理包装子组件
735
- />
736
- ))}
737
-
738
- {
739
- // 如果禁用默认语言环境前缀,则直接在根路径渲染子组件
740
- !middleware.prefixDefault && (
741
- <Route
742
- path="*"
743
- element={
744
- <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
745
- } // 使用语言环境管理包装子组件
746
- />
747
- )
748
- }
670
+ {localeMap(({ locale, urlPrefix }) => (
671
+ <Route
672
+ // 路由模式用于捕获语言环境(例如 /en/,/fr/)并匹配所有后续路径
673
+ path={`${urlPrefix}/*`}
674
+ key={locale}
675
+ element={
676
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
677
+ } // 使用语言环境管理包装子组件
678
+ />
679
+ ))}
749
680
  </Routes>
750
681
  </BrowserRouter>
751
682
  );
752
683
  ```
753
684
 
754
685
  ```jsx fileName="src/components/LocaleRouter.mjx" codeFormat="esm"
755
- // 导入必要的依赖和函数
756
- import { configuration, getPathWithoutLocale } from "intlayer"; // 来自 'intlayer' 的工具函数和类型
757
- // 来自 'intlayer' 的工具函数和类型
758
- import { IntlayerProvider } from "react-intlayer"; // 国际化上下文的提供者
759
- import {
760
- BrowserRouter,
761
- Routes,
762
- Route,
763
- Navigate,
764
- useLocation,
765
- } from "react-router-dom"; // 用于管理导航的路由组件
766
-
767
- // 从 Intlayer 配置中解构
768
- const { internationalization, middleware } = configuration;
769
- const { locales, defaultLocale } = internationalization;
770
-
771
- /**
772
- * 一个处理本地化的组件,使用适当的语言环境上下文包裹子组件。
773
- /**
774
- * 它管理基于 URL 的语言检测和验证。
775
- */
776
- const AppLocalized = ({ children, locale }) => {
777
- const { pathname, search } = useLocation(); // 获取当前的 URL 路径
778
-
779
- // 确定当前语言,如果未提供则回退到默认语言
780
- const currentLocale = locale ?? defaultLocale;
781
-
782
- // 从路径中移除语言前缀以构造基础路径
783
- const pathWithoutLocale = getPathWithoutLocale(
784
- pathname // 当前 URL 路径
785
- );
786
-
787
- /**
788
- * 如果 middleware.prefixDefault 为 true,则默认语言应始终带有前缀。
789
- */
790
- if (middleware.prefixDefault) {
791
- // 验证语言
792
- if (!locale || !locales.includes(locale)) {
793
- // 重定向到带有更新路径的默认语言
794
- return (
795
- <Navigate
796
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
797
- replace // 替换当前的历史记录条目为新的条目
798
- />
799
- );
800
- }
801
-
802
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
803
- return (
804
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
805
- );
806
- } else {
807
- /**
808
- * 当 middleware.prefixDefault 为 false 时,默认语言环境不带前缀。
809
- * 确保当前语言环境有效且不是默认语言环境。
810
- */
811
- if (
812
- currentLocale.toString() !== defaultLocale.toString() &&
813
- !locales
814
- .filter(
815
- (locale) => locale.toString() !== defaultLocale.toString() // 排除默认语言环境
816
- )
817
- .includes(currentLocale) // 检查当前语言是否在有效语言列表中
818
- ) {
819
- // 重定向到不带语言前缀的路径
820
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
821
- }
822
-
823
- // 使用 IntlayerProvider 包裹子组件并设置当前语言
824
- return (
825
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
826
- );
827
- }
828
- };
686
+ import { localeMap } from 'intlayer'; // 来自 'intlayer' 的工具函数和类型
687
+ import type { FC, PropsWithChildren } from 'react'; // React 函数组件和属性类型
688
+ import { IntlayerProvider } from 'react-intlayer'; // 国际化上下文提供者
689
+ import { BrowserRouter, Route, Routes } from 'react-router-dom'; // 用于管理导航的路由组件
829
690
 
830
691
  /**
831
- * 一个设置特定语言路由的路由组件。
692
+ * 一个设置特定语言环境路由的路由组件。
832
693
  * 它使用 React Router 来管理导航并渲染本地化组件。
833
694
  */
834
- export const LocaleRouter = ({ children }) => (
695
+ export const LocaleRouter: FC<PropsWithChildren> = ({ children }) => (
835
696
  <BrowserRouter>
836
697
  <Routes>
837
- {locales
838
- .filter(
839
- (locale) => middleware.prefixDefault || locale !== defaultLocale
840
- )
841
- .map((locale) => (
842
- <Route
843
- // 路由模式用于捕获语言环境(例如 /en/,/fr/)并匹配所有后续路径
844
- path={`/${locale}/*`}
845
- key={locale}
846
- element={<AppLocalized locale={locale}>{children}</AppLocalized>} // 使用语言环境管理包装子组件
847
- />
848
- ))}
849
-
850
- {
851
- // 如果禁用默认语言环境的前缀,则直接在根路径渲染子组件
852
- !middleware.prefixDefault && (
853
- <Route
854
- path="*"
855
- element={
856
- <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
857
- } // 使用语言环境管理包装子组件
858
- />
859
- )
860
- }
698
+ {localeMap(({ locale, urlPrefix }) => (
699
+ <Route
700
+ // 路由模式用于捕获语言环境(例如 /en/,/fr/)并匹配所有后续路径
701
+ path={`${urlPrefix}/*`}
702
+ key={locale}
703
+ element={
704
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
705
+ } // 使用语言环境管理包装子组件
706
+ />
707
+ ))}
861
708
  </Routes>
862
709
  </BrowserRouter>
863
710
  );
864
711
  ```
865
712
 
866
713
  ```jsx fileName="src/components/LocaleRouter.cjx" codeFormat="commonjs"
867
- // 导入必要的依赖和函数
868
- const { configuration, getPathWithoutLocale } = require("intlayer"); // 来自 'intlayer' 的实用函数和类型
869
- const { IntlayerProvider, useLocale } = require("react-intlayer"); // 国际化上下文的提供者
870
- const {
871
- BrowserRouter,
872
- Routes,
873
- Route,
874
- Navigate,
875
- useLocation,
876
- } = require("react-router-dom"); // 用于管理导航的路由组件
877
-
878
- // 从 Intlayer 中解构配置
879
- const { internationalization, middleware } = configuration;
880
- const { locales, defaultLocale } = internationalization;
881
-
882
- /**
883
- * 一个处理本地化的组件,使用适当的语言环境上下文包裹子组件。
884
- * 它管理基于 URL 的语言环境检测和验证。
885
- */
886
- const AppLocalized = ({ children, locale }) => {
887
- const { pathname, search } = useLocation(); // 获取当前的 URL 路径
888
-
889
- // 确定当前的语言环境,如果未提供则使用默认语言环境
890
- const currentLocale = locale ?? defaultLocale;
891
-
892
- // 移除路径中的语言环境前缀以构建基础路径
893
- const pathWithoutLocale = getPathWithoutLocale(
894
- pathname // 当前的 URL 路径
895
- );
896
-
897
- /**
898
- * 如果 middleware.prefixDefault 为 true,则默认语言环境应始终带有前缀。
899
- */
900
- if (middleware.prefixDefault) {
901
- // 验证语言环境
902
- if (!locale || !locales.includes(locale)) {
903
- // 重定向到带有默认语言环境的更新路径
904
- return (
905
- <Navigate
906
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
907
- replace // 替换当前的历史记录条目为新的条目
908
- />
909
- );
910
- }
911
-
912
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
913
- return (
914
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
915
- );
916
- } else {
917
- /**
918
- * 当 middleware.prefixDefault 为 false 时,默认语言环境不带前缀。
919
- * 确保当前语言环境有效且不是默认语言环境。
920
- */
921
- if (
922
- currentLocale.toString() !== defaultLocale.toString() &&
923
- !locales
924
- .filter(
925
- (locale) => locale.toString() !== defaultLocale.toString() // 排除默认语言环境
926
- )
927
- .includes(currentLocale) // 检查当前语言环境是否在有效语言环境列表中
928
- ) {
929
- // 重定向到不带语言前缀的路径
930
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
931
- }
932
-
933
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
934
- return (
935
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
936
- );
937
- }
938
- };
714
+ const { localeMap } = require("intlayer"); // 来自 'intlayer' 的实用函数和类型
715
+ const React = require("react"); // 导入 React
716
+ const { IntlayerProvider } = require("react-intlayer"); // 国际化上下文的提供者
717
+ const { BrowserRouter, Route, Routes } = require("react-router-dom"); // 用于管理导航的路由组件
939
718
 
940
719
  /**
941
720
  * 一个设置特定语言环境路由的路由组件。
942
721
  * 它使用 React Router 来管理导航并渲染本地化组件。
943
722
  */
944
- const LocaleRouter = ({ children }) => (
945
- <BrowserRouter>
946
- <Routes>
947
- {locales
948
- .filter(
949
- (locale) => middleware.prefixDefault || locale !== defaultLocale
950
- )
951
- .map((locale) => (
952
- <Route
953
- // 路由模式用于捕获语言环境(例如 /en/,/fr/)并匹配所有后续路径
954
- path={`/${locale}/*`}
955
- key={locale}
956
- element={<AppLocalized locale={locale}>{children}</AppLocalized>} // 使用本地化管理包装子组件
957
- />
958
- ))}
723
+ const LocaleRouter = ({ children }) =>
724
+ React.createElement(
725
+ BrowserRouter,
726
+ {},
727
+ React.createElement(
728
+ Routes,
729
+ {},
730
+ localeMap(({ locale, urlPrefix }) =>
731
+ React.createElement(Route, {
732
+ path: `${urlPrefix}/*`,
733
+ key: locale,
734
+ element: React.createElement(IntlayerProvider, { locale }, children),
735
+ })
736
+ )
737
+ )
738
+ );
959
739
 
960
- {
961
- // 如果禁用默认语言前缀,则直接在根路径渲染子组件
962
- !middleware.prefixDefault && (
963
- <Route
964
- path="*"
965
- element={
966
- <AppLocalized locale={defaultLocale}>{children}</AppLocalized>
967
- } // 使用本地化管理包装子组件
968
- />
969
- )
970
- }
971
- </Routes>
972
- </BrowserRouter>
973
- );
740
+ exports.LocaleRouter = LocaleRouter;
974
741
  ```
975
742
 
743
+ > 注意:如果您使用 `routing.mode: 'no-prefix' | 'search-params'`,您可能不需要使用 `localeMap` 函数。
744
+
976
745
  然后,您可以在应用中使用 `LocaleRouter` 组件:
977
746
 
978
747
  ```tsx fileName="src/App.tsx" codeFormat="typescript"
@@ -1014,6 +783,8 @@ const App = () => (
1014
783
 
1015
784
  同时,您还可以使用 `intlayerProxy` 为您的应用程序添加服务器端路由。该插件将根据 URL 自动检测当前语言环境并设置相应的语言环境 Cookie。如果未指定语言环境,插件将根据用户浏览器的语言偏好确定最合适的语言环境。如果未检测到任何语言环境,它将重定向到默认语言环境。
1016
785
 
786
+ > 请注意,要在生产环境中使用 `intlayerProxy`,您需要将 `vite-intlayer` 包从 `devDependencies` 切换到 `dependencies`。
787
+
1017
788
  ```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
1018
789
  import { defineConfig } from "vite";
1019
790
  import react from "@vitejs/plugin-react-swc";
@@ -1300,7 +1071,7 @@ export const useI18nHTMLAttributes = () => {
1300
1071
 
1301
1072
  ```jsx fileName="src/hooks/useI18nHTMLAttributes.msx" codeFormat="esm"
1302
1073
  import { useEffect } from "react";
1303
- import { useLocale } from "react-intlayer";
1074
+ import { useLocale } from "intlayer";
1304
1075
  import { getHTMLTextDir } from "intlayer";
1305
1076
 
1306
1077
  /**
@@ -1308,7 +1079,7 @@ import { getHTMLTextDir } from "intlayer";
1308
1079
  * - `lang`:通知浏览器和搜索引擎页面的语言。
1309
1080
  * - `dir`:确保正确的阅读顺序(例如,英文为 'ltr',阿拉伯文为 'rtl')。
1310
1081
  *
1311
- * 此动态更新对于正确的文本渲染、无障碍访问和SEO至关重要。
1082
+ * 此动态更新对于正确的文本渲染、无障碍访问和 SEO 至关重要。
1312
1083
  */
1313
1084
  export const useI18nHTMLAttributes = () => {
1314
1085
  const { locale } = useLocale();
@@ -1350,32 +1121,6 @@ const useI18nHTMLAttributes = () => {
1350
1121
  module.exports = { useI18nHTMLAttributes };
1351
1122
  ```
1352
1123
 
1353
- #### 在您的应用程序中使用该 Hook
1354
-
1355
- 将该 Hook 集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
1356
-
1357
- ```tsx fileName="src/App.tsx" codeFormat="typescript"
1358
- import type { FC } from "react";
1359
- import { IntlayerProvider, useIntlayer } from "react-intlayer";
1360
- import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
1361
- import "./App.css";
1362
-
1363
- const AppContent: FC = () => {
1364
- // 应用该 Hook,根据当前语言环境更新 <html> 标签的 lang 和 dir 属性。
1365
- useI18nHTMLAttributes();
1366
-
1367
- // ... 组件的其余部分
1368
- };
1369
-
1370
- const App: FC = () => (
1371
- <IntlayerProvider>
1372
- <AppContent />
1373
- </IntlayerProvider>
1374
- );
1375
-
1376
- export default App;
1377
- ```
1378
-
1379
1124
  #### 在您的应用程序中使用 Hook
1380
1125
 
1381
1126
  将该 Hook 集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
@@ -1445,31 +1190,6 @@ const App = () => (
1445
1190
  module.exports = App;
1446
1191
  ```
1447
1192
 
1448
- 通过应用这些更改,您的应用程序将:
1449
-
1450
- - 确保 **语言** (`lang`) 属性正确反映当前语言环境,这对 SEO 和浏览器行为非常重要。
1451
- - 根据语言环境调整 **文本方向** (`dir`),提升对不同阅读顺序语言的可读性和可用性。
1452
- - 提供更 **无障碍** 的体验,因为辅助技术依赖这些属性以实现最佳功能。
1453
-
1454
- ### (可选)步骤 10:创建本地化链接组件
1455
-
1456
- ```tsx fileName="src/App.tsx" codeFormat="typescript"
1457
- // 应用该钩子以根据当前语言环境更新 <html> 标签的 lang 和 dir 属性。
1458
- useI18nHTMLAttributes();
1459
-
1460
- // ... 组件的其余部分
1461
- };
1462
-
1463
- const App = () => (
1464
- <IntlayerProvider>
1465
- <AppContent />
1466
- </IntlayerProvider>
1467
- );
1468
-
1469
- module.exports = App;
1470
-
1471
- ```
1472
-
1473
1193
  通过应用这些更改,您的应用将能够:
1474
1194
 
1475
1195
  - 确保 **语言** (`lang`) 属性正确反映当前的语言环境,这对于 SEO 和浏览器行为非常重要。
@@ -1497,11 +1217,10 @@ import {
1497
1217
  } from "react";
1498
1218
  import { useLocale } from "react-intlayer";
1499
1219
 
1500
- export interface LinkProps
1501
- extends DetailedHTMLProps<
1502
- AnchorHTMLAttributes<HTMLAnchorElement>,
1503
- HTMLAnchorElement
1504
- > {}
1220
+ export interface LinkProps extends DetailedHTMLProps<
1221
+ AnchorHTMLAttributes<HTMLAnchorElement>,
1222
+ HTMLAnchorElement
1223
+ > {}
1505
1224
 
1506
1225
  /**
1507
1226
  * 工具函数,用于检查给定的 URL 是否为外部链接。
@@ -1650,8 +1369,8 @@ Intlayer 使用模块增强(module augmentation)来利用 TypeScript 的优
1650
1369
 
1651
1370
  为此,您可以在 `.gitignore` 文件中添加以下指令:
1652
1371
 
1653
- ```plaintext
1654
- # 使用Intlayer翻译您的Vite and React | 国际化(i18n)
1372
+ ```plaintext fileName=".gitignore"
1373
+ # 忽略 Intlayer 生成的文件
1655
1374
  .intlayer
1656
1375
  ```
1657
1376
 
@@ -1675,5 +1394,3 @@ Intlayer 使用模块增强(module augmentation)来利用 TypeScript 的优
1675
1394
  ### 深入了解
1676
1395
 
1677
1396
  要进一步使用,您可以实现[可视化编辑器](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_visual_editor.md)或使用[内容管理系统(CMS)](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_CMS.md)将内容外部化。
1678
-
1679
- ---
@@ -22,6 +22,7 @@ slugs:
22
22
  - doc
23
23
  - plugin
24
24
  - sync-json
25
+ youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
25
26
  history:
26
27
  - version: 6.1.6
27
28
  date: 2025-10-05
@@ -30,6 +31,8 @@ history:
30
31
 
31
32
  ## 同步 JSON(i18n 桥接)
32
33
 
34
+ <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&amp;origin=http://intlayer.org&amp;controls=0&amp;rel=1"/>
35
+
33
36
  将 Intlayer 作为您现有 i18n 体系的附加组件使用。此插件可使您的 JSON 消息与 Intlayer 字典保持同步,从而您可以:
34
37
 
35
38
  - 继续使用 i18next、next-intl、react-intl、vue-i18n、next-translate、nuxt-i18n、Solid-i18next、svelte-i18n 等。
@@ -56,7 +56,7 @@ const config: IntlayerConfig = {
56
56
  لاحظ أنه إذا كنت تستخدم الخطاف `useLocale`، فسيتم استخدام خيار `availableLocales` لتحديد الوصول إلى قائمة اللغات.
57
57
 
58
58
  ```ts
59
- import { useLocale } from "intlayer";
59
+ import { useLocale } from "react-intlayer";
60
60
 
61
61
  const { availableLocales } = useLocale();
62
62
 
@@ -56,7 +56,7 @@ Seien Sie vorsichtig, alle in der Option `availableLocales` enthaltenen Sprachen
56
56
  Beachten Sie, dass wenn Sie den `useLocale` Hook verwenden, die Option `availableLocales` verwendet wird, um den Zugriff auf die Sprachliste festzulegen.
57
57
 
58
58
  ```ts
59
- import { useLocale } from "intlayer";
59
+ import { useLocale } from "react-intlayer";
60
60
 
61
61
  const { availableLocales } = useLocale();
62
62
 
@@ -56,7 +56,7 @@ Be careful, all locales included in the `availableLocales` option should be incl
56
56
  Note that if you use the `useLocale` hook, the `availableLocales` option will be used to set access to the locale list.
57
57
 
58
58
  ```ts
59
- import { useLocale } from "intlayer";
59
+ import { useLocale } from "react-intlayer";
60
60
 
61
61
  const { availableLocales } = useLocale();
62
62
 
@@ -56,7 +56,7 @@ Be cautious: all locales included in the `availableLocales` option should also b
56
56
  Note that if you use the `useLocale` hook, the `availableLocales` option will be used to set access to the locale list.
57
57
 
58
58
  ```ts
59
- import { useLocale } from "intlayer";
59
+ import { useLocale } from "react-intlayer";
60
60
 
61
61
  const { availableLocales } = useLocale();
62
62
 
@@ -56,7 +56,7 @@ Ten cuidado, todos los locales incluidos en la opción `availableLocales` deben
56
56
  Ten en cuenta que si usas el hook `useLocale`, la opción `availableLocales` se utilizará para establecer el acceso a la lista de locales.
57
57
 
58
58
  ```ts
59
- import { useLocale } from "intlayer";
59
+ import { useLocale } from "react-intlayer";
60
60
 
61
61
  const { availableLocales } = useLocale();
62
62