@intlayer/docs 8.0.0 → 8.0.1-canary.1

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 (172) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +160 -0
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +160 -0
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +8 -0
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/intlayer_with_adonisjs.md +394 -0
  8. package/docs/ar/intlayer_with_hono.md +223 -0
  9. package/docs/ar/intlayer_with_vite+preact.md +317 -675
  10. package/docs/ar/packages/adonis-intlayer/exports.md +50 -0
  11. package/docs/ar/packages/adonis-intlayer/intlayer.md +54 -0
  12. package/docs/ar/packages/adonis-intlayer/t.md +149 -0
  13. package/docs/ar/packages/hono-intlayer/exports.md +59 -0
  14. package/docs/ar/packages/hono-intlayer/intlayer.md +60 -0
  15. package/docs/ar/packages/hono-intlayer/t.md +268 -0
  16. package/docs/de/intlayer_with_adonisjs.md +392 -0
  17. package/docs/de/intlayer_with_hono.md +418 -0
  18. package/docs/de/intlayer_with_vite+preact.md +272 -632
  19. package/docs/de/packages/adonis-intlayer/exports.md +50 -0
  20. package/docs/de/packages/adonis-intlayer/intlayer.md +54 -0
  21. package/docs/de/packages/adonis-intlayer/t.md +149 -0
  22. package/docs/de/packages/hono-intlayer/exports.md +59 -0
  23. package/docs/de/packages/hono-intlayer/intlayer.md +59 -0
  24. package/docs/de/packages/hono-intlayer/t.md +316 -0
  25. package/docs/en/index.md +8 -0
  26. package/docs/en/intlayer_with_adonisjs.md +388 -0
  27. package/docs/en/intlayer_with_hono.md +418 -0
  28. package/docs/en/intlayer_with_vite+preact.md +171 -556
  29. package/docs/en/introduction.md +1 -0
  30. package/docs/en/packages/adonis-intlayer/exports.md +50 -0
  31. package/docs/en/packages/adonis-intlayer/intlayer.md +54 -0
  32. package/docs/en/packages/adonis-intlayer/t.md +149 -0
  33. package/docs/en/packages/hono-intlayer/exports.md +59 -0
  34. package/docs/en/packages/hono-intlayer/intlayer.md +59 -0
  35. package/docs/en/packages/hono-intlayer/t.md +316 -0
  36. package/docs/en-GB/intlayer_with_adonisjs.md +394 -0
  37. package/docs/en-GB/intlayer_with_hono.md +418 -0
  38. package/docs/en-GB/intlayer_with_vite+preact.md +236 -583
  39. package/docs/en-GB/packages/adonis-intlayer/exports.md +50 -0
  40. package/docs/en-GB/packages/adonis-intlayer/intlayer.md +54 -0
  41. package/docs/en-GB/packages/adonis-intlayer/t.md +149 -0
  42. package/docs/en-GB/packages/hono-intlayer/exports.md +59 -0
  43. package/docs/en-GB/packages/hono-intlayer/intlayer.md +59 -0
  44. package/docs/en-GB/packages/hono-intlayer/t.md +316 -0
  45. package/docs/es/intlayer_with_adonisjs.md +388 -0
  46. package/docs/es/intlayer_with_hono.md +418 -0
  47. package/docs/es/intlayer_with_vite+preact.md +286 -650
  48. package/docs/es/packages/adonis-intlayer/exports.md +50 -0
  49. package/docs/es/packages/adonis-intlayer/intlayer.md +54 -0
  50. package/docs/es/packages/adonis-intlayer/t.md +149 -0
  51. package/docs/es/packages/hono-intlayer/exports.md +59 -0
  52. package/docs/es/packages/hono-intlayer/intlayer.md +59 -0
  53. package/docs/es/packages/hono-intlayer/t.md +316 -0
  54. package/docs/fr/intlayer_with_adonisjs.md +388 -0
  55. package/docs/fr/intlayer_with_hono.md +418 -0
  56. package/docs/fr/intlayer_with_vite+preact.md +274 -614
  57. package/docs/fr/packages/adonis-intlayer/exports.md +50 -0
  58. package/docs/fr/packages/adonis-intlayer/intlayer.md +54 -0
  59. package/docs/fr/packages/adonis-intlayer/t.md +149 -0
  60. package/docs/fr/packages/hono-intlayer/exports.md +59 -0
  61. package/docs/fr/packages/hono-intlayer/intlayer.md +59 -0
  62. package/docs/fr/packages/hono-intlayer/t.md +316 -0
  63. package/docs/hi/intlayer_with_adonisjs.md +394 -0
  64. package/docs/hi/intlayer_with_hono.md +227 -0
  65. package/docs/hi/intlayer_with_vite+preact.md +304 -680
  66. package/docs/hi/packages/adonis-intlayer/exports.md +50 -0
  67. package/docs/hi/packages/adonis-intlayer/intlayer.md +54 -0
  68. package/docs/hi/packages/adonis-intlayer/t.md +149 -0
  69. package/docs/hi/packages/hono-intlayer/exports.md +59 -0
  70. package/docs/hi/packages/hono-intlayer/intlayer.md +60 -0
  71. package/docs/hi/packages/hono-intlayer/t.md +268 -0
  72. package/docs/id/intlayer_with_adonisjs.md +394 -0
  73. package/docs/id/intlayer_with_hono.md +227 -0
  74. package/docs/id/intlayer_with_vite+preact.md +297 -697
  75. package/docs/id/packages/adonis-intlayer/exports.md +50 -0
  76. package/docs/id/packages/adonis-intlayer/intlayer.md +54 -0
  77. package/docs/id/packages/adonis-intlayer/t.md +149 -0
  78. package/docs/id/packages/hono-intlayer/exports.md +59 -0
  79. package/docs/id/packages/hono-intlayer/intlayer.md +60 -0
  80. package/docs/id/packages/hono-intlayer/t.md +268 -0
  81. package/docs/it/intlayer_with_adonisjs.md +394 -0
  82. package/docs/it/intlayer_with_hono.md +227 -0
  83. package/docs/it/intlayer_with_vite+preact.md +290 -659
  84. package/docs/it/packages/adonis-intlayer/exports.md +50 -0
  85. package/docs/it/packages/adonis-intlayer/intlayer.md +54 -0
  86. package/docs/it/packages/adonis-intlayer/t.md +149 -0
  87. package/docs/it/packages/hono-intlayer/exports.md +59 -0
  88. package/docs/it/packages/hono-intlayer/intlayer.md +60 -0
  89. package/docs/it/packages/hono-intlayer/t.md +268 -0
  90. package/docs/ja/intlayer_with_adonisjs.md +394 -0
  91. package/docs/ja/intlayer_with_hono.md +227 -0
  92. package/docs/ja/intlayer_with_vite+preact.md +307 -662
  93. package/docs/ja/packages/adonis-intlayer/exports.md +50 -0
  94. package/docs/ja/packages/adonis-intlayer/intlayer.md +54 -0
  95. package/docs/ja/packages/adonis-intlayer/t.md +149 -0
  96. package/docs/ja/packages/hono-intlayer/exports.md +59 -0
  97. package/docs/ja/packages/hono-intlayer/intlayer.md +60 -0
  98. package/docs/ja/packages/hono-intlayer/t.md +268 -0
  99. package/docs/ko/intlayer_with_adonisjs.md +394 -0
  100. package/docs/ko/intlayer_with_hono.md +227 -0
  101. package/docs/ko/intlayer_with_vite+preact.md +303 -703
  102. package/docs/ko/packages/adonis-intlayer/exports.md +50 -0
  103. package/docs/ko/packages/adonis-intlayer/intlayer.md +54 -0
  104. package/docs/ko/packages/adonis-intlayer/t.md +149 -0
  105. package/docs/ko/packages/hono-intlayer/exports.md +59 -0
  106. package/docs/ko/packages/hono-intlayer/intlayer.md +60 -0
  107. package/docs/ko/packages/hono-intlayer/t.md +268 -0
  108. package/docs/pl/intlayer_with_adonisjs.md +394 -0
  109. package/docs/pl/intlayer_with_hono.md +227 -0
  110. package/docs/pl/intlayer_with_vite+preact.md +289 -690
  111. package/docs/pl/packages/adonis-intlayer/exports.md +50 -0
  112. package/docs/pl/packages/adonis-intlayer/intlayer.md +54 -0
  113. package/docs/pl/packages/adonis-intlayer/t.md +149 -0
  114. package/docs/pl/packages/hono-intlayer/exports.md +59 -0
  115. package/docs/pl/packages/hono-intlayer/intlayer.md +60 -0
  116. package/docs/pl/packages/hono-intlayer/t.md +268 -0
  117. package/docs/pt/intlayer_with_adonisjs.md +394 -0
  118. package/docs/pt/intlayer_with_hono.md +227 -0
  119. package/docs/pt/intlayer_with_vite+preact.md +275 -637
  120. package/docs/pt/packages/adonis-intlayer/exports.md +50 -0
  121. package/docs/pt/packages/adonis-intlayer/intlayer.md +54 -0
  122. package/docs/pt/packages/adonis-intlayer/t.md +149 -0
  123. package/docs/pt/packages/hono-intlayer/exports.md +59 -0
  124. package/docs/pt/packages/hono-intlayer/intlayer.md +60 -0
  125. package/docs/pt/packages/hono-intlayer/t.md +268 -0
  126. package/docs/ru/intlayer_with_adonisjs.md +393 -0
  127. package/docs/ru/intlayer_with_hono.md +223 -0
  128. package/docs/ru/intlayer_with_vite+preact.md +319 -683
  129. package/docs/ru/packages/adonis-intlayer/exports.md +50 -0
  130. package/docs/ru/packages/adonis-intlayer/intlayer.md +54 -0
  131. package/docs/ru/packages/adonis-intlayer/t.md +149 -0
  132. package/docs/ru/packages/hono-intlayer/exports.md +59 -0
  133. package/docs/ru/packages/hono-intlayer/intlayer.md +60 -0
  134. package/docs/ru/packages/hono-intlayer/t.md +268 -0
  135. package/docs/tr/intlayer_with_adonisjs.md +394 -0
  136. package/docs/tr/intlayer_with_hono.md +227 -0
  137. package/docs/tr/intlayer_with_vite+preact.md +332 -665
  138. package/docs/tr/packages/adonis-intlayer/exports.md +50 -0
  139. package/docs/tr/packages/adonis-intlayer/intlayer.md +54 -0
  140. package/docs/tr/packages/adonis-intlayer/t.md +149 -0
  141. package/docs/tr/packages/hono-intlayer/exports.md +59 -0
  142. package/docs/tr/packages/hono-intlayer/intlayer.md +60 -0
  143. package/docs/tr/packages/hono-intlayer/t.md +268 -0
  144. package/docs/uk/intlayer_with_adonisjs.md +394 -0
  145. package/docs/uk/intlayer_with_hono.md +227 -0
  146. package/docs/uk/intlayer_with_vite+preact.md +228 -626
  147. package/docs/uk/packages/adonis-intlayer/exports.md +50 -0
  148. package/docs/uk/packages/adonis-intlayer/intlayer.md +54 -0
  149. package/docs/uk/packages/adonis-intlayer/t.md +149 -0
  150. package/docs/uk/packages/hono-intlayer/exports.md +59 -0
  151. package/docs/uk/packages/hono-intlayer/intlayer.md +60 -0
  152. package/docs/uk/packages/hono-intlayer/t.md +268 -0
  153. package/docs/vi/intlayer_with_adonisjs.md +394 -0
  154. package/docs/vi/intlayer_with_hono.md +227 -0
  155. package/docs/vi/intlayer_with_vite+preact.md +294 -679
  156. package/docs/vi/packages/adonis-intlayer/exports.md +50 -0
  157. package/docs/vi/packages/adonis-intlayer/intlayer.md +54 -0
  158. package/docs/vi/packages/adonis-intlayer/t.md +149 -0
  159. package/docs/vi/packages/hono-intlayer/exports.md +59 -0
  160. package/docs/vi/packages/hono-intlayer/intlayer.md +60 -0
  161. package/docs/vi/packages/hono-intlayer/t.md +268 -0
  162. package/docs/zh/intlayer_with_adonisjs.md +393 -0
  163. package/docs/zh/intlayer_with_hono.md +418 -0
  164. package/docs/zh/intlayer_with_vite+preact.md +338 -743
  165. package/docs/zh/packages/adonis-intlayer/exports.md +50 -0
  166. package/docs/zh/packages/adonis-intlayer/intlayer.md +54 -0
  167. package/docs/zh/packages/adonis-intlayer/t.md +149 -0
  168. package/docs/zh/packages/hono-intlayer/exports.md +59 -0
  169. package/docs/zh/packages/hono-intlayer/intlayer.md +60 -0
  170. package/docs/zh/packages/hono-intlayer/t.md +294 -0
  171. package/package.json +6 -6
  172. package/src/generated/docs.entry.ts +160 -0
@@ -24,7 +24,7 @@ history:
24
24
  changes: 初始化历史
25
25
  ---
26
26
 
27
- # 使用Intlayer翻译您的Vite and Preact | 国际化(i18n)
27
+ # 使用 Intlayer 翻译您的 Vite Preact 网站 | 国际化 (i18n)
28
28
 
29
29
  <Tabs defaultTab="video">
30
30
  <Tab label="Video" value="video">
@@ -45,28 +45,30 @@ history:
45
45
  </Tab>
46
46
  </Tabs>
47
47
 
48
- > 该包正在开发中。有关更多信息,请参见[问题](https://github.com/aymericzip/intlayer/issues/118)。通过点赞该问题,表达您对 Intlayer for Preact 的兴趣。
48
+ ## 目录
49
49
 
50
- 请参阅 GitHub 上的[应用模板](https://github.com/aymericzip/intlayer-vite-preact-template)。
50
+ <TOC/>
51
51
 
52
52
  ## 什么是 Intlayer?
53
53
 
54
- **Intlayer** 是一个创新的开源国际化(i18n)库,旨在简化现代 Web 应用程序的多语言支持。
54
+ **Intlayer** 是一个创新的开源国际化 (i18n) 库,旨在简化现代 Web 应用程序的多语言支持。
55
55
 
56
56
  使用 Intlayer,您可以:
57
57
 
58
- - **通过组件级声明式字典轻松管理翻译**。
58
+ - **轻松管理翻译**:使用组件级的声明式字典。
59
59
  - **动态本地化元数据、路由和内容**。
60
- - **确保 TypeScript 支持**,通过自动生成类型,提升自动补全和错误检测能力。
61
- - **受益于高级功能**,如动态语言环境检测和切换。
60
+ - **确保 TypeScript 支持**:通过自动生成的类型,改进自动补全和错误检测。
61
+ - **受益于高级功能**:例如动态语言环境检测和切换。
62
62
 
63
63
  ---
64
64
 
65
- ## 在 Vite 和 Preact 应用中设置 Intlayer 的分步指南
65
+ ## 在 Vite 和 Preact 应用程序中设置 Intlayer 的分步指南
66
66
 
67
- ### 第一步:安装依赖
67
+ 请参阅 GitHub 上的 [应用程序模板](https://github.com/aymericzip/intlayer-vite-preact-template)。
68
68
 
69
- 使用 npm 安装所需的包:
69
+ ### 1 步:安装依赖项
70
+
71
+ 使用 npm 安装必要的包:
70
72
 
71
73
  ```bash packageManager="npm"
72
74
  npm install intlayer preact-intlayer
@@ -94,59 +96,19 @@ bunx intlayer init
94
96
 
95
97
  - **intlayer**
96
98
 
97
- - **intlayer**
98
- 核心包,提供国际化工具,用于配置管理、翻译、[内容声明](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)、转译以及[命令行工具](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_cli.md)。
99
-
100
- - **preact-intlayer**
101
- 将 Intlayer 集成到 Preact 应用中的包。它提供了 Preact 国际化的上下文提供者和钩子。
102
-
103
- - **vite-intlayer**
104
- 包含用于将 Intlayer 集成到[Vite 打包工具](https://vite.dev/guide/why.html#why-bundle-for-production)的 Vite 插件,以及用于检测用户首选语言、管理 Cookie 和处理 URL 重定向的中间件。
105
-
106
- ### 第2步:配置您的项目
107
-
108
- 创建一个配置文件来配置您应用程序的语言:
109
-
110
- ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
111
- import { Locales, type IntlayerConfig } from "intlayer";
112
-
113
- const config: IntlayerConfig = {
114
- internationalization: {
115
- locales: [
116
- Locales.ENGLISH,
117
- Locales.FRENCH,
118
- Locales.SPANISH,
119
- // 您的其他语言
120
- ],
121
- defaultLocale: Locales.ENGLISH,
122
- },
123
- };
99
+ 提供配置管理、翻译、[内容声明](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) 的核心包。
124
100
 
125
- export default config;
126
- ```
101
+ - **preact-intlayer**
127
102
 
128
- ```javascript fileName="intlayer.config.mjs" codeFormat="esm"
129
- import { Locales } from "intlayer";
103
+ Intlayer 与 Preact 应用程序集成的包。它为 Preact 国际化提供上下文提供者和钩子。
130
104
 
131
- /** @type {import('intlayer').IntlayerConfig} */
132
- const config = {
133
- internationalization: {
134
- locales: [
135
- Locales.ENGLISH,
136
- Locales.FRENCH,
137
- Locales.SPANISH,
138
- // 您的其他语言
139
- ],
140
- defaultLocale: Locales.ENGLISH,
141
- },
142
- };
105
+ - **vite-intlayer**
143
106
 
144
- export default config;
145
- ```
107
+ 包含用于将 Intlayer 与 [Vite 打包器](https://vite.dev/guide/why.html#why-bundle-for-production) 集成的 Vite 插件,以及用于检测用户首选语言环境、管理 cookie 和处理 URL 重定向的中间件。
146
108
 
147
- ### 第2步:配置您的项目
109
+ ### 第 2 步:配置项目
148
110
 
149
- 创建一个配置文件来配置您应用程序的语言:
111
+ 创建一个配置文件来配置应用程序的语言:
150
112
 
151
113
  ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
152
114
  import { Locales, type IntlayerConfig } from "intlayer";
@@ -157,10 +119,14 @@ const config: IntlayerConfig = {
157
119
  Locales.ENGLISH,
158
120
  Locales.FRENCH,
159
121
  Locales.SPANISH,
160
- // 您的其他语言
122
+ // 您的其他语言环境
161
123
  ],
162
124
  defaultLocale: Locales.ENGLISH,
163
125
  },
126
+ routing: {
127
+ mode: "prefix-no-default", // 默认:除默认语言环境外,为所有语言环境添加前缀
128
+ storage: ["cookie", "header"], // 默认:在 cookie 中存储语言环境并从 header 中检测
129
+ },
164
130
  };
165
131
 
166
132
  export default config;
@@ -176,10 +142,14 @@ const config = {
176
142
  Locales.ENGLISH,
177
143
  Locales.FRENCH,
178
144
  Locales.SPANISH,
179
- // 您的其他语言
145
+ // 您的其他语言环境
180
146
  ],
181
147
  defaultLocale: Locales.ENGLISH,
182
148
  },
149
+ routing: {
150
+ mode: "prefix-no-default", // 默认:除默认语言环境外,为所有语言环境添加前缀
151
+ storage: ["cookie", "header"], // 默认:在 cookie 中存储语言环境并从 header 中检测
152
+ },
183
153
  };
184
154
 
185
155
  export default config;
@@ -195,35 +165,22 @@ const config = {
195
165
  Locales.ENGLISH,
196
166
  Locales.FRENCH,
197
167
  Locales.SPANISH,
198
- // 您的其他语言
168
+ // 您的其他语言环境
199
169
  ],
200
170
  defaultLocale: Locales.ENGLISH,
201
171
  },
172
+ routing: {
173
+ mode: "prefix-no-default", // 默认:除默认语言环境外,为所有语言环境添加前缀
174
+ storage: ["cookie", "header"], // 默认:在 cookie 中存储语言环境并从 header 中检测
175
+ },
202
176
  };
203
177
 
204
178
  module.exports = config;
205
179
  ```
206
180
 
207
- > 通过此配置文件,您可以设置本地化的 URL、中间件重定向、cookie 名称、内容声明的位置和扩展名,禁用 Intlayer 在控制台的日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
181
+ > 通过此配置文件,您可以设置本地化 URL、路由模式、存储选项、cookie 名称、内容声明的位置和扩展名、禁用控制台中的 Intlayer 日志等。有关可用参数的完整列表,请参阅 [配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
208
182
 
209
- ### 第3步:在您的 Vite 配置中集成 Intlayer
210
-
211
- 将 intlayer 插件添加到您的配置中。
212
-
213
- ```typescript fileName="vite.config.ts" codeFormat="typescript"
214
- import { defineConfig } from "vite";
215
- import preact from "@preact/preset-vite";
216
- import { intlayer } from "vite-intlayer";
217
-
218
- // https://vitejs.dev/config/
219
- export default defineConfig({
220
- plugins: [preact(), intlayer()],
221
- });
222
- ```
223
-
224
- > 通过此配置文件,您可以设置本地化的 URL、中间件重定向、cookie 名称、内容声明的位置和扩展名,禁用控制台中的 Intlayer 日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
225
-
226
- ### 第3步:在您的 Vite 配置中集成 Intlayer
183
+ ### 第 3 步:在 Vite 配置中集成 Intlayer
227
184
 
228
185
  将 intlayer 插件添加到您的配置中。
229
186
 
@@ -260,9 +217,9 @@ module.exports = defineConfig({
260
217
  });
261
218
  ```
262
219
 
263
- > `intlayer()` Vite 插件用于将 Intlayer 集成到 Vite 中。它确保内容声明文件的构建,并在开发模式下监视这些文件。它在 Vite 应用程序中定义了 Intlayer 环境变量。此外,它还提供别名以优化性能。
220
+ > `intlayer()` Vite 插件用于将 Intlayer Vite 集成。它确保构建内容声明文件并在开发模式下监视它们。它在 Vite 应用程序中定义了 Intlayer 环境变量。此外,它还提供别名以优化性能。
264
221
 
265
- ### 第4步:声明您的内容
222
+ ### 第 4 步:声明内容
266
223
 
267
224
  创建并管理您的内容声明以存储翻译:
268
225
 
@@ -287,18 +244,12 @@ const appContent = {
287
244
  title: "Vite + Preact",
288
245
 
289
246
  count: t({
290
- zh: "计数是 ",
291
247
  en: "count is ",
292
248
  fr: "le compte est ",
293
249
  es: "el recuento es ",
294
250
  }),
295
251
 
296
252
  edit: t<ComponentChildren>({
297
- zh: (
298
- <>
299
- 编辑 <code>src/app.tsx</code> 并保存以测试 HMR
300
- </>
301
- ),
302
253
  en: (
303
254
  <>
304
255
  Edit <code>src/app.tsx</code> and save to test HMR
@@ -317,7 +268,6 @@ const appContent = {
317
268
  }),
318
269
 
319
270
  readTheDocs: t({
320
- zh: "点击 Vite 和 Preact 标志以了解更多信息",
321
271
  en: "Click on the Vite and Preact logos to learn more",
322
272
  fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
323
273
  es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
@@ -330,7 +280,7 @@ export default appContent;
330
280
 
331
281
  ```javascript fileName="src/app.content.mjs" contentDeclarationFormat="esm"
332
282
  import { t } from "intlayer";
333
- // import { h } from 'preact'; // 如果你直接在 .mjs 中使用 JSX,则需要此行
283
+ // import { h } from 'preact'; // 如果直接在 .mjs 中使用 JSX,则需要此行
334
284
 
335
285
  /** @type {import('intlayer').Dictionary} */
336
286
  const appContent = {
@@ -362,7 +312,7 @@ const appContent = {
362
312
  }),
363
313
 
364
314
  readTheDocs: t({
365
- en: "点击 Vite Preact 标志以了解更多信息",
315
+ en: "Click on the Vite and Preact logos to learn more",
366
316
  fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
367
317
  es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
368
318
  }),
@@ -374,19 +324,19 @@ export default appContent;
374
324
 
375
325
  ```javascript fileName="src/app.content.cjs" contentDeclarationFormat="commonjs"
376
326
  const { t } = require("intlayer");
377
- // const { h } = require('preact'); // 如果你直接在 .cjs 文件中使用 JSX,则需要此行
327
+ // const { h } = require('preact'); // 如果直接在 .cjs 中使用 JSX,则需要此行
378
328
 
379
329
  /** @type {import('intlayer').Dictionary} */
380
330
  const appContent = {
381
331
  key: "app",
382
332
  content: {
383
333
  viteLogo: t({
384
- en: "Vite 标志",
334
+ en: "Vite logo",
385
335
  fr: "Logo Vite",
386
336
  es: "Logo Vite",
387
337
  }),
388
338
  preactLogo: t({
389
- en: "Preact 标志",
339
+ en: "Preact logo",
390
340
  fr: "Logo Preact",
391
341
  es: "Logo Preact",
392
342
  }),
@@ -397,21 +347,18 @@ const appContent = {
397
347
  en: "count is ",
398
348
  fr: "le compte est ",
399
349
  es: "el recuento es ",
400
- zh: "计数是 ",
401
350
  }),
402
351
 
403
352
  edit: t({
404
353
  en: "Edit src/app.tsx and save to test HMR",
405
354
  fr: "Éditez src/app.tsx et enregistrez pour tester HMR",
406
355
  es: "Edita src/app.tsx y guarda para probar HMR",
407
- zh: "编辑 src/app.tsx 并保存以测试 HMR",
408
356
  }),
409
357
 
410
358
  readTheDocs: t({
411
359
  en: "Click on the Vite and Preact logos to learn more",
412
360
  fr: "Cliquez sur les logos Vite et Preact pour en savoir plus",
413
- es: "Haga clic en los logotipos de Vite y Preact para obtener más información",
414
- zh: "点击 Vite 和 Preact 标志了解更多信息",
361
+ es: "Haga clic en los logotipos de Vite et Preact pour en savoir plus",
415
362
  }),
416
363
  },
417
364
  };
@@ -427,7 +374,6 @@ module.exports = appContent;
427
374
  "viteLogo": {
428
375
  "nodeType": "translation",
429
376
  "translation": {
430
- "zh": "Vite 标志",
431
377
  "en": "Vite logo",
432
378
  "fr": "Logo Vite",
433
379
  "es": "Logo Vite"
@@ -436,7 +382,6 @@ module.exports = appContent;
436
382
  "preactLogo": {
437
383
  "nodeType": "translation",
438
384
  "translation": {
439
- "zh": "Preact 标志",
440
385
  "en": "Preact logo",
441
386
  "fr": "Logo Preact",
442
387
  "es": "Logo Preact"
@@ -445,7 +390,6 @@ module.exports = appContent;
445
390
  "title": {
446
391
  "nodeType": "translation",
447
392
  "translation": {
448
- "zh": "Vite + Preact",
449
393
  "en": "Vite + Preact",
450
394
  "fr": "Vite + Preact",
451
395
  "es": "Vite + Preact"
@@ -454,7 +398,6 @@ module.exports = appContent;
454
398
  "count": {
455
399
  "nodeType": "translation",
456
400
  "translation": {
457
- "zh": "计数是 ",
458
401
  "en": "count is ",
459
402
  "fr": "le compte est ",
460
403
  "es": "el recuento es "
@@ -463,7 +406,7 @@ module.exports = appContent;
463
406
  "edit": {
464
407
  "nodeType": "translation",
465
408
  "translation": {
466
- "en": "编辑 src/app.tsx 并保存以测试 HMR",
409
+ "en": "Edit src/app.tsx and save to test HMR",
467
410
  "fr": "Éditez src/app.tsx et enregistrez pour tester HMR",
468
411
  "es": "Edita src/app.tsx y guarda para probar HMR"
469
412
  }
@@ -471,7 +414,7 @@ module.exports = appContent;
471
414
  "readTheDocs": {
472
415
  "nodeType": "translation",
473
416
  "translation": {
474
- "en": "点击 Vite Preact 标志以了解更多信息",
417
+ "en": "Click on the Vite and Preact logos to learn more",
475
418
  "fr": "Cliquez sur les logos Vite et Preact pour en savoir plus",
476
419
  "es": "Haga clic en los logotipos de Vite y Preact para obtener más información"
477
420
  }
@@ -480,22 +423,22 @@ module.exports = appContent;
480
423
  }
481
424
  ```
482
425
 
483
- > 您的内容声明可以定义在应用程序中的任何位置,只要它们被包含在 `contentDir` 目录中(默认是 `./src`)。并且文件扩展名需匹配内容声明文件扩展名(默认是 `.content.{json,ts,tsx,js,jsx,mjs,cjs}`)。
426
+ > 只要您的内容声明包含在 `contentDir` 目录(默认情况下为 `./src`)中,就可以在应用程序的任何位置定义它们。并且需匹配内容声明文件扩展名(默认情况下为 `.content.{json,ts,tsx,js,jsx,mjs,cjs}`)。
484
427
 
485
- > 更多详情,请参考[内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/get_started.md)。
428
+ > 有关更多详细信息,请参考 [内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)。
486
429
 
487
- > 如果您的内容文件包含 TSX 代码,您可能需要导入 `import { h } from "preact";`,或者确保您的 JSX pragma 已正确设置为 Preact
430
+ > 如果您的内容文件包含 TSX 代码,您可能需要导入 `import { h } from "preact";` 或确保正确设置 Preact 的 JSX pragma。
488
431
 
489
- ### 第5步:在代码中使用 Intlayer
432
+ ### 第 5 步:在代码中使用 Intlayer
490
433
 
491
434
  在整个应用程序中访问您的内容字典:
492
435
 
493
436
  ```tsx {6,10} fileName="src/app.tsx" codeFormat="typescript"
494
437
  import { useState } from "preact/hooks";
495
438
  import type { FunctionalComponent } from "preact";
496
- import preactLogo from "./assets/preact.svg"; // 假设你有一个 preact.svg 文件
439
+ import preactLogo from "./assets/preact.svg"; // 假设您有 preact.svg
497
440
  import viteLogo from "/vite.svg";
498
- import "./app.css"; // 假设你的 CSS 文件名为 app.css
441
+ import "./app.css"; // 假设您的 CSS 文件名为 app.css
499
442
  import { IntlayerProvider, useIntlayer } from "preact-intlayer";
500
443
 
501
444
  const AppContent: FunctionalComponent = () => {
@@ -524,6 +467,12 @@ const AppContent: FunctionalComponent = () => {
524
467
  </button>
525
468
  <p>{content.edit}</p>
526
469
  </div>
470
+ {/* Markdown 内容 */}
471
+ <div>{content.myMarkdownContent}</div>
472
+
473
+ {/* HTML 内容 */}
474
+ <div>{content.myHtmlContent}</div>
475
+
527
476
  <p class="read-the-docs">{content.readTheDocs}</p>
528
477
  </>
529
478
  );
@@ -632,7 +581,7 @@ const App = () => (
632
581
  module.exports = App;
633
582
  ```
634
583
 
635
- > 如果您想在字符串属性中使用内容,例如 `alt`、`title`、`href`、`aria-label` 等,必须调用函数的值,如:
584
+ > 如果您想在字符串属性中使用您的内容,例如 `alt`、`title`、`href`、`aria-label` 等,您必须调用该函数的值,例如:
636
585
 
637
586
  > ```jsx
638
587
  > <img src={content.image.src.value} alt={content.image.value} />
@@ -640,11 +589,11 @@ module.exports = App;
640
589
 
641
590
  > 注意:在 Preact 中,`className` 通常写作 `class`。
642
591
 
643
- > 要了解更多关于 `useIntlayer` 钩子的内容,请参阅[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useIntlayer.md)(`preact-intlayer` 的 API 类似)。
592
+ > 要了解有关 `useIntlayer` 钩子的更多信息,请参考 [文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useIntlayer.md)(`preact-intlayer` 的 API 类似)。
644
593
 
645
- ### (可选)步骤 6:更改内容语言
594
+ ### (可选)第 6 步:更改内容语言
646
595
 
647
- 要更改内容的语言,可以使用 `useLocale` 钩子提供的 `setLocale` 函数。此函数允许您设置应用程序的语言环境并相应地更新内容。
596
+ 要更改内容的语言,您可以使用 `useLocale` 钩子提供的 `setLocale` 函数。此函数允许您设置应用程序的语言环境并相应地更新内容。
648
597
 
649
598
  ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
650
599
  import type { FunctionalComponent } from "preact";
@@ -655,7 +604,9 @@ const LocaleSwitcher: FunctionalComponent = () => {
655
604
  const { setLocale } = useLocale();
656
605
 
657
606
  return (
658
- <button onClick={() => setLocale(Locales.ENGLISH)}>将语言切换为英语</button>
607
+ <button onClick={() => setLocale(Locales.ENGLISH)}>
608
+ Change Language to English
609
+ </button>
659
610
  );
660
611
  };
661
612
 
@@ -670,7 +621,9 @@ const LocaleSwitcher = () => {
670
621
  const { setLocale } = useLocale();
671
622
 
672
623
  return (
673
- <button onClick={() => setLocale(Locales.ENGLISH)}>将语言切换为英语</button>
624
+ <button onClick={() => setLocale(Locales.ENGLISH)}>
625
+ Change Language to English
626
+ </button>
674
627
  );
675
628
  };
676
629
 
@@ -685,18 +638,20 @@ const LocaleSwitcher = () => {
685
638
  const { setLocale } = useLocale();
686
639
 
687
640
  return (
688
- <button onClick={() => setLocale(Locales.ENGLISH)}>切换语言到英语</button>
641
+ <button onClick={() => setLocale(Locales.ENGLISH)}>
642
+ Change Language to English
643
+ </button>
689
644
  );
690
645
  };
691
646
 
692
647
  module.exports = LocaleSwitcher;
693
648
  ```
694
649
 
695
- > 想了解更多关于 `useLocale` 钩子的内容,请参阅[文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(`preact-intlayer` 的 API 类似)。
650
+ > 要了解有关 `useLocale` 钩子的更多信息,请参考 [文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(`preact-intlayer` 的 API 类似)。
696
651
 
697
- ### (可选)步骤7:为您的应用添加本地化路由
652
+ ### (可选)步骤 7:为您的应用程序添加本地化路由
698
653
 
699
- 此步骤的目的是为每种语言创建唯一的路由。这对于 SEO 和 SEO 友好的 URL 非常有用。
654
+ 此步骤的目的是为每种语言设置唯一的路由。这对于 SEO 和 SEO 友好的 URL 非常有用。
700
655
  示例:
701
656
 
702
657
  ```plaintext
@@ -705,410 +660,107 @@ module.exports = LocaleSwitcher;
705
660
  - https://example.com/fr/about
706
661
  ```
707
662
 
708
- > 默认情况下,默认语言的路由不会添加前缀。如果您想为默认语言添加前缀,可以在配置中将 `middleware.prefixDefault` 选项设置为 `true`。更多信息请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
709
-
710
- 要为您的应用添加本地化路由,您可以创建一个 `LocaleRouter` 组件来包裹应用的路由,并处理基于语言的路由。以下是使用 [preact-iso](https://github.com/preactjs/preact-iso) 的示例:
711
-
712
- 首先,安装 `preact-iso`:
663
+ > 默认情况下,默认语言环境的路由不带前缀。如果您想为默认语言环境添加前缀,可以在配置中将 `routing.mode` 选项设置为 `"prefix-all"`。有关更多信息,请参阅 [配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
713
664
 
714
- ```bash packageManager="npm"
715
- npm install preact-iso
716
- npx intlayer init
717
- ```
718
-
719
- ```bash packageManager="pnpm"
720
- pnpm add preact-iso
721
- pnpm intlayer init
722
- ```
723
-
724
- ```bash packageManager="yarn"
725
- yarn add preact-iso
726
- ```
665
+ 要为您的应用程序添加本地化路由,您可以创建一个 `LocaleRouter` 组件,该组件包裹您的应用程序路由并处理基于语言环境的路由。以下是使用 [preact-iso](https://github.com/preactjs/preact-iso) 的示例:
727
666
 
728
667
  ```tsx fileName="src/components/LocaleRouter.tsx" codeFormat="typescript"
729
- import { type Locales, configuration, getPathWithoutLocale } from "intlayer";
730
- import { ComponentChildren, FunctionalComponent } from "preact";
668
+ import { localeMap } from "intlayer";
731
669
  import { IntlayerProvider } from "preact-intlayer";
732
- import { LocationProvider, useLocation } from "preact-iso";
733
- import { useEffect } from "preact/hooks";
734
-
735
- const { internationalization, middleware } = configuration;
736
- const { locales, defaultLocale } = internationalization;
737
-
738
- const Navigate: FunctionalComponent<{ to: string; replace?: boolean }> = ({
739
- to,
740
- replace,
741
- }) => {
742
- const { route } = useLocation();
743
- useEffect(() => {
744
- route(to, replace);
745
- }, [to, replace, route]);
746
- return null;
747
- };
748
-
749
- /**
750
- * 一个处理本地化并用适当的语言环境上下文包裹子组件的组件。
751
- * 它管理基于 URL 的语言环境检测和验证。
752
- */
753
- /**
754
- * 一个处理本地化的组件,使用适当的语言环境上下文包裹子组件。
755
- * 它管理基于 URL 的语言环境检测和验证。
756
- */
757
- const AppLocalized: FunctionalComponent<{
758
- children: ComponentChildren;
759
- locale?: Locales;
760
- }> = ({ children, locale }) => {
761
- const { path: pathname, url } = useLocation();
762
-
763
- if (!url) {
764
- return null;
765
- }
766
-
767
- const search = url.substring(pathname.length);
768
-
769
- // 确定当前语言环境,如果未提供则回退到默认语言环境
770
- const currentLocale = locale ?? defaultLocale;
771
-
772
- // 从路径中移除语言环境前缀以构造基础路径
773
- const pathWithoutLocale = getPathWithoutLocale(
774
- pathname // 当前 URL 路径
775
- );
776
-
777
- /**
778
- * 如果 middleware.prefixDefault 为 true,则默认语言应始终带有前缀。
779
- */
780
- if (middleware.prefixDefault) {
781
- // 验证语言
782
- if (!locale || !locales.includes(locale)) {
783
- // 重定向到带有更新路径的默认语言
784
- return (
785
- <Navigate
786
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
787
- replace // 用新条目替换当前历史记录
788
- />
789
- );
790
- }
791
-
792
- // 使用 IntlayerProvider 包裹子组件并设置当前语言
793
- return (
794
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
795
- );
796
- } else {
797
- /**
798
- * 当 middleware.prefixDefault 为 false 时,默认语言不带前缀。
799
- * 确保当前语言环境有效且不是默认语言环境。
800
- */
801
- if (
802
- currentLocale.toString() !== defaultLocale.toString() &&
803
- !locales
804
- .filter(
805
- (loc) => loc.toString() !== defaultLocale.toString() // 排除默认语言环境
806
- )
807
- .includes(currentLocale) // 检查当前语言环境是否在有效语言环境列表中
808
- ) {
809
- // 重定向到无语言环境前缀的路径
810
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
811
- }
812
-
813
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
814
- return (
815
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
816
- );
817
- }
818
- };
819
-
820
- const RouterContent: FunctionalComponent<{
821
- children: ComponentChildren;
822
- }> = ({ children }) => {
823
- const { path } = useLocation();
824
-
825
- if (!path) {
826
- return null;
827
- }
828
-
829
- const pathLocale = path.split("/")[1] as Locales;
830
-
831
- const isLocaleRoute = locales
832
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
833
- .some((locale) => locale.toString() === pathLocale);
834
-
835
- if (isLocaleRoute) {
836
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
837
- }
838
-
839
- return (
840
- <AppLocalized
841
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
842
- >
843
- {children}
844
- </AppLocalized>
845
- );
846
- };
670
+ import { LocationProvider, Router, Route } from "preact-iso";
671
+ import type { ComponentChildren, FunctionalComponent } from "preact";
847
672
 
848
673
  /**
849
- * 一个设置特定语言环境路由的路由组件。
850
- * 它使用 preact-iso 来管理导航并渲染本地化组件。
674
+ * 设置特定语言环境路由的路由组件。
675
+ * 它使用 preact-iso 管理导航并渲染本地化组件。
851
676
  */
852
677
  export const LocaleRouter: FunctionalComponent<{
853
678
  children: ComponentChildren;
854
679
  }> = ({ children }) => (
855
680
  <LocationProvider>
856
- <RouterContent>{children}</RouterContent>
681
+ <Router>
682
+ {localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
683
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
684
+ .map(({ locale, urlPrefix }) => (
685
+ <Route
686
+ key={locale}
687
+ path={`${urlPrefix}/:rest*`}
688
+ component={() => (
689
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
690
+ )}
691
+ />
692
+ ))}
693
+ </Router>
857
694
  </LocationProvider>
858
695
  );
859
696
  ```
860
697
 
861
698
  ```jsx fileName="src/components/LocaleRouter.jsx" codeFormat="esm"
862
- // 导入必要的依赖和函数
863
- import { configuration, getPathWithoutLocale } from "intlayer";
699
+ import { localeMap } from "intlayer";
864
700
  import { IntlayerProvider } from "preact-intlayer";
865
- import { LocationProvider, useLocation } from "preact-iso";
866
- import { useEffect } from "preact/hooks";
867
- import { h } from "preact"; // JSX 所需
868
-
869
- // 从 Intlayer 中解构配置
870
- const { internationalization, middleware } = configuration;
871
- const { locales, defaultLocale } = internationalization;
872
-
873
- const Navigate = ({ to, replace }) => {
874
- const { route } = useLocation();
875
- useEffect(() => {
876
- route(to, replace);
877
- }, [to, replace, route]);
878
- return null;
879
- };
701
+ import { LocationProvider, Router, Route } from "preact-iso";
880
702
 
881
703
  /**
882
- * 一个处理本地化的组件,包裹子组件并提供相应的语言环境上下文。
883
- * 它管理基于 URL 的语言检测和验证。
884
- */
885
- const AppLocalized = ({ children, locale }) => {
886
- const { path: pathname, url } = useLocation();
887
-
888
- if (!url) {
889
- return null;
890
- }
891
-
892
- const search = url.substring(pathname.length);
893
-
894
- // 确定当前语言环境,如果未提供则回退到默认语言
895
- const currentLocale = locale ?? defaultLocale;
896
-
897
- // 从路径中移除语言前缀以构造基础路径
898
- const pathWithoutLocale = getPathWithoutLocale(
899
- pathname // 当前 URL 路径
900
- );
901
-
902
- /**
903
- * 如果 middleware.prefixDefault 为 true,默认语言应始终带有前缀。
904
- */
905
- if (middleware.prefixDefault) {
906
- // 验证语言环境
907
- if (!locale || !locales.includes(locale)) {
908
- // 重定向到带有更新路径的默认语言环境
909
- return (
910
- <Navigate
911
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
912
- replace // 用新的历史记录条目替换当前条目
913
- />
914
- );
915
- }
916
-
917
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
918
- return (
919
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
920
- );
921
- } else {
922
- /**
923
- * 当 middleware.prefixDefault 为 false 时,默认语言环境不带前缀。
924
- * 确保当前语言环境有效且不是默认语言环境。
925
- */
926
- if (
927
- currentLocale.toString() !== defaultLocale.toString() &&
928
- !locales
929
- .filter(
930
- (loc) => loc.toString() !== defaultLocale.toString() // 排除默认语言环境
931
- )
932
- .includes(currentLocale) // 检查当前语言环境是否在有效语言环境列表中
933
- ) {
934
- // 重定向到不带语言环境前缀的路径
935
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
936
- }
937
-
938
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
939
- return (
940
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
941
- );
942
- }
943
- };
944
-
945
- const RouterContent = ({ children }) => {
946
- const { path } = useLocation();
947
-
948
- if (!path) {
949
- return null;
950
- }
951
-
952
- const pathLocale = path.split("/")[1];
953
-
954
- const isLocaleRoute = locales
955
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
956
- .some((locale) => locale.toString() === pathLocale);
957
-
958
- if (isLocaleRoute) {
959
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
960
- }
961
-
962
- return (
963
- <AppLocalized
964
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
965
- >
966
- {children}
967
- </AppLocalized>
968
- );
969
- };
970
-
971
- /**
972
- * 一个设置特定语言环境路由的路由组件。
973
- * 它使用 preact-iso 来管理导航并渲染本地化组件。
704
+ * 设置特定语言环境路由的路由组件。
705
+ * 它使用 preact-iso 管理导航并渲染本地化组件。
974
706
  */
975
707
  export const LocaleRouter = ({ children }) => (
976
708
  <LocationProvider>
977
- <RouterContent>{children}</RouterContent>
709
+ <Router>
710
+ {localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
711
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
712
+ .map(({ locale, urlPrefix }) => (
713
+ <Route
714
+ key={locale}
715
+ path={`${urlPrefix}/:rest*`}
716
+ component={() => (
717
+ <IntlayerProvider locale={locale}>{children}</IntlayerProvider>
718
+ )}
719
+ />
720
+ ))}
721
+ </Router>
978
722
  </LocationProvider>
979
723
  );
980
724
  ```
981
725
 
982
726
  ```jsx fileName="src/components/LocaleRouter.cjsx" codeFormat="commonjs"
983
- // 导入必要的依赖和函数
984
- const { configuration, getPathWithoutLocale } = require("intlayer");
727
+ const { localeMap } = require("intlayer");
985
728
  const { IntlayerProvider } = require("preact-intlayer");
986
- const { LocationProvider, useLocation } = require("preact-iso");
987
- const { useEffect } = require("preact/hooks");
988
- const { h } = require("preact"); // JSX所需
989
-
990
- // 从Intlayer中解构配置
991
- const { internationalization, middleware } = configuration;
992
- const { locales, defaultLocale } = internationalization;
993
-
994
- const Navigate = ({ to, replace }) => {
995
- const { route } = useLocation();
996
- useEffect(() => {
997
- route(to, replace);
998
- }, [to, replace, route]);
999
- return null;
1000
- };
729
+ const { LocationProvider, Router, Route } = require("preact-iso");
1001
730
 
1002
731
  /**
1003
- * 一个处理本地化的组件,使用适当的语言环境上下文包裹子组件。
1004
- * 它管理基于URL的语言环境检测和验证。
732
+ * 设置特定语言环境路由的路由组件。
733
+ * 它使用 preact-iso 管理导航并渲染本地化组件。
1005
734
  */
1006
- const AppLocalized = ({ children, locale }) => {
1007
- const { path: pathname, url } = useLocation();
1008
-
1009
- if (!url) {
1010
- return null;
1011
- }
1012
-
1013
- const search = url.substring(pathname.length);
1014
-
1015
- // 确定当前语言环境,如果未提供则回退到默认语言环境
1016
- const currentLocale = locale ?? defaultLocale;
1017
-
1018
- // 从路径中移除语言环境前缀以构造基础路径
1019
- const pathWithoutLocale = getPathWithoutLocale(
1020
- pathname // 当前 URL 路径
1021
- );
1022
-
1023
- /**
1024
- * 如果 middleware.prefixDefault 为 true,则默认语言环境应始终带有前缀。
1025
- */
1026
- if (middleware.prefixDefault) {
1027
- // 验证语言环境
1028
- if (!locale || !locales.includes(locale)) {
1029
- // 重定向到带有更新路径的默认语言环境
1030
- return (
1031
- <Navigate
1032
- to={`/${defaultLocale}/${pathWithoutLocale}${search}`}
1033
- replace // 替换当前历史记录条目为新的条目
1034
- />
1035
- );
1036
- }
1037
-
1038
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
1039
- return (
1040
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
1041
- );
1042
- } else {
1043
- /**
1044
- * 当 middleware.prefixDefault 为 false 时,默认语言环境不带前缀。
1045
- * 确保当前语言环境有效且不是默认语言环境。
1046
- */
1047
- if (
1048
- currentLocale.toString() !== defaultLocale.toString() &&
1049
- !locales
1050
- .filter(
1051
- (loc) => loc.toString() !== defaultLocale.toString() // 排除默认语言环境
735
+ const LocaleRouter = ({ children }) =>
736
+ h(
737
+ LocationProvider,
738
+ {},
739
+ h(
740
+ Router,
741
+ {},
742
+ localeMap(({ locale, urlPrefix }) => ({ locale, urlPrefix }))
743
+ .sort((a, b) => b.urlPrefix.length - a.urlPrefix.length)
744
+ .map(({ locale, urlPrefix }) =>
745
+ h(Route, {
746
+ key: locale,
747
+ path: `${urlPrefix}/:rest*`,
748
+ component: () => h(IntlayerProvider, { locale }, children),
749
+ })
1052
750
  )
1053
- .includes(currentLocale) // 检查当前语言环境是否在有效语言环境列表中
1054
- ) {
1055
- // 重定向到无语言环境前缀的路径
1056
- return <Navigate to={`${pathWithoutLocale}${search}`} replace />;
1057
- }
1058
-
1059
- // 使用 IntlayerProvider 包裹子组件并设置当前语言环境
1060
- return (
1061
- <IntlayerProvider locale={currentLocale}>{children}</IntlayerProvider>
1062
- );
1063
- }
1064
- };
1065
-
1066
- const RouterContent = ({ children }) => {
1067
- const { path } = useLocation();
1068
-
1069
- if (!path) {
1070
- return null;
1071
- }
1072
-
1073
- const pathLocale = path.split("/")[1];
1074
-
1075
- const isLocaleRoute = locales
1076
- .filter((locale) => middleware.prefixDefault || locale !== defaultLocale)
1077
- .some((locale) => locale.toString() === pathLocale);
1078
-
1079
- if (isLocaleRoute) {
1080
- return <AppLocalized locale={pathLocale}>{children}</AppLocalized>;
1081
- }
1082
-
1083
- return (
1084
- <AppLocalized
1085
- locale={!middleware.prefixDefault ? defaultLocale : undefined}
1086
- >
1087
- {children}
1088
- </AppLocalized>
751
+ )
1089
752
  );
1090
- };
1091
-
1092
- /**
1093
- * 一个设置特定语言环境路由的路由组件。
1094
- * 它使用 preact-iso 来管理导航并渲染本地化组件。
1095
- */
1096
- const LocaleRouter = ({ children }) => (
1097
- <LocationProvider>
1098
- <RouterContent>{children}</RouterContent>
1099
- </LocationProvider>
1100
- );
1101
753
 
1102
754
  module.exports = { LocaleRouter };
1103
755
  ```
1104
756
 
1105
- 然后,你可以在你的应用中使用 `LocaleRouter` 组件:
757
+ 然后,您可以在应用程序中使用 `LocaleRouter` 组件:
1106
758
 
1107
759
  ```tsx fileName="src/app.tsx" codeFormat="typescript"
1108
760
  import { LocaleRouter } from "./components/LocaleRouter";
1109
761
  import type { FunctionalComponent } from "preact";
1110
- tsx fileName="src/app.tsx" codeFormat="typescript"
1111
- // ... 你的 AppContent 组件(在步骤5中定义)
762
+
763
+ // ... 您的 AppContent 组件
1112
764
 
1113
765
  const App: FunctionalComponent = () => (
1114
766
  <LocaleRouter>
@@ -1121,7 +773,8 @@ export default App;
1121
773
 
1122
774
  ```jsx fileName="src/app.jsx" codeFormat="esm"
1123
775
  import { LocaleRouter } from "./components/LocaleRouter";
1124
- // ... 你的 AppContent 组件(在步骤5中定义)
776
+
777
+ // ... 您的 AppContent 组件
1125
778
 
1126
779
  const App = () => (
1127
780
  <LocaleRouter>
@@ -1134,7 +787,8 @@ export default App;
1134
787
 
1135
788
  ```jsx fileName="src/app.cjsx" codeFormat="commonjs"
1136
789
  const { LocaleRouter } = require("./components/LocaleRouter");
1137
- // ... 你的 AppContent 组件(在步骤5中定义)
790
+
791
+ // ... 您的 AppContent 组件
1138
792
 
1139
793
  const App = () => (
1140
794
  <LocaleRouter>
@@ -1145,47 +799,12 @@ const App = () => (
1145
799
  module.exports = App;
1146
800
  ```
1147
801
 
1148
- 同时,您还可以使用 `intlayerProxy` 为您的应用程序添加服务器端路由。该插件将根据 URL 自动检测当前语言环境并设置相应的语言环境 Cookie。如果未指定语言环境,插件将根据用户浏览器的语言偏好确定最合适的语言环境。如果仍未检测到语言环境,则会重定向到默认语言环境。
1149
-
1150
- ```typescript {3,7} fileName="vite.config.ts" codeFormat="typescript"
1151
- import { defineConfig } from "vite";
1152
- import preact from "@preact/preset-vite";
1153
- import { intlayer, intlayerProxy } from "vite-intlayer";
1154
-
1155
- // https://vitejs.dev/config/
1156
- export default defineConfig({
1157
- plugins: [preact(), intlayer(), intlayerProxy()],
1158
- });
1159
- ```
1160
-
1161
- ```javascript {3,7} fileName="vite.config.mjs" codeFormat="esm"
1162
- import { defineConfig } from "vite";
1163
- import preact from "@preact/preset-vite";
1164
- import { intlayer, intlayerProxy } from "vite-intlayer";
802
+ ### (可选)步骤 8:在语言环境更改时更改 URL
1165
803
 
1166
- // https://vitejs.dev/config/
1167
- export default defineConfig({
1168
- plugins: [preact(), intlayer(), intlayerProxy()],
1169
- });
1170
- ```
1171
-
1172
- ```javascript {3,7} fileName="vite.config.cjs" codeFormat="commonjs"
1173
- const { defineConfig } = require("vite");
1174
- const preact = require("@preact/preset-vite");
1175
- const { intlayer, intlayerProxy } = require("vite-intlayer");
1176
-
1177
- // https://vitejs.dev/config/
1178
- module.exports = defineConfig({
1179
- plugins: [preact(), intlayer(), intlayerProxy()],
1180
- });
1181
- ```
1182
-
1183
- ### (可选)步骤 8:当语言环境改变时更改 URL
1184
-
1185
- 要在语言环境更改时更改 URL,您可以使用 `useLocale` 钩子提供的 `onLocaleChange` 属性。同时,您可以使用 `preact-iso` 中的 `useLocation` 和 `route` 来更新 URL 路径。
804
+ 要在语言环境更改时更改 URL,可以使用 `useLocale` 钩子提供的 `onLocaleChange` 属性。同时,您可以使用 `preact-iso` 中 `useLocation` 的 `route` 方法来更新 URL 路径。
1186
805
 
1187
806
  ```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat="typescript"
1188
- import { useLocation, route } from "preact-iso";
807
+ import { useLocation } from "preact-iso";
1189
808
  import {
1190
809
  Locales,
1191
810
  getHTMLTextDir,
@@ -1196,16 +815,15 @@ import { useLocale } from "preact-intlayer";
1196
815
  import type { FunctionalComponent } from "preact";
1197
816
 
1198
817
  const LocaleSwitcher: FunctionalComponent = () => {
1199
- const location = useLocation();
818
+ const { url, route } = useLocation();
1200
819
  const { locale, availableLocales, setLocale } = useLocale({
1201
820
  onLocaleChange: (newLocale) => {
1202
- const currentFullPath = location.url; // preact-iso 提供完整的 URL
1203
821
  // 使用更新后的语言环境构建 URL
1204
- // 例如: /es/about?foo=bar
1205
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
822
+ // 示例:/es/about?foo=bar
823
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1206
824
 
1207
825
  // 更新 URL 路径
1208
- route(pathWithLocale, true); // true 表示替换当前历史记录
826
+ route(pathWithLocale, true); // true 表示替换 (replace)
1209
827
  },
1210
828
  });
1211
829
 
@@ -1215,13 +833,13 @@ const LocaleSwitcher: FunctionalComponent = () => {
1215
833
  <div id="localePopover" popover="auto">
1216
834
  {availableLocales.map((localeItem) => (
1217
835
  <a
1218
- href={getLocalizedUrl(location.url, localeItem)}
836
+ href={getLocalizedUrl(url, localeItem)}
1219
837
  hreflang={localeItem}
1220
838
  aria-current={locale === localeItem ? "page" : undefined}
1221
839
  onClick={(e) => {
1222
840
  e.preventDefault();
1223
841
  setLocale(localeItem);
1224
- // 设置语言环境后,程序化导航将由 onLocaleChange 处理
842
+ // 设置语言环境后的程序化导航将由 onLocaleChange 处理
1225
843
  }}
1226
844
  key={localeItem}
1227
845
  >
@@ -1230,15 +848,15 @@ const LocaleSwitcher: FunctionalComponent = () => {
1230
848
  {localeItem}
1231
849
  </span>
1232
850
  <span>
1233
- {/* 语言在其自身语言环境中的名称 - 例如 Français */}
851
+ {/* 该语言环境自身的语言名称 - 例如 Français */}
1234
852
  {getLocaleName(localeItem, localeItem)}
1235
853
  </span>
1236
854
  <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1237
- {/* 语言在当前语言环境中的名称 - 例如当前语言环境为 Locales.SPANISH 时显示 Francés */}
855
+ {/* 当前语言环境下的语言名称 - 例如当当前语言环境为 Locales.SPANISH 时显示 Francés */}
1238
856
  {getLocaleName(localeItem, locale)}
1239
857
  </span>
1240
858
  <span dir="ltr" lang={Locales.ENGLISH}>
1241
- {/* 语言的英文名称 - 例如 French */}
859
+ {/* 英语名称 - 例如 French */}
1242
860
  {getLocaleName(localeItem, Locales.ENGLISH)}
1243
861
  </span>
1244
862
  </a>
@@ -1252,7 +870,7 @@ export default LocaleSwitcher;
1252
870
  ```
1253
871
 
1254
872
  ```jsx fileName="src/components/LocaleSwitcher.jsx" codeFormat="esm"
1255
- import { useLocation, route } from "preact-iso";
873
+ import { useLocation } from "preact-iso";
1256
874
  import {
1257
875
  Locales,
1258
876
  getHTMLTextDir,
@@ -1260,14 +878,12 @@ import {
1260
878
  getLocalizedUrl,
1261
879
  } from "intlayer";
1262
880
  import { useLocale } from "preact-intlayer";
1263
- import { h } from "preact"; // 用于 JSX
1264
881
 
1265
882
  const LocaleSwitcher = () => {
1266
- const location = useLocation();
883
+ const { url, route } = useLocation();
1267
884
  const { locale, availableLocales, setLocale } = useLocale({
1268
885
  onLocaleChange: (newLocale) => {
1269
- const currentFullPath = location.url;
1270
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
886
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1271
887
  route(pathWithLocale, true);
1272
888
  },
1273
889
  });
@@ -1278,7 +894,7 @@ const LocaleSwitcher = () => {
1278
894
  <div id="localePopover" popover="auto">
1279
895
  {availableLocales.map((localeItem) => (
1280
896
  <a
1281
- href={getLocalizedUrl(location.url, localeItem)}
897
+ href={getLocalizedUrl(url, localeItem)}
1282
898
  hreflang={localeItem}
1283
899
  aria-current={locale === localeItem ? "page" : undefined}
1284
900
  onClick={(e) => {
@@ -1306,7 +922,7 @@ export default LocaleSwitcher;
1306
922
  ```
1307
923
 
1308
924
  ```jsx fileName="src/components/LocaleSwitcher.cjsx" codeFormat="commonjs"
1309
- const { useLocation, route } = require("preact-iso");
925
+ const { useLocation } = require("preact-iso");
1310
926
  const {
1311
927
  Locales,
1312
928
  getHTMLTextDir,
@@ -1314,45 +930,51 @@ const {
1314
930
  getLocalizedUrl,
1315
931
  } = require("intlayer");
1316
932
  const { useLocale } = require("preact-intlayer");
1317
- const { h } = require("preact"); // 用于 JSX
1318
933
 
1319
934
  const LocaleSwitcher = () => {
1320
- const location = useLocation();
935
+ const { url, route } = useLocation();
1321
936
  const { locale, availableLocales, setLocale } = useLocale({
1322
937
  onLocaleChange: (newLocale) => {
1323
- const currentFullPath = location.url;
1324
- const pathWithLocale = getLocalizedUrl(currentFullPath, newLocale);
938
+ const pathWithLocale = getLocalizedUrl(url, newLocale);
1325
939
  route(pathWithLocale, true);
1326
940
  },
1327
941
  });
1328
942
 
1329
- return (
1330
- <div>
1331
- <button popovertarget="localePopover">{getLocaleName(locale)}</button>
1332
- <div id="localePopover" popover="auto">
1333
- {availableLocales.map((localeItem) => (
1334
- <a
1335
- href={getLocalizedUrl(location.url, localeItem)}
1336
- hreflang={localeItem}
1337
- aria-current={locale === localeItem ? "page" : undefined}
1338
- onClick={(e) => {
943
+ return h(
944
+ "div",
945
+ {},
946
+ h("button", { popovertarget: "localePopover" }, getLocaleName(locale)),
947
+ h(
948
+ "div",
949
+ { id: "localePopover", popover: "auto" },
950
+ availableLocales.map((localeItem) =>
951
+ h(
952
+ "a",
953
+ {
954
+ href: getLocalizedUrl(url, localeItem),
955
+ hreflang: localeItem,
956
+ "aria-current": locale === localeItem ? "page" : undefined,
957
+ onClick: (e) => {
1339
958
  e.preventDefault();
1340
959
  setLocale(localeItem);
1341
- }}
1342
- key={localeItem}
1343
- >
1344
- <span>{localeItem}</span>
1345
- <span>{getLocaleName(localeItem, localeItem)}</span>
1346
- <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1347
- {getLocaleName(localeItem, locale)}
1348
- </span>
1349
- <span dir="ltr" lang={Locales.ENGLISH}>
1350
- {getLocaleName(localeItem, Locales.ENGLISH)}
1351
- </span>
1352
- </a>
1353
- ))}
1354
- </div>
1355
- </div>
960
+ },
961
+ key: localeItem,
962
+ },
963
+ h("span", {}, localeItem),
964
+ h("span", {}, getLocaleName(localeItem, localeItem)),
965
+ h(
966
+ "span",
967
+ { dir: getHTMLTextDir(localeItem), lang: localeItem },
968
+ getLocaleName(localeItem, locale)
969
+ ),
970
+ h(
971
+ "span",
972
+ { dir: "ltr", lang: Locales.ENGLISH },
973
+ getLocaleName(localeItem, Locales.ENGLISH)
974
+ )
975
+ )
976
+ )
977
+ )
1356
978
  );
1357
979
  };
1358
980
 
@@ -1361,25 +983,21 @@ module.exports = LocaleSwitcher;
1361
983
 
1362
984
  > 文档参考:
1363
985
  >
1364
- > > - [`useLocale` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(`preact-intlayer` 的 API 类似)> - [`getLocaleName` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocaleName.md)> - [`getLocalizedUrl` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocalizedUrl.md)> - [`getHTMLTextDir` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getHTMLTextDir.md)> - [`hreflang` 属性](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [`lang` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/lang)> - [`dir` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/dir)> - [`aria-current` 属性](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [Popover API](https://developer.mozilla.org/zh-CN/docs/Web/API/Popover_API)> > - [`useLocale` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(`preact-intlayer` 的 API 类似)> - [`getLocaleName` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocaleName.md)> - [`getLocalizedUrl` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocalizedUrl.md)> - [`getHTMLTextDir` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getHTMLTextDir.md)> - [`hreflang` 属性](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [`lang` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/lang)> - [`dir` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/dir)> - [`aria-current` 属性](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [Popover API](https://developer.mozilla.org/zh-CN/docs/Web/API/Popover_API)
1365
-
1366
- 下面是更新后的**第9步**,增加了说明和优化的代码示例:
986
+ > > - [`useLocale` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/react-intlayer/useLocale.md)(`preact-intlayer` 的 API 类似)> - [`getLocaleName` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocaleName.md)> - [`getLocalizedUrl` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocalizedUrl.md)> - [`getHTMLTextDir` 钩子](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getHTMLTextDir.md)> - [`hreflang` 属性](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)> - [`lang` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/lang)> - [`dir` 属性](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Global_attributes/dir)> - [`aria-current` 属性](https://developer.mozilla.org/zh-CN/docs/Web/Accessibility/ARIA/Attributes/aria-current)> - [Popover API](https://developer.mozilla.org/zh-CN/docs/Web/API/Popover_API)
1367
987
 
1368
- ---
1369
-
1370
- ### (可选)第9步:切换HTML的语言和方向属性
988
+ ### (可选)第 9 步:切换 HTML 语言和方向属性
1371
989
 
1372
- 当您的应用支持多语言时,更新`<html>`标签的`lang`和`dir`属性以匹配当前语言环境非常重要。这样做可以确保:
990
+ 当您的应用程序支持多种语言时,更新 `<html>` 标签的 `lang` 和 `dir` 属性以匹配当前语言环境至关重要。这样做可以确保:
1373
991
 
1374
- - **无障碍性**:屏幕阅读器和辅助技术依赖正确的`lang`属性来准确发音和解释内容。
1375
- - **文本渲染**:`dir`(方向)属性确保文本以正确的顺序呈现(例如,英语为从左到右,阿拉伯语或希伯来语为从右到左),这对可读性至关重要。
992
+ - **无障碍性**:屏幕阅读器和辅助技术依靠正确的 `lang` 属性来准确发音和解释内容。
993
+ - **文本渲染**:`dir`(方向)属性确保文本以正确的顺序呈现(例如,英语从左到右,阿拉伯语或希伯来语从右到左),这对于可读性至关重要。
1376
994
  - **SEO**:搜索引擎使用 `lang` 属性来确定页面的语言,有助于在搜索结果中提供正确的本地化内容。
1377
995
 
1378
- 通过在语言环境变化时动态更新这些属性,您可以确保所有支持语言的用户都能获得一致且无障碍的体验。
996
+ 通过在语言环境更改时动态更新这些属性,您可以确保所有支持语言的用户都能获得一致且无障碍的体验。
1379
997
 
1380
- #### 实现该 Hook
998
+ #### 实现钩子
1381
999
 
1382
- 创建一个自定义 Hook 来管理 HTML 属性。该 Hook 监听语言环境的变化并相应地更新属性:
1000
+ 创建一个自定义钩子来管理 HTML 属性。该钩子监听语言环境更改并相应地更新属性:
1383
1001
 
1384
1002
  ```tsx fileName="src/hooks/useI18nHTMLAttributes.tsx" codeFormat="typescript"
1385
1003
  import { useEffect } from "preact/hooks";
@@ -1388,8 +1006,8 @@ import { getHTMLTextDir } from "intlayer";
1388
1006
 
1389
1007
  /**
1390
1008
  * 根据当前语言环境更新 HTML <html> 元素的 `lang` 和 `dir` 属性。
1391
- * - `lang`:通知浏览器和搜索引擎页面的语言。
1392
- * - `dir`:确保正确的阅读顺序(例如,英语为 'ltr',阿拉伯语为 'rtl')。
1009
+ * - `lang`: 通知浏览器和搜索引擎页面的语言。
1010
+ * - `dir`: 确保正确的阅读顺序(例如,英语为 'ltr',阿拉伯语为 'rtl')。
1393
1011
  *
1394
1012
  * 这种动态更新对于正确的文本渲染、无障碍访问和 SEO 至关重要。
1395
1013
  */
@@ -1397,7 +1015,7 @@ export const useI18nHTMLAttributes = () => {
1397
1015
  const { locale } = useLocale();
1398
1016
 
1399
1017
  useEffect(() => {
1400
- // 将语言属性更新为当前的语言环境。
1018
+ // 将语言属性更新为当前语言环境。
1401
1019
  document.documentElement.lang = locale;
1402
1020
 
1403
1021
  // 根据当前语言环境设置文本方向。
@@ -1444,22 +1062,22 @@ const useI18nHTMLAttributes = () => {
1444
1062
  module.exports = { useI18nHTMLAttributes };
1445
1063
  ```
1446
1064
 
1447
- #### 在您的应用程序中使用该 Hook
1065
+ #### 在应用程序中使用钩子
1448
1066
 
1449
- 将该 Hook 集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
1067
+ 将钩子集成到您的主组件中,以便在语言环境更改时更新 HTML 属性:
1450
1068
 
1451
1069
  ```tsx fileName="src/app.tsx" codeFormat="typescript"
1452
1070
  import type { FunctionalComponent } from "preact";
1453
- import { IntlayerProvider } from "preact-intlayer"; // 如果 AppContent 需要,useIntlayer 已经导入
1071
+ import { IntlayerProvider } from "preact-intlayer"; // 如果 AppContent 需要,useIntlayer 已导入
1454
1072
  import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
1455
1073
  import "./app.css";
1456
- // 第5步中定义的 AppContent
1074
+ // 第 5 步中的 AppContent 定义
1457
1075
 
1458
1076
  const AppWithHooks: FunctionalComponent = () => {
1459
- // 应用该 Hook 以根据当前语言环境更新 <html> 标签的 lang 和 dir 属性。
1077
+ // 应用钩子以根据语言环境更新 <html> 标签的 lang 和 dir 属性。
1460
1078
  useI18nHTMLAttributes();
1461
1079
 
1462
- // 假设 AppContent 是您在第 5 步中定义的主要内容展示组件
1080
+ // 假设 AppContent 是您在第 5 步中的主要内容显示组件
1463
1081
  return <AppContent />;
1464
1082
  };
1465
1083
 
@@ -1476,7 +1094,7 @@ export default App;
1476
1094
  import { IntlayerProvider } from "preact-intlayer";
1477
1095
  import { useI18nHTMLAttributes } from "./hooks/useI18nHTMLAttributes";
1478
1096
  import "./app.css";
1479
- // AppContent 定义来自第 5
1097
+ // 5 步中的 AppContent 定义
1480
1098
 
1481
1099
  const AppWithHooks = () => {
1482
1100
  useI18nHTMLAttributes();
@@ -1496,7 +1114,7 @@ export default App;
1496
1114
  const { IntlayerProvider } = require("preact-intlayer");
1497
1115
  const { useI18nHTMLAttributes } = require("./hooks/useI18nHTMLAttributes");
1498
1116
  require("./app.css");
1499
- // 第5步中定义的 AppContent
1117
+ // 第 5 步中的 AppContent 定义
1500
1118
 
1501
1119
  const AppWithHooks = () => {
1502
1120
  useI18nHTMLAttributes();
@@ -1512,209 +1130,186 @@ const App = () => (
1512
1130
  module.exports = App;
1513
1131
  ```
1514
1132
 
1515
- 通过应用这些更改,您的应用程序将:
1516
-
1517
- - 确保 **语言** (`lang`) 属性正确反映当前的语言环境,这对于 SEO 和浏览器行为非常重要。
1518
- - 根据语言环境调整 **文本方向** (`dir`),提升不同阅读顺序语言的可读性和可用性。
1519
- - 提供更**无障碍**的体验,因为辅助技术依赖这些属性来实现最佳功能。
1133
+ ### (可选)第 10 步:创建本地化链接组件
1520
1134
 
1521
- ### (可选)步骤10:创建本地化链接组件
1135
+ 为了确保您的应用程序导航尊重当前语言环境,您可以创建一个自定义 `Link` 组件。此组件会自动为内部 URL 添加当前语言前缀。
1522
1136
 
1523
- 为了确保您的应用导航尊重当前语言环境,您可以创建一个自定义的 `Link` 组件。该组件会自动为内部 URL 添加当前语言的前缀。
1137
+ 这种行为在以下几个方面非常有用:
1524
1138
 
1525
- 这种行为有几个好处:
1139
+ - **SEO 和用户体验**:本地化 URL 帮助搜索引擎正确索引特定语言的页面,并为用户提供其首选语言的内容。
1140
+ - **一致性**:通过在整个应用程序中使用本地化链接,您可以确保导航保持在当前语言环境内,防止意外的语言切换。
1141
+ - **可维护性**:将本地化逻辑集中在单个组件中可以简化 URL 的管理。
1526
1142
 
1527
- - **SEO 和用户体验**:本地化的 URL 有助于搜索引擎正确索引特定语言的页面,并为用户提供其偏好的语言内容。
1528
- - **一致性**:通过在整个应用中使用本地化链接,您可以确保导航保持在当前语言环境内,避免意外的语言切换。
1529
- - **可维护性**:将本地化逻辑集中在单个组件中简化了 URL 的管理。
1143
+ 以下是 Preact 中本地化 `Link` 组件的实现:
1530
1144
 
1531
- 对于使用 `preact-iso` 的 Preact,通常使用标准的 `<a>` 标签进行导航,`preact-iso` 负责路由处理。如果你需要在点击时进行编程式导航(例如,在导航前执行某些操作),可以使用来自 `useLocation` 的 `route` 函数。下面是如何创建一个本地化 URL 的自定义锚点组件:
1532
-
1533
- ```tsx fileName="src/components/LocalizedLink.tsx" codeFormat="typescript"
1145
+ ```tsx fileName="src/components/Link.tsx" codeFormat="typescript"
1534
1146
  import { getLocalizedUrl } from "intlayer";
1535
- import { useLocale, useLocation, route } from "preact-intlayer"; // 假设 useLocation 和 route 可以通过 preact-intlayer 从 preact-iso 重新导出,或者直接导入
1536
- // 如果没有重新导出,直接导入:import { useLocation, route } from "preact-iso";
1537
- import type { JSX } from "preact"; // 用于 HTMLAttributes
1538
- import { forwardRef } from "preact/compat"; // 用于转发 refs
1147
+ import { useLocale } from "preact-intlayer";
1148
+ import { forwardRef } from "preact/compat";
1149
+ import type { JSX } from "preact";
1539
1150
 
1540
- export interface LocalizedLinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
1151
+ export interface LinkProps extends JSX.HTMLAttributes<HTMLAnchorElement> {
1541
1152
  href: string;
1542
- replace?: boolean; // 可选:替换历史记录状态
1543
1153
  }
1544
1154
 
1545
1155
  /**
1546
- * 工具函数,用于检查给定的 URL 是否为外部链接。
1547
- * 如果 URL 以 http:// 或 https:// 开头,则视为外部链接。
1156
+ * 检查给定 URL 是否为外部链接的实用函数。
1157
+ * 如果 URL 以 http:// 或 https:// 开头,则被视为外部链接。
1548
1158
  */
1549
1159
  export const checkIsExternalLink = (href?: string): boolean =>
1550
1160
  /^https?:\/\//.test(href ?? "");
1551
1161
 
1552
1162
  /**
1553
- * 一个自定义的 Link 组件,根据当前语言环境调整 href 属性。
1554
- * 对于内部链接,它使用 `getLocalizedUrl` URL 前添加语言前缀(例如 /fr/about)。
1555
- * 这确保导航保持在相同的语言环境中。
1556
- * 它使用标准的 <a> 标签,但可以通过 preact-iso 的 `route` 触发客户端导航。
1163
+ * 一个自定义 Link 组件,根据当前语言环境自适应 href 属性。
1164
+ * 对于内部链接,它使用 `getLocalizedUrl` URL 添加语言环境前缀(例如 /fr/about)。
1165
+ * 这确保了导航保持在同一语言环境上下文中。
1557
1166
  */
1558
- export const LocalizedLink = forwardRef<HTMLAnchorElement, LocalizedLinkProps>(
1559
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1167
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
1168
+ ({ href, children, ...props }, ref) => {
1560
1169
  const { locale } = useLocale();
1561
- const location = useLocation(); // 来自 preact-iso
1562
1170
  const isExternalLink = checkIsExternalLink(href);
1563
1171
 
1172
+ // 如果链接是内部的且提供了有效的 href,则获取本地化 URL。
1564
1173
  const hrefI18n =
1565
1174
  href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1566
1175
 
1567
- const handleClick = (event: JSX.TargetedMouseEvent<HTMLAnchorElement>) => {
1568
- if (onClick) {
1569
- onClick(event);
1570
- }
1571
- if (
1572
- !isExternalLink &&
1573
- href && // 确保 href 已定义
1574
- event.button === 0 && // 左键点击
1575
- !event.metaKey &&
1576
- !event.ctrlKey &&
1577
- !event.shiftKey &&
1578
- !event.altKey && // 标准修饰键检查
1579
- !props.target // 不在新标签页/窗口打开
1580
- ) {
1581
- event.preventDefault();
1582
- if (location.url !== hrefI18n) {
1583
- // 仅当 URL 不同时才导航
1584
- route(hrefI18n, replace); // 使用 preact-iso 的 route
1585
- }
1586
- }
1587
- };
1588
-
1589
1176
  return (
1590
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1177
+ <a href={hrefI18n} ref={ref} {...props}>
1591
1178
  {children}
1592
1179
  </a>
1593
1180
  );
1594
1181
  }
1595
1182
  );
1183
+
1184
+ Link.displayName = "Link";
1596
1185
  ```
1597
1186
 
1598
- ```jsx fileName="src/components/LocalizedLink.jsx" codeFormat="esm"
1187
+ ```jsx fileName="src/components/Link.jsx" codeFormat="esm"
1599
1188
  import { getLocalizedUrl } from "intlayer";
1600
1189
  import { useLocale } from "preact-intlayer";
1601
- import { useLocation, route } from "preact-iso"; // 从 preact-iso 导入
1602
1190
  import { forwardRef } from "preact/compat";
1603
- import { h } from "preact"; // 用于 JSX
1604
1191
 
1192
+ /**
1193
+ * 检查给定 URL 是否为外部链接的实用函数。
1194
+ * 如果 URL 以 http:// 或 https:// 开头,则被视为外部链接。
1195
+ */
1605
1196
  export const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1606
1197
 
1607
- export const LocalizedLink = forwardRef(
1608
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1609
- const { locale } = useLocale();
1610
- const location = useLocation();
1611
- const isExternalLink = checkIsExternalLink(href);
1198
+ /**
1199
+ * 一个自定义 Link 组件,根据当前语言环境自适应 href 属性。
1200
+ * 对于内部链接,它使用 `getLocalizedUrl` URL 添加语言环境前缀(例如 /fr/about)。
1201
+ * 这确保了导航保持在同一语言环境上下文中。
1202
+ */
1203
+ export const Link = forwardRef(({ href, children, ...props }, ref) => {
1204
+ const { locale } = useLocale();
1205
+ const isExternalLink = checkIsExternalLink(href);
1612
1206
 
1613
- const hrefI18n =
1614
- href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1207
+ // 如果链接是内部的且提供了有效的 href,则获取本地化 URL。
1208
+ const hrefI18n =
1209
+ href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1615
1210
 
1616
- const handleClick = (event) => {
1617
- if (onClick) {
1618
- onClick(event);
1619
- }
1620
- if (
1621
- !isExternalLink &&
1622
- href &&
1623
- event.button === 0 &&
1624
- !event.metaKey &&
1625
- !event.ctrlKey &&
1626
- !event.shiftKey &&
1627
- !event.altKey &&
1628
- !props.target
1629
- ) {
1630
- event.preventDefault();
1631
- if (location.url !== hrefI18n) {
1632
- route(hrefI18n, replace);
1633
- }
1634
- }
1635
- };
1211
+ return (
1212
+ <a href={hrefI18n} ref={ref} {...props}>
1213
+ {children}
1214
+ </a>
1215
+ );
1216
+ });
1636
1217
 
1637
- return (
1638
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1639
- {children}
1640
- </a>
1641
- );
1642
- }
1643
- );
1218
+ Link.displayName = "Link";
1644
1219
  ```
1645
1220
 
1646
- ```jsx fileName="src/components/LocalizedLink.cjsx" codeFormat="commonjs"
1221
+ ```jsx fileName="src/components/Link.cjsx" codeFormat="commonjs"
1647
1222
  const { getLocalizedUrl } = require("intlayer");
1648
1223
  const { useLocale } = require("preact-intlayer");
1649
- const { useLocation, route } = require("preact-iso"); // 从 preact-iso 导入
1650
1224
  const { forwardRef } = require("preact/compat");
1651
- const { h } = require("preact"); // 用于 JSX
1652
1225
 
1226
+ /**
1227
+ * 检查给定 URL 是否为外部链接的实用函数。
1228
+ * 如果 URL 以 http:// 或 https:// 开头,则被视为外部链接。
1229
+ */
1653
1230
  const checkIsExternalLink = (href) => /^https?:\/\//.test(href ?? "");
1654
1231
 
1655
- // 检查是否为外部链接的函数
1656
- const LocalizedLink = forwardRef(
1657
- ({ href, children, onClick, replace = false, ...props }, ref) => {
1658
- const { locale } = useLocale(); // 获取当前语言环境
1659
- const location = useLocation(); // 获取当前路由信息
1660
- const isExternalLink = checkIsExternalLink(href); // 判断是否为外部链接
1661
-
1662
- // 如果是内部链接,则根据当前语言环境生成本地化链接
1663
- const hrefI18n =
1664
- href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1665
-
1666
- const handleClick = (event) => {
1667
- if (onClick) {
1668
- onClick(event);
1669
- }
1670
- if (
1671
- !isExternalLink &&
1672
- href &&
1673
- event.button === 0 &&
1674
- !event.metaKey &&
1675
- !event.ctrlKey &&
1676
- !event.shiftKey &&
1677
- !event.altKey &&
1678
- !props.target
1679
- ) {
1680
- event.preventDefault();
1681
- if (location.url !== hrefI18n) {
1682
- route(hrefI18n, replace);
1683
- }
1684
- }
1685
- };
1232
+ /**
1233
+ * 一个自定义 Link 组件,根据当前语言环境自适应 href 属性。
1234
+ * 对于内部链接,它使用 `getLocalizedUrl` URL 添加语言环境前缀(例如 /fr/about)。
1235
+ * 这确保了导航保持在同一语言环境上下文中。
1236
+ */
1237
+ const Link = forwardRef(({ href, children, ...props }, ref) => {
1238
+ const { locale } = useLocale();
1239
+ const isExternalLink = checkIsExternalLink(href);
1240
+
1241
+ // 如果链接是内部的且提供了有效的 href,则获取本地化 URL。
1242
+ const hrefI18n =
1243
+ href && !isExternalLink ? getLocalizedUrl(href, locale) : href;
1244
+
1245
+ return h(
1246
+ "a",
1247
+ {
1248
+ href: hrefI18n,
1249
+ ref: ref,
1250
+ ...props,
1251
+ },
1252
+ children
1253
+ );
1254
+ });
1686
1255
 
1687
- return (
1688
- <a href={hrefI18n} ref={ref} onClick={handleClick} {...props}>
1689
- {children}
1690
- </a>
1691
- );
1692
- }
1693
- );
1256
+ Link.displayName = "Link";
1694
1257
 
1695
- module.exports = { LocalizedLink, checkIsExternalLink };
1258
+ module.exports = { Link, checkIsExternalLink };
1696
1259
  ```
1697
1260
 
1698
1261
  #### 工作原理
1699
1262
 
1700
1263
  - **检测外部链接**:
1701
- 辅助函数 `checkIsExternalLink` 用于判断 URL 是否为外部链接。外部链接保持不变。
1702
- - **获取当前语言环境**:
1703
- `useLocale` 钩子提供当前的语言环境。
1264
+ 辅助函数 `checkIsExternalLink` 确定 URL 是否为外部。外部链接保持不变,因为它们不需要本地化。
1265
+ - **检索当前语言环境**:
1266
+ `useLocale` 钩子提供当前的语言环境(例如,法语为 `fr`)。
1704
1267
  - **本地化 URL**:
1705
- 对于内部链接,`getLocalizedUrl` 会在 URL 前添加当前语言环境的前缀。
1706
- - **客户端导航**:
1707
- `handleClick` 函数会检查链接是否为内部链接以及是否应阻止标准导航。如果是,则使用 `preact-iso` 的 `route` 函数(通过 `useLocation` 获取或直接导入)来执行客户端导航。这提供了类似 SPA 的行为,而无需完全重新加载页面。
1268
+ 对于内部链接(即非外部链接),使用 `getLocalizedUrl` 自动为 URL 添加当前语言环境的前缀。这意味着如果您的用户处于法语环境,将 `/about` 作为 `href` 传递将使其转换为 `/fr/about`。
1708
1269
  - **返回链接**:
1709
- 该组件返回一个带有本地化 URL 和自定义点击处理程序的 `<a>` 元素。
1270
+ 该组件返回一个带有本地化 URL `<a>` 元素,确保导航与语言环境保持一致。
1271
+
1272
+ ### (可选)第 11 步:渲染 Markdown 和 HTML
1273
+
1274
+ Intlayer 支持在 Preact 中渲染 Markdown 和 HTML 内容。
1275
+
1276
+ 您可以通过使用 `.use()` 方法自定义 Markdown 和 HTML 内容的渲染。此方法允许您覆盖特定标签的默认渲染。
1277
+
1278
+ ```tsx
1279
+ import { useIntlayer } from "preact-intlayer";
1280
+
1281
+ const { myMarkdownContent, myHtmlContent } = useIntlayer("my-component");
1282
+
1283
+ // ...
1284
+
1285
+ return (
1286
+ <div>
1287
+ {/* 基本渲染 */}
1288
+ {myMarkdownContent}
1289
+
1290
+ {/* Markdown 的自定义渲染 */}
1291
+ {myMarkdownContent.use({
1292
+ h1: (props) => <h1 style={{ color: "red" }} {...props} />,
1293
+ })}
1294
+
1295
+ {/* HTML 的基本渲染 */}
1296
+ {myHtmlContent}
1297
+
1298
+ {/* HTML 的自定义渲染 */}
1299
+ {myHtmlContent.use({
1300
+ b: (props) => <strong style={{ color: "blue" }} {...props} />,
1301
+ })}
1302
+ </div>
1303
+ );
1304
+ ```
1710
1305
 
1711
1306
  ### 配置 TypeScript
1712
1307
 
1713
1308
  Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库更健壮。
1714
1309
 
1715
- ![Autocompletion](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1310
+ ![自动补全](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1716
1311
 
1717
- ![Translation error](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1312
+ ![翻译错误](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1718
1313
 
1719
1314
  确保您的 TypeScript 配置包含自动生成的类型。
1720
1315
 
@@ -1724,7 +1319,7 @@ Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库
1724
1319
  "compilerOptions": {
1725
1320
  // ...
1726
1321
  "jsx": "react-jsx",
1727
- "jsxImportSource": "preact", // 推荐用于 Preact 10 及以上版本
1322
+ "jsxImportSource": "preact", // 推荐用于 Preact 10+
1728
1323
  // ...
1729
1324
  },
1730
1325
  "include": [
@@ -1734,13 +1329,13 @@ Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库
1734
1329
  }
1735
1330
  ```
1736
1331
 
1737
- > 确保您的 `tsconfig.json` 针对 Preact 进行了设置,特别是 `jsx` 和 `jsxImportSource`,或者对于旧版本的 Preact,如果不使用 `preset-vite` 的默认配置,则需配置 `jsxFactory`/`jsxFragmentFactory`。
1332
+ > 确保您的 `tsconfig.json` 已为 Preact 设置,特别是 `jsx` 和 `jsxImportSource`;如果不使用 `preset-vite` 的默认值,对于较旧的 Preact 版本,还需要设置 `jsxFactory`/`jsxFragmentFactory`。
1738
1333
 
1739
1334
  ### Git 配置
1740
1335
 
1741
- 建议忽略 Intlayer 生成的文件。这样可以避免将它们提交到您的 Git 仓库中。
1336
+ 建议忽略 Intlayer 生成的文件。这样可以避免将它们提交到您的 Git 仓库。
1742
1337
 
1743
- 要做到这一点,您可以将以下指令添加到您的 `.gitignore` 文件中:
1338
+ 为此,您可以在 `.gitignore` 文件中添加以下指令:
1744
1339
 
1745
1340
  ```plaintext
1746
1341
  # 忽略 Intlayer 生成的文件
@@ -1753,19 +1348,19 @@ Intlayer 使用模块增强来利用 TypeScript 的优势,使您的代码库
1753
1348
 
1754
1349
  [从 VS Code 市场安装](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1755
1350
 
1756
- 该扩展提供:
1351
+ 此扩展提供:
1757
1352
 
1758
- - 翻译键的**自动补全**。
1759
- - 缺失翻译的**实时错误检测**。
1760
- - 翻译内容的**内联预览**。
1761
- - 轻松创建和更新翻译的**快速操作**。
1353
+ - **自动补全** 翻译键。
1354
+ - **实时错误检测** 缺失的翻译。
1355
+ - **内联预览** 翻译内容。
1356
+ - **快速操作** 轻松创建和更新翻译。
1762
1357
 
1763
- 有关如何使用该扩展的更多详细信息,请参阅 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
1358
+ 有关如何使用该扩展的更多详细信息,请参考 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
1764
1359
 
1765
1360
  ---
1766
1361
 
1767
- ### 深入探索
1362
+ ### 深入了解
1768
1363
 
1769
- 要进一步使用,您可以实现[可视化编辑器](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)将内容外部化。
1364
+ 要进一步了解,您可以实现 [可视化编辑器](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) 将内容外部化。
1770
1365
 
1771
1366
  ---