@intlayer/docs 5.8.0-canary.0 → 5.8.1-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/blog/ar/intlayer_with_next-i18next.md +2 -2
  2. package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +96 -219
  3. package/blog/ar/react-i18next_vs_react-intl_vs_intlayer.md +88 -129
  4. package/blog/ar/vue-i18n_vs_intlayer.md +268 -0
  5. package/blog/de/intlayer_with_next-i18next.md +2 -2
  6. package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  7. package/blog/de/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  8. package/blog/de/vue-i18n_vs_intlayer.md +268 -0
  9. package/blog/en/intlayer_with_next-i18next.md +2 -2
  10. package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  11. package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +88 -120
  12. package/blog/en/vue-i18n_vs_intlayer.md +276 -0
  13. package/blog/en-GB/intlayer_with_next-i18next.md +2 -2
  14. package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +85 -218
  15. package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +80 -130
  16. package/blog/en-GB/vue-i18n_vs_intlayer.md +258 -0
  17. package/blog/es/intlayer_with_next-i18next.md +2 -2
  18. package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  19. package/blog/es/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  20. package/blog/es/vue-i18n_vs_intlayer.md +268 -0
  21. package/blog/fr/intlayer_with_next-i18next.md +2 -2
  22. package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
  23. package/blog/fr/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
  24. package/blog/fr/vue-i18n_vs_intlayer.md +269 -0
  25. package/blog/hi/intlayer_with_next-i18next.md +2 -2
  26. package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +97 -220
  27. package/blog/hi/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
  28. package/blog/hi/vue-i18n_vs_intlayer.md +268 -0
  29. package/blog/it/intlayer_with_next-i18next.md +2 -2
  30. package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
  31. package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
  32. package/blog/it/vue-i18n_vs_intlayer.md +268 -0
  33. package/blog/ja/intlayer_with_next-i18next.md +2 -2
  34. package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  35. package/blog/ja/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  36. package/blog/ja/vue-i18n_vs_intlayer.md +268 -0
  37. package/blog/ko/intlayer_with_next-i18next.md +2 -2
  38. package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +95 -217
  39. package/blog/ko/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
  40. package/blog/ko/vue-i18n_vs_intlayer.md +268 -0
  41. package/blog/pt/intlayer_with_next-i18next.md +2 -2
  42. package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  43. package/blog/pt/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  44. package/blog/pt/vue-i18n_vs_intlayer.md +268 -0
  45. package/blog/ru/intlayer_with_next-i18next.md +2 -2
  46. package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +94 -217
  47. package/blog/ru/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  48. package/blog/ru/vue-i18n_vs_intlayer.md +268 -0
  49. package/blog/zh/intlayer_with_next-i18next.md +2 -2
  50. package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
  51. package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
  52. package/blog/zh/vue-i18n_vs_intlayer.md +269 -0
  53. package/dist/cjs/generated/blog.entry.cjs +41 -0
  54. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  55. package/dist/esm/generated/blog.entry.mjs +41 -0
  56. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  57. package/dist/types/generated/blog.entry.d.ts +1 -0
  58. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  59. package/docs/ar/formatters.md +417 -31
  60. package/docs/ar/how_works_intlayer.md +2 -4
  61. package/docs/ar/interest_of_intlayer.md +7 -10
  62. package/docs/ar/intlayer_CMS.md +2 -3
  63. package/docs/ar/intlayer_visual_editor.md +2 -3
  64. package/docs/ar/intlayer_with_tanstack.md +1 -1
  65. package/docs/ar/introduction.md +4 -4
  66. package/docs/de/formatters.md +444 -34
  67. package/docs/de/introduction.md +2 -2
  68. package/docs/en/dictionary/enumeration.md +2 -2
  69. package/docs/en/dictionary/function_fetching.md +2 -2
  70. package/docs/en/dictionary/get_started.md +2 -2
  71. package/docs/en/dictionary/translation.md +2 -2
  72. package/docs/en/formatters.md +383 -15
  73. package/docs/en/how_works_intlayer.md +2 -4
  74. package/docs/en/interest_of_intlayer.md +48 -29
  75. package/docs/en/intlayer_CMS.md +2 -3
  76. package/docs/en/intlayer_visual_editor.md +2 -3
  77. package/docs/en/intlayer_with_create_react_app.md +2 -2
  78. package/docs/en/intlayer_with_express.md +2 -2
  79. package/docs/en/intlayer_with_tanstack.md +1 -1
  80. package/docs/en/introduction.md +4 -4
  81. package/docs/en/packages/express-intlayer/index.md +2 -2
  82. package/docs/en/packages/intlayer/getConfiguration.md +2 -3
  83. package/docs/en/packages/intlayer/getEnumeration.md +2 -7
  84. package/docs/en/packages/intlayer/getHTMLTextDir.md +2 -4
  85. package/docs/en/packages/intlayer/getLocaleLang.md +2 -4
  86. package/docs/en/packages/intlayer/getLocaleName.md +2 -3
  87. package/docs/en/packages/intlayer/getLocalizedUrl.md +2 -8
  88. package/docs/en/packages/intlayer/getMultilingualUrls.md +2 -7
  89. package/docs/en/packages/intlayer/getPathWithoutLocale.md +2 -3
  90. package/docs/en/packages/intlayer/getTranslation.md +2 -4
  91. package/docs/en/packages/intlayer/index.md +2 -2
  92. package/docs/en/packages/next-intlayer/index.md +2 -2
  93. package/docs/en/packages/next-intlayer/t.md +2 -2
  94. package/docs/en/packages/next-intlayer/useDictionary.md +2 -2
  95. package/docs/en/packages/next-intlayer/useIntlayer.md +2 -2
  96. package/docs/en/packages/next-intlayer/useLocale.md +2 -2
  97. package/docs/en/packages/react-intlayer/index.md +2 -2
  98. package/docs/en/packages/react-intlayer/t.md +2 -2
  99. package/docs/en/packages/react-intlayer/useI18n.md +2 -2
  100. package/docs/en/packages/react-intlayer/useIntlayer.md +2 -2
  101. package/docs/en/packages/react-intlayer/useLocale.md +2 -2
  102. package/docs/en/packages/react-scripts-intlayer/index.md +2 -2
  103. package/docs/en/packages/solid-intlayer/index.md +2 -2
  104. package/docs/en/packages/vite-intlayer/index.md +2 -2
  105. package/docs/en-GB/formatters.md +402 -16
  106. package/docs/en-GB/how_works_intlayer.md +2 -4
  107. package/docs/en-GB/interest_of_intlayer.md +7 -10
  108. package/docs/en-GB/intlayer_with_tanstack.md +1 -1
  109. package/docs/en-GB/introduction.md +2 -2
  110. package/docs/es/formatters.md +438 -28
  111. package/docs/es/how_works_intlayer.md +2 -4
  112. package/docs/es/interest_of_intlayer.md +7 -10
  113. package/docs/es/intlayer_with_tanstack.md +1 -1
  114. package/docs/es/introduction.md +2 -2
  115. package/docs/fr/formatters.md +438 -28
  116. package/docs/fr/how_works_intlayer.md +2 -4
  117. package/docs/fr/interest_of_intlayer.md +7 -10
  118. package/docs/fr/intlayer_with_tanstack.md +1 -1
  119. package/docs/fr/introduction.md +2 -2
  120. package/docs/hi/formatters.md +430 -39
  121. package/docs/hi/how_works_intlayer.md +2 -4
  122. package/docs/hi/interest_of_intlayer.md +7 -10
  123. package/docs/hi/intlayer_with_tanstack.md +1 -1
  124. package/docs/hi/introduction.md +2 -2
  125. package/docs/it/formatters.md +438 -30
  126. package/docs/it/how_works_intlayer.md +2 -4
  127. package/docs/it/interest_of_intlayer.md +7 -10
  128. package/docs/it/intlayer_with_tanstack.md +1 -1
  129. package/docs/it/introduction.md +2 -2
  130. package/docs/ja/formatters.md +435 -47
  131. package/docs/ja/how_works_intlayer.md +2 -4
  132. package/docs/ja/interest_of_intlayer.md +7 -10
  133. package/docs/ja/intlayer_with_tanstack.md +1 -1
  134. package/docs/ja/introduction.md +2 -2
  135. package/docs/ko/formatters.md +432 -41
  136. package/docs/ko/how_works_intlayer.md +2 -4
  137. package/docs/ko/interest_of_intlayer.md +7 -10
  138. package/docs/ko/intlayer_with_tanstack.md +1 -1
  139. package/docs/ko/introduction.md +2 -2
  140. package/docs/pt/formatters.md +416 -30
  141. package/docs/pt/how_works_intlayer.md +2 -4
  142. package/docs/pt/intlayer_with_tanstack.md +1 -1
  143. package/docs/pt/introduction.md +2 -2
  144. package/docs/ru/autoFill.md +2 -2
  145. package/docs/ru/configuration.md +1 -40
  146. package/docs/ru/formatters.md +438 -28
  147. package/docs/ru/how_works_intlayer.md +5 -7
  148. package/docs/ru/index.md +1 -1
  149. package/docs/ru/interest_of_intlayer.md +8 -11
  150. package/docs/ru/intlayer_CMS.md +7 -8
  151. package/docs/ru/intlayer_cli.md +4 -7
  152. package/docs/ru/intlayer_visual_editor.md +5 -6
  153. package/docs/ru/intlayer_with_angular.md +1 -1
  154. package/docs/ru/intlayer_with_create_react_app.md +5 -5
  155. package/docs/ru/intlayer_with_lynx+react.md +1 -1
  156. package/docs/ru/intlayer_with_nextjs_15.md +3 -3
  157. package/docs/ru/intlayer_with_nextjs_page_router.md +2 -2
  158. package/docs/ru/intlayer_with_nuxt.md +1 -1
  159. package/docs/ru/intlayer_with_react_native+expo.md +2 -2
  160. package/docs/ru/intlayer_with_tanstack.md +3 -3
  161. package/docs/ru/intlayer_with_vite+preact.md +3 -3
  162. package/docs/ru/intlayer_with_vite+react.md +3 -3
  163. package/docs/ru/intlayer_with_vite+solid.md +1 -1
  164. package/docs/ru/intlayer_with_vite+svelte.md +1 -1
  165. package/docs/ru/intlayer_with_vite+vue.md +2 -2
  166. package/docs/ru/introduction.md +5 -5
  167. package/docs/ru/locale_mapper.md +1 -1
  168. package/docs/ru/packages/@intlayer/api/index.md +2 -2
  169. package/docs/ru/packages/@intlayer/chokidar/index.md +1 -1
  170. package/docs/ru/packages/@intlayer/cli/index.md +2 -2
  171. package/docs/ru/packages/@intlayer/config/index.md +2 -2
  172. package/docs/ru/packages/@intlayer/core/index.md +2 -2
  173. package/docs/ru/packages/@intlayer/design-system/index.md +2 -2
  174. package/docs/ru/packages/@intlayer/dictionary-entry/index.md +2 -2
  175. package/docs/ru/packages/@intlayer/editor/index.md +1 -1
  176. package/docs/ru/packages/@intlayer/editor-react/index.md +1 -1
  177. package/docs/ru/packages/@intlayer/webpack/index.md +1 -1
  178. package/docs/ru/packages/angular-intlayer/index.md +1 -1
  179. package/docs/ru/packages/express-intlayer/index.md +3 -3
  180. package/docs/ru/packages/express-intlayer/t.md +1 -1
  181. package/docs/ru/packages/intlayer/getEnumeration.md +3 -8
  182. package/docs/ru/packages/intlayer/getTranslation.md +3 -5
  183. package/docs/ru/packages/intlayer/getTranslationContent.md +1 -3
  184. package/docs/ru/packages/intlayer/index.md +3 -3
  185. package/docs/ru/packages/intlayer-cli/index.md +1 -1
  186. package/docs/ru/packages/intlayer-editor/index.md +2 -2
  187. package/docs/ru/packages/lynx-intlayer/index.md +1 -1
  188. package/docs/ru/packages/next-intlayer/index.md +4 -4
  189. package/docs/ru/packages/next-intlayer/t.md +4 -4
  190. package/docs/ru/packages/next-intlayer/useLocale.md +3 -3
  191. package/docs/ru/packages/nuxt-intlayer/index.md +1 -1
  192. package/docs/ru/packages/preact-intlayer/index.md +1 -1
  193. package/docs/ru/packages/react-intlayer/index.md +4 -4
  194. package/docs/ru/packages/react-intlayer/t.md +4 -4
  195. package/docs/ru/packages/react-native-intlayer/index.md +1 -1
  196. package/docs/ru/packages/react-scripts-intlayer/index.md +3 -3
  197. package/docs/ru/packages/solid-intlayer/index.md +3 -3
  198. package/docs/ru/packages/svelte-intlayer/index.md +1 -1
  199. package/docs/ru/packages/vite-intlayer/index.md +3 -3
  200. package/docs/ru/packages/vue-intlayer/index.md +1 -1
  201. package/docs/ru/per_locale_file.md +1 -1
  202. package/docs/ru/roadmap.md +3 -5
  203. package/docs/ru/vs_code_extension.md +1 -1
  204. package/docs/zh/formatters.md +446 -38
  205. package/docs/zh/how_works_intlayer.md +2 -4
  206. package/docs/zh/interest_of_intlayer.md +7 -10
  207. package/docs/zh/intlayer_with_tanstack.md +1 -1
  208. package/docs/zh/introduction.md +2 -2
  209. package/frequent_questions/ar/domain_routing.md +1 -1
  210. package/frequent_questions/en/domain_routing.md +1 -1
  211. package/frequent_questions/en-GB/domain_routing.md +1 -1
  212. package/frequent_questions/es/domain_routing.md +1 -1
  213. package/frequent_questions/fr/domain_routing.md +1 -1
  214. package/frequent_questions/hi/domain_routing.md +1 -1
  215. package/frequent_questions/it/domain_routing.md +1 -1
  216. package/frequent_questions/ko/domain_routing.md +1 -1
  217. package/frequent_questions/pt/domain_routing.md +1 -1
  218. package/frequent_questions/ru/domain_routing.md +1 -1
  219. package/frequent_questions/ru/get_locale_cookie.md +4 -4
  220. package/frequent_questions/ru/static_rendering.md +1 -2
  221. package/frequent_questions/zh/domain_routing.md +1 -1
  222. package/package.json +9 -11
  223. package/src/generated/blog.entry.ts +42 -1
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  createdAt: 2025-01-02
3
3
  updatedAt: 2025-06-29
4
- title: react-i18n vs react-intl vs Intlayer
5
- description: react-i18nextnext-intl和Intlayer
4
+ title: react-i18next vs react-intl vs Intlayer
5
+ description: react-i18nextnext-intl Intlayer 集成,用于 React 应用的国际化 (i18n)
6
6
  keywords:
7
7
  - next-intl
8
8
  - react-i18next
9
9
  - Intlayer
10
10
  - 国际化
11
- - 文档
11
+ - 博客
12
12
  - Next.js
13
13
  - JavaScript
14
14
  - React
@@ -17,178 +17,137 @@ slugs:
17
17
  - react-i18next-vs-react-intl-vs-intlayer
18
18
  ---
19
19
 
20
- # React-Intl React-i18next Intlayer | React 国际化 (i18n)
20
+ # react-Intl VS react-i18next VS intlayer | React 国际化 (i18n)
21
21
 
22
- 以下是三个流行的 i18n(国际化)库在 React 中的简明比较:**React-Intl**、**React-i18next** **Intlayer**。每个库都为在您的 React 应用中集成多语言支持提供了独特的功能和工作流程。阅读完本文后,您应该能够决定哪个解决方案最符合您的需求。
22
+ 本指南比较了三种成熟的 **React** 国际化方案:**react-intl**(FormatJS)、**react-i18next**(i18next)和 **Intlayer**。
23
+ 我们重点关注 **纯 React** 应用(例如 Vite、CRA、SPA)。如果您使用的是 Next.js,请参阅我们专门的 Next.js 比较。
23
24
 
24
- ---
25
-
26
- ## 1. 介绍
27
-
28
- 在 React 应用中实现国际化 (i18n) 有多种方式。这里介绍的三种库有不同的设计理念、功能集和社区支持:
25
+ 我们将评估:
29
26
 
30
- 1. **React-Intl**
31
- 2. **React-i18next**
32
- 3. **Intlayer**
27
+ - 架构与内容组织
28
+ - TypeScript 与安全性
29
+ - 缺失翻译的处理
30
+ - 丰富的内容与格式化能力
31
+ - 性能与加载行为
32
+ - 开发者体验(DX)、工具链与维护
33
+ - SEO/路由(依赖框架)
33
34
 
34
- 下面,您将找到每个解决方案的概述,随后是功能比较、优缺点以及示例用例。
35
+ > **简而言之**:这三者都能实现 React 应用的本地化。如果您需要**组件范围的内容**、**严格的 TypeScript 类型**、**构建时缺失键检查**、**支持 Tree-shaking 的字典**,以及内置的编辑工具(可视化编辑器/CMS + 可选的 AI 翻译),那么 **Intlayer** 是模块化 React 代码库中最完整的选择。
35
36
 
36
37
  ---
37
38
 
38
- ## 2. React-Intl
39
-
40
- ### 概述
41
-
42
- [**React-Intl**](https://formatjs.io/docs/react-intl/) 是 [FormatJS](https://formatjs.io/) 套件的一部分。它提供了一套强大的 **API 和组件** 来处理消息格式化、复数形式、日期/时间和数字格式化。React-Intl 在企业应用中被广泛使用,主要是因为它是标准化消息语法和格式化的生态系统的一部分。
43
-
44
- ### 主要特性
45
-
46
- - **ICU 消息语法**:提供全面的语法来处理消息插值、复数形式等。
47
- - **本地化格式化**:内置工具根据地区格式化日期、时间、数字和相对时间。
48
- - **声明式组件**:提供 `<FormattedMessage>`、`<FormattedNumber>`、`<FormattedDate>` 等,以便在 JSX 中无缝使用。
49
- - **丰富的生态系统**:与 FormatJS 工具(例如 [babel-plugin-react-intl](https://formatjs.io/docs/tooling/babel-plugin/))良好集成,用于提取、管理和编译消息。
50
-
51
- ### 典型工作流程
52
-
53
- 1. **定义消息目录**(通常是每个地区的 JSON 文件)。
54
- 2. **在 `<IntlProvider locale="zh" messages={messages}>` 中包装您的应用**。
55
- 3. **使用** `<FormattedMessage id="myMessage" defaultMessage="你好,世界" />` 或 `useIntl()` 钩子来访问翻译字符串。
56
-
57
- ### 优点
58
-
59
- - 成熟且在许多生产环境中使用。
60
- - 高级消息格式化,包括复数形式、性别、时区等。
61
- - 对消息提取和编译的强大工具支持。
62
-
63
- ### 缺点
39
+ ## 高层定位
64
40
 
65
- - 需要熟悉 **ICU 消息格式**,这可能比较冗长。
66
- - 处理动态或复杂翻译(不只是字符串)的方式不直观。
41
+ - **react-intl** - 以 ICU 为先,符合标准的格式化(日期/数字/复数),拥有成熟的 API。目录通常是集中管理的;键的安全性和构建时验证主要由你负责。
42
+ - **react-i18next** - 极其流行且灵活;支持命名空间、检测器和许多插件(ICU、后端等)。功能强大,但随着项目规模扩大,配置可能变得复杂。
43
+ - **Intlayer** - 面向组件的 React 内容模型,**严格的 TS 类型**,**构建时检查**,**支持 Tree-shaking**,以及 **可视化编辑器/CMS** 和 **AI 辅助翻译**。兼容 React Router、Vite、CRA 等。
67
44
 
68
45
  ---
69
46
 
70
- ## 3. React-i18next
47
+ ## 功能矩阵(React 重点)
48
+
49
+ | 功能 | `react-intlayer` (Intlayer) | `react-i18next` (i18next) | `react-intl` (FormatJS) |
50
+ | -------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------- |
51
+ | **组件附近的翻译** | ✅ 是,内容与每个组件共置 | ❌ 否 | ❌ 否 |
52
+ | **TypeScript 集成** | ✅ 高级,自动生成严格类型 | ⚠️ 基础;需要额外配置以保证安全 | ✅ 良好,但不够严格 |
53
+ | **缺失翻译检测** | ✅ TypeScript 错误高亮和构建时错误/警告 | ⚠️ 主要是运行时回退字符串 | ⚠️ 回退字符串 |
54
+ | **丰富内容(JSX/Markdown/组件)** | ✅ 直接支持 | ⚠️ 有限 / 仅插值 | ⚠️ ICU 语法,不是真正的 JSX |
55
+ | **AI 驱动的翻译** | ✅ 是,支持多个 AI 提供商。可使用您自己的 API 密钥。考虑到您的应用程序和内容范围的上下文 | ❌ 否 | ❌ 否 |
56
+ | **可视化编辑器** | ✅ 是,本地可视化编辑器 + 可选 CMS;可以外部化代码库内容;可嵌入 | ❌ 否 / 通过外部本地化平台提供 | ❌ 否 / 通过外部本地化平台提供 |
57
+ | **本地化路由** | ✅ 是,开箱即用支持本地化路径(兼容 Next.js 和 Vite) | ⚠️ 无内置支持,需要插件(例如 `next-i18next`)或自定义路由配置 | ❌ 否,仅支持消息格式化,路由需手动管理 |
58
+ | **动态路由生成** | ✅ 是 | ⚠️ 依赖插件/生态系统或手动设置 | ❌ 不提供 |
59
+ | **复数形式处理** | ✅ 基于枚举的模式 | ✅ 可配置(如 i18next-icu 插件) | ✅ (ICU) |
60
+ | **格式化(日期、数字、货币)** | ✅ 优化的格式化器(底层使用 Intl) | ⚠️ 通过插件或自定义 Intl 使用 | ✅ ICU 格式化器 |
61
+ | **内容格式** | ✅ .tsx, .ts, .js, .json, .md, .txt, (.yaml 进行中) | ⚠️ .json | ✅ .json, .js |
62
+ | **ICU 支持** | ⚠️ 进行中 | ⚠️ 通过插件(如 i18next-icu) | ✅ 是 |
63
+ | **SEO 辅助工具(hreflang,网站地图)** | ✅ 内置工具:网站地图、robots.txt、元数据辅助工具 | ⚠️ 社区插件/手动 | ❌ 非核心功能 |
64
+ | **生态系统 / 社区** | ⚠️ 较小但增长迅速且反应灵敏 | ✅ 最大且成熟 | ✅ 大型 |
65
+ | **服务器端渲染与服务器组件** | ✅ 支持,针对 SSR / React 服务器组件进行了优化 | ⚠️ 支持页面级别,但需要在组件树上传递 t 函数给子服务器组件 | ❌ 不支持,需要在组件树上传递 t 函数给子服务器组件 |
66
+ | **Tree-shaking(仅加载使用的内容)** | ✅ 支持,通过 Babel/SWC 插件在构建时按组件进行优化 | ⚠️ 通常加载全部(可通过命名空间/代码拆分进行改进) | ⚠️ 通常加载全部 |
67
+ | **懒加载** | ✅ 是的,按语言环境 / 按词典 | ✅ 是的(例如,按需加载后端/命名空间) | ✅ 是的(拆分语言包) |
68
+ | **清除未使用内容** | ✅ 是的,按词典在构建时 | ❌ 否,仅通过手动命名空间分割 | ❌ 否,所有声明的消息都会被打包 |
69
+ | **大型项目管理** | ✅ 鼓励模块化,适合设计系统 | ⚠️ 需要良好的文件管理 | ⚠️ 中央目录可能变得庞大 |
71
70
 
72
- ### 概述
73
-
74
- [**React-i18next**](https://react.i18next.com/) 是 [i18next](https://www.i18next.com/) 的 React 扩展,是最流行的 JavaScript i18n 框架之一。它提供了 **广泛的特性** 用于运行时翻译、懒加载和语言检测,使其对于各种用例极其灵活。
75
-
76
- ### 主要特性
77
-
78
- - **灵活的翻译结构**:不绑定于像 ICU 这样的单一格式。您可以将翻译存储在 JSON 中,使用插值、复数形式等。
79
- - **动态语言切换**:内置语言检测插件和运行时更新。
80
- - **嵌套和结构化翻译**:可以轻松地将翻译嵌套在 JSON 中。
81
- - **广泛的插件生态系统**:用于检测(浏览器、路径、子域等)、资源加载、缓存等。
82
-
83
- ### 典型工作流程
84
-
85
- 1. **安装 `i18next` 和 `react-i18next`。**
86
- 2. **配置 i18n** 加载翻译(JSON)并设置语言检测或回退。
87
- 3. **在 `I18nextProvider` 中包装您的应用**。
88
- 4. **使用 `useTranslation()` 钩子** 或 `<Trans>` 组件来显示翻译。
71
+ ---
89
72
 
90
- ### 优点
73
+ ## 深度比较
91
74
 
92
- - 高度 **灵活** 和功能丰富。
93
- - 非常活跃的社区和大量插件生态系统。
94
- - 轻松 **动态加载** 翻译(例如,从服务器按需加载)。
75
+ ### 1) 架构与可扩展性
95
76
 
96
- ### 缺点
77
+ - **react-intl / react-i18next**:大多数配置保持每种语言的**集中式本地化文件夹**,有时按**命名空间**(i18next)拆分。早期效果良好,但随着应用增长,成为共享的表面区域。
78
+ - **Intlayer**:提倡与其所服务的 UI **共置** 的 **每组件(或每功能)字典**。这保持了所有权的清晰,便于组件的复制/迁移,并减少跨团队的键变动。未使用的内容更容易识别和删除。
97
79
 
98
- - **配置可能比较冗长**,尤其是如果您有更高级的需求。
99
- - 如果您希望严格类型的翻译,可能需要额外的 TypeScript 设置。
80
+ **重要原因:** 模块化内容反映模块化 UI。当翻译与其所属组件共存时,大型 React 代码库会保持更整洁。
100
81
 
101
82
  ---
102
83
 
103
- ## 4. Intlayer
84
+ ### 2) TypeScript 与安全性
104
85
 
105
- ### 概述
86
+ - **react-intl**:类型定义扎实,但**没有自动键类型**;你需要自己强制安全模式。
87
+ - **react-i18next**:为钩子提供强类型;**严格的键类型**通常需要额外配置或生成器。
88
+ - **Intlayer**:**从您的内容自动生成严格类型**。IDE 自动完成和**编译时错误**可以在运行时之前捕获拼写错误和缺失的键。
106
89
 
107
- [**Intlayer**](https://github.com/aymericzip/intlayer) 是一个较新的开源 i18n 库,专注于 **组件级内容声明**、类型安全和 **动态路由**。它专为现代 React 工作流设计,支持 **Create React App** 和 **Vite** 设置。它还包括高级功能,如 **基于区域的路由** 和 **自动生成的 TypeScript 类型** 用于翻译。
90
+ **重要原因:** 将失败“左移”(到构建/CI阶段)可以减少生产环境问题并加快开发者反馈循环。
108
91
 
109
- ### 主要特性
92
+ ---
110
93
 
111
- - **声明性内容文件**:每个组件或模块可以在专用的 `.content.tsx` 或 `.content.json` 文件中声明其翻译,将内容紧邻使用处。
112
- - **内置路由和中间件**:可选模块用于本地化路由(例如,`/zh/about`、`/fr/about`)和用于检测用户区域的服务器中间件。
113
- - **自动生成的 TypeScript 类型**:通过自动完成功能和编译时错误检测,确保类型安全。
114
- - **动态和丰富的翻译**:可以在翻译中包含 JSX/TSX 以应对更复杂的用例(例如,链接、加粗文本、翻译中的图标)。
94
+ ### 3) 缺失翻译处理
115
95
 
116
- ### 典型工作流程
96
+ - **react-intl / react-i18next**:默认使用**运行时回退**(键回显或默认语言)。您可以添加代码检查/插件,但构建时不保证检测。
97
+ - **Intlayer**:通过**构建时检测**,在缺少必需的语言或键时发出警告或错误。
117
98
 
118
- 1. **安装 `intlayer` 和 `react-intlayer`。**
119
- 2. **创建 `intlayer.config.ts`** 定义可用的区域和默认区域。
120
- 3. **使用 Intlayer CLI** 或插件来 **转译** 内容声明。
121
- 4. **在 `<IntlayerProvider>` 中包装您的应用** 并使用 `useIntlayer("keyName")` 获取内容。
99
+ **重要原因:** CI 在缺失字符串时失败,防止“神秘的英文”泄漏到非英文界面中。
122
100
 
123
- ### 优点
101
+ ---
124
102
 
125
- - **TypeScript 友好**,具有内置类型生成和错误检查。
126
- - 可能 **丰富的内容**(例如,将 React 节点传递作为翻译)。
127
- - **开箱即用的本地化路由**。
128
- - 与流行的构建工具(CRA、Vite)集成,易于设置。
103
+ ### 4) 丰富内容与格式化
129
104
 
130
- ### 缺点
105
+ - **react-intl**:对复数、选择、日期/数字和消息组合提供出色的 **ICU** 支持。可以使用 JSX,但思维模型仍以消息为中心。
106
+ - **react-i18next**:灵活的插值和用于嵌入元素/组件的 **`<Trans>`** 组件;通过插件支持 ICU。
107
+ - **Intlayer**:内容文件可以包含 **丰富节点**(JSX/Markdown/组件)和 **元数据**。格式化底层使用 Intl;复数模式设计符合人体工学。
131
108
 
132
- - React-Intl React-i18next 相比仍然 **相对较新**。
133
- - 更加注重“组件级内容声明”的方法, , 可能与典型的 .json 目录有一定差异。
134
- - 与更成熟的库相比,生态系统和社区较小。
109
+ **重要原因:** 当库能够干净地支持 React 节点时,处理复杂的 UI 文本(链接、加粗部分、内联组件)会更加轻松。
135
110
 
136
111
  ---
137
112
 
138
- ## 5. 功能比较
113
+ ### 5) 性能与加载行为
114
+
115
+ - **react-intl / react-i18next**:您通常需要手动管理**目录拆分**和**懒加载**(命名空间/动态导入)。这种方式有效但需要严格的规范。
116
+ - **Intlayer**:自动**摇树优化**未使用的字典,并开箱即用地支持**按字典/按语言的懒加载**。
139
117
 
140
- | **特性** | **React-Intl** | **React-i18next** | **Intlayer** |
141
- | ------------------- | ----------------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
142
- | **主要用例** | 基于字符串的翻译,日期/数字格式化,ICU 消息语法 | 全功能 i18n,易于动态切换、嵌套、插件生态系统 | 强类型翻译,聚焦于声明式内容、本地化路由和可选的服务器中间件 |
143
- | **方法** | 使用 `<IntlProvider>` 和 FormatJS 消息组件 | 使用 `I18nextProvider` 和 `useTranslation()` 钩子 | 使用 `<IntlayerProvider>` 和 `useIntlayer()` 钩子以及内容声明 |
144
- | **本地化格式** | 基于 ICU 的字符串(JSON 或 JavaScript 目录) | JSON 资源文件(或自定义加载程序)。ICU 格式可通过 i18next 插件选择 | `.content.[ts/js/tsx]` 或 JSON 声明;可以包含字符串或 React 组件 |
145
- | **路由** | 由外部处理(没有内置的本地化路由机制) | 通过 i18next 插件(路径、子域检测等)外部处理 | 内置支持本地化路由(如 `/zh/about`、`/fr/about`),以及可选的服务器中间件(用于 SSR/Vite) |
146
- | **TypeScript 支持** | 良好(官方包的类型定义) | 良好,但如果您希望严格检查类型翻译,则需要额外的配置 | 优秀(自动生成内容键和翻译的类型定义) |
147
- | **复数和格式化** | 高级:內置日期/时间/数字格式化、复数/性别支持 | 可配置的复数形式。日期/时间格式化通常通过外部库或 i18next 插件完成 | 可以依赖标准 JavaScript Intl 或将逻辑嵌入内容中。虽然不如 FormatJS 专业,但能处理典型案例。 |
148
- | **社区和生态系统** | 大,属于 FormatJS 生态系统 | 非常大,活跃,插件众多(检测、缓存、框架等) | 较小但正在成长;开源,现代方法 |
149
- | **学习曲线** | 中等(学习 ICU 消息语法,FormatJS 规范) | 低到中等(使用比较简单,但高级配置可能会变得冗长) | 中等(内容声明的概念和专业构建步骤) |
118
+ **重要性说明:** 更小的包体积和更少的未使用字符串能提升启动和导航性能。
150
119
 
151
120
  ---
152
121
 
153
- ## 6. 何时选择每种
122
+ ### 6) 开发体验(DX)、工具链与维护
154
123
 
155
- 1. **React-Intl**
124
+ - **react-intl / react-i18next**:拥有广泛的社区生态系统;对于编辑工作流,通常采用外部本地化平台。
125
+ - **Intlayer**:提供免费的**可视化编辑器**和**可选的内容管理系统(CMS)**(内容可保存在 Git 中或外部化)。还提供用于内容创作的**VSCode 扩展**,以及使用您自己的提供商密钥进行的**AI 辅助翻译**。
156
126
 
157
- - 您需要 **强大的格式化** 用于日期/时间/数字,和强大的 **ICU 消息语法**。
158
- - 您更倾向于使用“**基于标准**”的方法进行翻译。
159
- - 您不需要本地化路由或强类型的翻译键。
127
+ **重要原因:** 内置工具缩短了开发者与内容作者之间的反馈周期--减少了胶水代码,降低了对第三方依赖的需求。
160
128
 
161
- 2. **React-i18next**
129
+ ---
162
130
 
163
- - 您需要一个 **灵活、成熟** 的解决方案,具有 **动态** 和 **按需** 加载翻译的功能。
164
- - 您希望使用 **基于插件** 的语言检测(例如,从 URL、Cookies、本地存储等)或高级缓存。
165
- - 您需要最大的生态系统,具有针对各种框架(如 Next.js、React Native 等)的许多现有集成。
131
+ ## 何时选择哪种方案?
166
132
 
167
- 3. **Intlayer**
168
- - 您希望 **强类型** **自动生成类型** 的集成,确保您很少遗漏翻译键。
169
- - 您更喜欢将 **内容声明** 紧邻组件,可能包含 React 节点或在翻译中使用高级逻辑。
170
- - 您需要 **内置本地化路由** 或想要轻松将其纳入您的 SSR 或 Vite 设置。
171
- - 您希望采用现代方法或简单地希望拥有一个覆盖 **内容管理**(i18n)和 **路由** 的类型安全的库。
133
+ - 如果您需要**以 ICU 为优先**的消息格式化,且希望使用简洁、符合标准的 API,并且您的团队能够手动维护目录和安全检查,**请选择 react-intl**。
134
+ - 如果您需要**i18next 生态系统的广泛支持**(检测器、后端、ICU 插件、集成等),并且愿意接受更多配置以获得更高灵活性,**请选择 react-i18next**。
135
+ - **选择 Intlayer** 如果你重视 **组件范围的内容管理**、**严格的 TypeScript 类型检查**、**构建时保证**、**摇树优化**,以及 **开箱即用** 的编辑工具 -- 尤其适用于 **大型、模块化** 的 React 应用。
172
136
 
173
137
  ---
174
138
 
175
- ## 7. 结论
176
-
177
- 每个库都为国际化 React 应用程序提供了强大的解决方案:
178
-
179
- - **React-Intl** 在消息格式化方面表现优异,是专注于 ICU 消息语法的企业解决方案的热门选择。
180
- - **React-i18next** 为高级或动态 i18n 需求提供了高度灵活和插件驱动的环境。
181
- - **Intlayer** 提供了 **现代、强类型** 的方法,结合了内容声明、高级的本地化路由和基于插件的(CRA,Vite)集成。
139
+ ## 实用迁移建议(react-intl / react-i18next → Intlayer)
182
140
 
183
- 您的选择在很大程度上取决于项目需求、期望的开发人员体验(DX)以及类型翻译或高级路由的重要程度。如果您重视内置的本地化路由和 TypeScript 集成,**Intlayer** 可能最具吸引力。如果您想要一个经过考验的、生态系统丰富的解决方案,**React-i18next** 是一个不错的选择。对于直接的 ICU 基于格式化的需求,**React-Intl** 是一个可靠的选择。
141
+ - **渐进迁移**:从一个功能或路由开始;在过渡期间并行保留旧版目录。
142
+ - **采用每组件字典**:将内容与组件共置,减少耦合。
143
+ - **启用严格检查**:让构建时错误提前暴露缺失的键/语言,便于 CI 早期发现。
144
+ - **测量包体积**:预期未使用的字符串被剔除后包体积会减小。
184
145
 
185
146
  ---
186
147
 
187
- ### 进一步阅读
148
+ ## 结论
188
149
 
189
- - [React-Intl 文档](https://formatjs.io/docs/react-intl/)
190
- - [React-i18next 文档](https://react.i18next.com/)
191
- - [Intlayer + CRA 开始指南](#)(来自您的文档)
192
- - [Intlayer + Vite 和 React 开始指南](#)(来自您的文档)
150
+ 所有三个库都能有效地实现 React 的本地化。区别在于你需要构建多少**基础设施**,才能达到一个**安全、可扩展**的环境:
193
151
 
194
- 随意混合和匹配这些方法以满足您的需求, , 没有“放之四海而皆准”的解决方案,每个库都在不断发展,以应对 React 生态系统中的新用例。
152
+ - 使用 **Intlayer**,**模块化内容**、**严格的 TS 类型检查**、**构建时安全性**、**摇树优化的包**以及**编辑工具**都是默认配置,而非额外负担。
153
+ - 如果你的团队重视多语言、组件驱动的 React 应用中的**可维护性和速度**,Intlayer 提供了目前**最完整**的开发者和内容工作流。
@@ -0,0 +1,269 @@
1
+ ---
2
+ createdAt: 2024-08-11
3
+ updatedAt: 2025-08-23
4
+ title: vue-i18n 与 Intlayer 对比
5
+ description: 比较 vue-i18n 与 Intlayer 在 Vue/Nuxt 应用中的国际化 (i18n) 方案
6
+ keywords:
7
+ - vue-i18n
8
+ - Intlayer
9
+ - 国际化
10
+ - i18n
11
+ - 博客
12
+ - Vue
13
+ - Nuxt
14
+ - JavaScript
15
+ slugs:
16
+ - blog
17
+ - vue-i18n-vs-intlayer
18
+ ---
19
+
20
+ # vue-i18n VS Intlayer | Vue 国际化 (i18n)
21
+
22
+ 本指南比较了两个流行的 **Vue 3**(及 **Nuxt**)国际化选项:**vue-i18n** 和 **Intlayer**。
23
+ 我们聚焦于现代 Vue 工具链(Vite,Composition API),并评估:
24
+
25
+ 1. **架构与内容组织**
26
+ 2. **TypeScript 与安全性**
27
+ 3. **缺失翻译处理**
28
+ 4. **路由与 URL 策略**
29
+ 5. **性能与加载行为**
30
+ 6. **开发者体验 (DX)、工具链与维护**
31
+ 7. **SEO 与大型项目的可扩展性**
32
+
33
+ > **简而言之**:两者都能实现 Vue 应用的本地化。如果你需要**组件范围的内容**、**严格的 TypeScript 类型**、**构建时缺失键检查**、**支持 Tree-shaking 的字典**,以及**内置的路由/SEO 辅助工具**,再加上**可视化编辑器和 AI 翻译**,那么 **Intlayer** 是更完整、更现代的选择。
34
+
35
+ ---
36
+
37
+ ## 高层定位
38
+
39
+ - **vue-i18n** - Vue 的事实标准国际化库。支持灵活的消息格式(ICU 风格)、单文件组件(SFC)中的 `<i18n>` 块用于本地消息,并拥有庞大的生态系统。安全性和大规模维护主要依赖开发者自身。
40
+ - **Intlayer** - 面向组件的内容模型,适用于 Vue/Vite/Nuxt,具备**严格的 TypeScript 类型检查**、**构建时校验**、**摇树优化**、**路由和 SEO 辅助工具**,可选的**可视化编辑器/CMS**,以及**AI 辅助翻译**。
41
+
42
+ ---
43
+
44
+ ## 并列功能对比(Vue 重点)
45
+
46
+ | 功能 | **Intlayer** | **vue-i18n** |
47
+ | -------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------- |
48
+ | **组件附近的翻译** | ✅ 是,内容与组件共置(例如,`MyComp.content.ts`) | ✅ 是,通过 SFC `<i18n>` 块(可选) |
49
+ | **TypeScript 集成** | ✅ 高级,自动生成 **严格** 类型和键自动补全 | ✅ 良好的类型定义;**严格的键安全性需要额外的设置/规范** |
50
+ | **缺失翻译检测** | ✅ **构建时** 警告/错误和 TS 显示 | ⚠️ 运行时回退/警告 |
51
+ | **丰富内容(组件/Markdown)** | ✅ 直接支持丰富节点和Markdown内容文件 | ⚠️ 有限支持(组件通过`<i18n-t>`,Markdown通过外部插件) |
52
+ | **AI驱动的翻译** | ✅ 内置使用您自己的AI提供商密钥的工作流程 | ❌ 未内置 |
53
+ | **可视化编辑器 / CMS** | ✅ 免费的可视化编辑器和可选的CMS | ❌ 未内置(使用外部平台) |
54
+ | **本地化路由** | ✅ 为 Vue Router/Nuxt 提供生成本地化路径、URL 和 `hreflang` 的辅助工具 | ⚠️ 非核心功能(使用 Nuxt i18n 或自定义 Vue Router 配置) |
55
+ | **动态路由生成** | ✅ 支持 | ❌ 不提供(由 Nuxt i18n 提供) |
56
+ | **复数化与格式化** | ✅ 枚举模式;基于 Intl 的格式化工具 | ✅ ICU 风格消息;Intl 格式化工具 |
57
+ | **内容格式** | ✅ `.ts`、`.js`、`.json`、`.md`、`.txt`(YAML 进行中) | ✅ `.json`、`.js`(加上 SFC `<i18n>` 块) |
58
+ | **ICU 支持** | ⚠️ 进行中 | ✅ 支持 |
59
+ | **SEO 辅助工具(站点地图、robots、元数据)** | ✅ 内置辅助工具(框架无关) | ❌ 非核心功能(Nuxt i18n/社区提供) |
60
+ | **SSR/SSG** | ✅ 支持 Vue SSR 和 Nuxt;不阻塞静态渲染 | ✅ 支持 Vue SSR/Nuxt |
61
+ | **Tree-shaking(仅打包使用的内容)** | ✅ 构建时按组件进行 | ⚠️ 部分支持;需要手动代码拆分/异步消息 |
62
+ | **懒加载** | ✅ 按语言/词典级别 | ✅ 支持异步语言消息 |
63
+ | **清理未使用内容** | ✅ 是(构建时) | ❌ 非内置功能 |
64
+ | **大型项目可维护性** | ✅ 鼓励模块化、设计系统友好的结构 | ✅ 可行,但需要严格的文件/命名空间管理 |
65
+ | **生态系统 / 社区** | ⚠️ 较小但增长迅速 | ✅ Vue 生态系统中庞大且成熟 |
66
+
67
+ ---
68
+
69
+ ## 深度比较
70
+
71
+ ### 1) 架构与可扩展性
72
+
73
+ - **vue-i18n**:常见的设置是为每个语言环境使用**集中式目录**(可选地拆分为文件/命名空间)。SFC `<i18n>` 块允许局部消息,但随着项目增长,团队通常会回归使用共享目录。
74
+ - **Intlayer**:提倡将**每个组件的字典**存储在其对应组件旁边。这减少了跨团队冲突,保持内容可发现性,并自然限制了漂移/未使用的键。
75
+
76
+ **重要原因:** 在大型 Vue 应用或设计系统中,**模块化内容**比单体目录更易于扩展。
77
+
78
+ ---
79
+
80
+ ### 2) TypeScript 与安全性
81
+
82
+ - **vue-i18n**:良好的 TS 支持;**严格键类型**通常需要自定义模式/泛型和谨慎的约定。
83
+ - **Intlayer**:从您的内容中**生成严格类型**,提供**IDE 自动补全**和针对拼写错误/缺失键的**编译时错误**。
84
+
85
+ **重要性说明:** 强类型可以在**运行前**捕获问题。
86
+
87
+ ---
88
+
89
+ ### 3) 缺失翻译处理
90
+
91
+ - **vue-i18n**:**运行时**警告/回退(例如,回退到默认语言或键)。
92
+ - **Intlayer**:通过**构建时**检测,针对不同语言和键发出警告/错误。
93
+
94
+ **重要性说明:** 构建时强制执行确保生产环境界面干净且一致。
95
+
96
+ ---
97
+
98
+ ### 4) 路由与 URL 策略(Vue Router/Nuxt)
99
+
100
+ - **两者**都支持本地化路由。
101
+ - **Intlayer** 提供辅助工具来 **生成本地化路径**,**管理语言前缀**,并为 SEO 生成 **`<link rel="alternate" hreflang>`** 标签。在 Nuxt 中,它补充了框架的路由功能。
102
+
103
+ **重要性:** 减少自定义粘合层,实现跨语言环境的 **更清晰的 SEO**。
104
+
105
+ ---
106
+
107
+ ### 5) 性能与加载行为
108
+
109
+ - **vue-i18n**:支持异步加载语言消息;避免过度打包需要你自行管理(需谨慎拆分目录)。
110
+ - **Intlayer**:在构建时进行 **Tree-shaking**,并按字典/语言进行 **懒加载**。未使用的内容不会被打包。
111
+
112
+ **重要性:** 更小的包体积和更快的多语言 Vue 应用启动速度。
113
+
114
+ ---
115
+
116
+ ### 6) 开发者体验与工具链
117
+
118
+ - **vue-i18n**:成熟的文档和社区;您通常会依赖**外部本地化平台**来进行编辑工作流程。
119
+ - **Intlayer**:提供免费的**可视化编辑器**,可选的**CMS**(支持 Git 或外部化),一个**VSCode 扩展**,**CLI/CI** 工具,以及使用您自己的提供商密钥的**AI 辅助翻译**。
120
+
121
+ **重要原因:** 降低运维成本,缩短开发与内容的循环时间。
122
+
123
+ ---
124
+
125
+ ### 7) SEO、SSR 与 SSG
126
+
127
+ - **两者**均支持 Vue SSR 和 Nuxt。
128
+ - **Intlayer**:增加了**SEO 辅助工具**(站点地图/元数据/`hreflang`),与框架无关,并且能很好地配合 Vue/Nuxt 构建。
129
+
130
+ **重要原因:** 实现国际化 SEO,无需定制复杂配置。
131
+
132
+ ---
133
+
134
+ ## 为什么选择 Intlayer?(问题与方法)
135
+
136
+ 大多数 i18n 方案(包括 **vue-i18n**)都从**集中式目录**开始:
137
+
138
+ ```bash
139
+ .
140
+ ├── locales
141
+ │ ├── en.json
142
+ │ ├── es.json
143
+ │ └── fr.json
144
+ └── src
145
+ └── components
146
+ └── MyComponent.vue
147
+ ```
148
+
149
+ 或者使用按语言区分的文件夹:
150
+
151
+ ```bash
152
+ .
153
+ ├── locales
154
+ │ ├── en
155
+ │ │ ├── footer.json
156
+ │ │ └── navbar.json
157
+ │ ├── fr
158
+ │ │ ├── footer.json
159
+ │ │ └── navbar.json
160
+ │ └── es
161
+ │ ├── footer.json
162
+ │ └── navbar.json
163
+ └── src
164
+ └── components
165
+ └── MyComponent.vue
166
+ ```
167
+
168
+ 随着应用程序的增长,这通常会减慢开发速度:
169
+
170
+ 1. **对于新组件**,你需要创建/编辑远程目录,连接命名空间,并进行翻译(通常通过从 AI 工具手动复制粘贴)。
171
+ 2. **在更改组件时**,你需要寻找共享的键,进行翻译,保持各语言版本同步,删除无用键,并对齐 JSON 结构。
172
+
173
+ **Intlayer** 将内容限定在**每个组件范围内**,并将其**保存在代码旁边**,就像我们已经对 CSS、故事、测试和文档所做的那样:
174
+
175
+ ```bash
176
+ .
177
+ └── components
178
+ └── MyComponent
179
+ ├── MyComponent.content.ts
180
+ └── MyComponent.vue
181
+ ```
182
+
183
+ **内容声明**(每个组件):
184
+
185
+ ```ts fileName="./components/MyComponent/MyComponent.content.ts"
186
+ import { t, type Dictionary } from "intlayer";
187
+
188
+ // 组件示例内容声明
189
+ const componentExampleContent = {
190
+ key: "component-example",
191
+ content: {
192
+ greeting: t({
193
+ en: "Hello World",
194
+ es: "Hola Mundo",
195
+ fr: "Bonjour le monde",
196
+ }),
197
+ },
198
+ } satisfies Dictionary;
199
+
200
+ export default componentExampleContent;
201
+ ```
202
+
203
+ **在 Vue 中的使用**(组合式 API):
204
+
205
+ ```vue fileName="./components/MyComponent/MyComponent.vue"
206
+ <script setup lang="ts">
207
+ import { useIntlayer } from "vue-intlayer"; // Vue 集成
208
+ const { greeting } = useIntlayer("component-example");
209
+ </script>
210
+
211
+ <template>
212
+ <span>{{ greeting }}</span>
213
+ </template>
214
+ ```
215
+
216
+ 这种方法:
217
+
218
+ - **加快开发速度**(声明一次;IDE/AI 自动补全)。
219
+ - **清理代码库**(1 个组件 = 1 个字典)。
220
+ - **简化复制/迁移**(复制组件及其内容一起复制)。
221
+ - **避免死键**(未使用的组件不导入内容)。
222
+ - **优化加载**(懒加载组件携带其内容)。
223
+
224
+ ---
225
+
226
+ ## Intlayer 的额外功能(与 Vue 相关)
227
+
228
+ - **跨框架支持**:支持 Vue、Nuxt、Vite、React、Express 等。
229
+ - **基于 JavaScript 的内容管理**:在代码中声明,灵活度高。
230
+ - **每个语言环境的声明文件**:为所有语言环境预设内容,工具自动生成其余部分。
231
+ - **类型安全环境**:强大的 TypeScript 配置,支持自动补全。
232
+ - **简化内容获取**:单一钩子/组合函数获取字典的所有内容。
233
+ - **有序的代码库**:一个组件对应一个字典,存放在同一文件夹。
234
+ - **增强的路由功能**:为 **Vue Router/Nuxt** 提供本地化路径和元数据的辅助工具。
235
+ - **Markdown 支持**:按语言环境导入远程/本地 Markdown;将 frontmatter 暴露给代码。
236
+ - **免费可视化编辑器和可选 CMS**:无需付费本地化平台即可创作;支持 Git 友好的同步。
237
+ - **可摇树内容**:仅打包使用的内容;支持懒加载。
238
+ - **静态渲染友好**:不阻塞静态站点生成(SSG)。
239
+ - **AI驱动的翻译**:使用您自己的AI提供商/API密钥,支持翻译成231种语言。
240
+ - **MCP服务器和VSCode扩展**:在您的IDE中自动化i18n工作流和内容创作。
241
+ - **互操作性**:在需要时与**vue-i18n**、**react-i18next**和**react-intl**桥接。
242
+
243
+ ---
244
+
245
+ ## 何时选择哪一个?
246
+
247
+ - 如果您想要**标准的Vue方案**,并且能够自行管理目录/命名空间,且您的应用是**小型到中型**(或者您已经依赖Nuxt i18n),请选择**vue-i18n**。
248
+ - 如果您重视**组件范围的内容**、**严格的TypeScript**、**构建时保证**、**摇树优化**以及**内置的路由/SEO/编辑工具**,尤其是针对**大型、模块化的Vue/Nuxt代码库**,请选择**Intlayer**。
249
+
250
+ ---
251
+
252
+ ## 实用迁移注意事项(vue-i18n → Intlayer)
253
+
254
+ - **按功能开始**:一次将一个路由/视图/组件迁移到本地 Intlayer 字典。
255
+ - **迁移期间桥接**:保持 vue-i18n 目录并行存在;逐步替换查找。
256
+ - **启用严格检查**:让构建时检测及早发现缺失的键/语言环境。
257
+ - **采用路由/SEO 辅助工具**:标准化语言环境检测和 `hreflang` 标签。
258
+ - **测量包大小**:随着未使用内容被排除,预计**包大小会减少**。
259
+
260
+ ---
261
+
262
+ ## 结论
263
+
264
+ **vue-i18n** 和 **Intlayer** 都能很好地本地化 Vue 应用。区别在于你需要自己构建多少内容,才能实现一个健壮且可扩展的方案:
265
+
266
+ - 使用 **Intlayer**,**模块化内容**、**严格的 TS**、**构建时安全性**、**摇树优化的包**以及**路由/SEO/编辑器工具**均为**开箱即用**。
267
+ - 如果您的团队优先考虑在多语言、组件驱动的 Vue/Nuxt 应用中的**可维护性和速度**,Intlayer 提供了目前**最完整**的体验。
268
+
269
+ 有关更多详情,请参阅 ['为什么选择 Intlayer?' 文档](https://intlayer.org/doc/why)。
@@ -1600,6 +1600,47 @@ const blogEntry = {
1600
1600
  )
1601
1601
  )
1602
1602
  },
1603
+ "./blog/en/vue-i18n_vs_intlayer.md": {
1604
+ en: Promise.resolve(
1605
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/en/vue-i18n_vs_intlayer.md"), "utf8")
1606
+ ),
1607
+ fr: Promise.resolve(
1608
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/fr/vue-i18n_vs_intlayer.md"), "utf8")
1609
+ ),
1610
+ ru: Promise.resolve(
1611
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/ru/vue-i18n_vs_intlayer.md"), "utf8")
1612
+ ),
1613
+ ja: Promise.resolve(
1614
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/ja/vue-i18n_vs_intlayer.md"), "utf8")
1615
+ ),
1616
+ ko: Promise.resolve(
1617
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/ko/vue-i18n_vs_intlayer.md"), "utf8")
1618
+ ),
1619
+ zh: Promise.resolve(
1620
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/zh/vue-i18n_vs_intlayer.md"), "utf8")
1621
+ ),
1622
+ es: Promise.resolve(
1623
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/es/vue-i18n_vs_intlayer.md"), "utf8")
1624
+ ),
1625
+ de: Promise.resolve(
1626
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/de/vue-i18n_vs_intlayer.md"), "utf8")
1627
+ ),
1628
+ ar: Promise.resolve(
1629
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/ar/vue-i18n_vs_intlayer.md"), "utf8")
1630
+ ),
1631
+ pt: Promise.resolve(
1632
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/pt/vue-i18n_vs_intlayer.md"), "utf8")
1633
+ ),
1634
+ "en-GB": Promise.resolve(
1635
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/en-GB/vue-i18n_vs_intlayer.md"), "utf8")
1636
+ ),
1637
+ it: Promise.resolve(
1638
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/it/vue-i18n_vs_intlayer.md"), "utf8")
1639
+ ),
1640
+ hi: Promise.resolve(
1641
+ (0, import_promises.readFile)((0, import_path.join)(dir, "../../../blog/hi/vue-i18n_vs_intlayer.md"), "utf8")
1642
+ )
1643
+ },
1603
1644
  "./blog/en/what_is_internationalization.md": {
1604
1645
  en: Promise.resolve(
1605
1646
  (0, import_promises.readFile)(