@intlayer/docs 7.5.11 → 7.5.13

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 (417) hide show
  1. package/blog/ar/intlayer_with_i18next.md +0 -2
  2. package/blog/ar/intlayer_with_next-i18next.md +0 -2
  3. package/blog/ar/intlayer_with_react-i18next.md +0 -2
  4. package/blog/de/intlayer_with_i18next.md +0 -45
  5. package/blog/de/intlayer_with_next-i18next.md +0 -46
  6. package/blog/de/intlayer_with_react-i18next.md +0 -2
  7. package/blog/en/intlayer_with_i18next.md +0 -46
  8. package/blog/en/intlayer_with_next-i18next.md +0 -48
  9. package/blog/en/intlayer_with_next-intl.md +0 -44
  10. package/blog/en/intlayer_with_react-i18next.md +0 -44
  11. package/blog/en/intlayer_with_react-intl.md +0 -42
  12. package/blog/en/intlayer_with_vue-i18n.md +0 -44
  13. package/blog/en-GB/intlayer_with_i18next.md +0 -45
  14. package/blog/en-GB/intlayer_with_next-i18next.md +0 -47
  15. package/blog/en-GB/intlayer_with_next-intl.md +0 -42
  16. package/blog/en-GB/intlayer_with_react-i18next.md +0 -43
  17. package/blog/en-GB/intlayer_with_react-intl.md +0 -42
  18. package/blog/en-GB/intlayer_with_vue-i18n.md +0 -46
  19. package/blog/es/intlayer_with_i18next.md +0 -45
  20. package/blog/es/intlayer_with_next-i18next.md +0 -47
  21. package/blog/es/intlayer_with_next-intl.md +0 -42
  22. package/blog/es/intlayer_with_react-i18next.md +0 -43
  23. package/blog/es/intlayer_with_react-intl.md +0 -42
  24. package/blog/es/intlayer_with_vue-i18n.md +0 -46
  25. package/blog/fr/intlayer_with_i18next.md +0 -45
  26. package/blog/fr/intlayer_with_next-i18next.md +0 -47
  27. package/blog/fr/intlayer_with_next-intl.md +0 -42
  28. package/blog/fr/intlayer_with_react-i18next.md +0 -43
  29. package/blog/fr/intlayer_with_react-intl.md +0 -42
  30. package/blog/fr/intlayer_with_vue-i18n.md +0 -46
  31. package/blog/hi/intlayer_with_i18next.md +0 -2
  32. package/blog/hi/intlayer_with_next-i18next.md +0 -2
  33. package/blog/hi/intlayer_with_react-i18next.md +0 -2
  34. package/blog/id/intlayer_with_i18next.md +0 -2
  35. package/blog/id/intlayer_with_next-i18next.md +0 -2
  36. package/blog/id/intlayer_with_react-i18next.md +0 -2
  37. package/blog/it/intlayer_with_i18next.md +0 -2
  38. package/blog/it/intlayer_with_next-i18next.md +0 -2
  39. package/blog/it/intlayer_with_react-i18next.md +0 -2
  40. package/blog/ja/intlayer_with_i18next.md +0 -45
  41. package/blog/ja/intlayer_with_next-i18next.md +0 -46
  42. package/blog/ja/intlayer_with_next-intl.md +0 -42
  43. package/blog/ja/intlayer_with_react-i18next.md +0 -42
  44. package/blog/ja/intlayer_with_react-intl.md +0 -42
  45. package/blog/ja/intlayer_with_vue-i18n.md +0 -46
  46. package/blog/ko/intlayer_with_i18next.md +0 -2
  47. package/blog/ko/intlayer_with_next-i18next.md +0 -2
  48. package/blog/ko/intlayer_with_react-i18next.md +0 -1
  49. package/blog/pl/intlayer_with_i18next.md +0 -45
  50. package/blog/pl/intlayer_with_next-i18next.md +0 -46
  51. package/blog/pl/intlayer_with_next-intl.md +0 -42
  52. package/blog/pl/intlayer_with_react-i18next.md +0 -43
  53. package/blog/pl/intlayer_with_react-intl.md +0 -42
  54. package/blog/pl/intlayer_with_vue-i18n.md +0 -46
  55. package/blog/pt/intlayer_with_i18next.md +0 -2
  56. package/blog/pt/intlayer_with_next-i18next.md +0 -2
  57. package/blog/pt/intlayer_with_react-i18next.md +0 -2
  58. package/blog/ru/intlayer_with_i18next.md +0 -45
  59. package/blog/ru/intlayer_with_next-i18next.md +0 -47
  60. package/blog/ru/intlayer_with_next-intl.md +0 -42
  61. package/blog/ru/intlayer_with_react-i18next.md +0 -43
  62. package/blog/ru/intlayer_with_react-intl.md +0 -42
  63. package/blog/ru/intlayer_with_vue-i18n.md +0 -46
  64. package/blog/tr/intlayer_with_i18next.md +0 -2
  65. package/blog/tr/intlayer_with_next-i18next.md +0 -1
  66. package/blog/tr/intlayer_with_react-i18next.md +0 -2
  67. package/blog/uk/compiler_vs_declarative_i18n.md +224 -0
  68. package/blog/uk/i18n_using_next-i18next.md +1086 -0
  69. package/blog/uk/i18n_using_next-intl.md +760 -0
  70. package/blog/uk/index.md +69 -0
  71. package/blog/uk/internationalization_and_SEO.md +273 -0
  72. package/blog/uk/intlayer_with_i18next.md +211 -0
  73. package/blog/uk/intlayer_with_next-i18next.md +202 -0
  74. package/blog/uk/intlayer_with_next-intl.md +203 -0
  75. package/blog/uk/intlayer_with_react-i18next.md +200 -0
  76. package/blog/uk/intlayer_with_react-intl.md +202 -0
  77. package/blog/uk/intlayer_with_vue-i18n.md +206 -0
  78. package/blog/uk/l10n_platform_alternative/Lokalise.md +80 -0
  79. package/blog/uk/l10n_platform_alternative/crowdin.md +80 -0
  80. package/blog/uk/l10n_platform_alternative/phrase.md +78 -0
  81. package/blog/uk/list_i18n_technologies/CMS/drupal.md +143 -0
  82. package/blog/uk/list_i18n_technologies/CMS/wix.md +167 -0
  83. package/blog/uk/list_i18n_technologies/CMS/wordpress.md +189 -0
  84. package/blog/uk/list_i18n_technologies/frameworks/angular.md +125 -0
  85. package/blog/uk/list_i18n_technologies/frameworks/flutter.md +128 -0
  86. package/blog/uk/list_i18n_technologies/frameworks/react-native.md +217 -0
  87. package/blog/uk/list_i18n_technologies/frameworks/react.md +155 -0
  88. package/blog/uk/list_i18n_technologies/frameworks/svelte.md +145 -0
  89. package/blog/uk/list_i18n_technologies/frameworks/vue.md +144 -0
  90. package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +1499 -0
  91. package/blog/uk/nextjs-multilingual-seo-comparison.md +360 -0
  92. package/blog/uk/rag_powered_documentation_assistant.md +288 -0
  93. package/blog/uk/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
  94. package/blog/uk/vue-i18n_vs_intlayer.md +279 -0
  95. package/blog/uk/what_is_internationalization.md +167 -0
  96. package/blog/vi/intlayer_with_i18next.md +0 -2
  97. package/blog/vi/intlayer_with_next-i18next.md +0 -2
  98. package/blog/vi/intlayer_with_react-i18next.md +0 -2
  99. package/blog/zh/intlayer_with_i18next.md +0 -2
  100. package/blog/zh/intlayer_with_next-i18next.md +0 -2
  101. package/blog/zh/intlayer_with_react-i18next.md +0 -2
  102. package/blog/zh/intlayer_with_vue-i18n.md +0 -46
  103. package/dist/cjs/generated/blog.entry.cjs +58 -29
  104. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  105. package/dist/cjs/generated/docs.entry.cjs +218 -99
  106. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  107. package/dist/cjs/generated/frequentQuestions.entry.cjs +50 -15
  108. package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
  109. package/dist/cjs/generated/legal.entry.cjs +4 -2
  110. package/dist/cjs/generated/legal.entry.cjs.map +1 -1
  111. package/dist/esm/generated/blog.entry.mjs +58 -29
  112. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  113. package/dist/esm/generated/docs.entry.mjs +218 -99
  114. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  115. package/dist/esm/generated/frequentQuestions.entry.mjs +50 -15
  116. package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
  117. package/dist/esm/generated/legal.entry.mjs +4 -2
  118. package/dist/esm/generated/legal.entry.mjs.map +1 -1
  119. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  120. package/dist/types/generated/docs.entry.d.ts +1 -0
  121. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  122. package/dist/types/generated/frequentQuestions.entry.d.ts +1 -0
  123. package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
  124. package/dist/types/generated/legal.entry.d.ts.map +1 -1
  125. package/docs/ar/configuration.md +6 -1
  126. package/docs/ar/dictionary/content_file.md +6 -1
  127. package/docs/ar/intlayer_with_next-i18next.md +0 -1
  128. package/docs/ar/intlayer_with_nextjs_14.md +28 -0
  129. package/docs/ar/intlayer_with_nextjs_15.md +28 -0
  130. package/docs/ar/intlayer_with_nextjs_16.md +28 -0
  131. package/docs/ar/intlayer_with_nextjs_no_locale_path.md +1159 -0
  132. package/docs/ar/plugins/sync-json.md +6 -2
  133. package/docs/de/configuration.md +6 -1
  134. package/docs/de/dictionary/content_file.md +6 -1
  135. package/docs/de/intlayer_with_next-i18next.md +0 -1
  136. package/docs/de/intlayer_with_nextjs_14.md +28 -0
  137. package/docs/de/intlayer_with_nextjs_15.md +28 -0
  138. package/docs/de/intlayer_with_nextjs_16.md +28 -0
  139. package/docs/de/intlayer_with_nextjs_no_locale_path.md +1152 -0
  140. package/docs/de/plugins/sync-json.md +6 -2
  141. package/docs/en/configuration.md +6 -1
  142. package/docs/en/dictionary/content_file.md +6 -1
  143. package/docs/en/intlayer_with_next-i18next.md +0 -1
  144. package/docs/en/intlayer_with_nextjs_14.md +28 -0
  145. package/docs/en/intlayer_with_nextjs_15.md +28 -0
  146. package/docs/en/intlayer_with_nextjs_16.md +31 -1
  147. package/docs/en/intlayer_with_nextjs_no_locale_path.md +1132 -0
  148. package/docs/en/plugins/sync-json.md +6 -2
  149. package/docs/en-GB/configuration.md +6 -1
  150. package/docs/en-GB/dictionary/content_file.md +3 -1
  151. package/docs/en-GB/intlayer_with_next-i18next.md +0 -1
  152. package/docs/en-GB/intlayer_with_nextjs_14.md +28 -0
  153. package/docs/en-GB/intlayer_with_nextjs_15.md +28 -0
  154. package/docs/en-GB/intlayer_with_nextjs_16.md +28 -0
  155. package/docs/en-GB/intlayer_with_nextjs_no_locale_path.md +1154 -0
  156. package/docs/en-GB/plugins/sync-json.md +6 -2
  157. package/docs/es/configuration.md +6 -1
  158. package/docs/es/dictionary/content_file.md +6 -1
  159. package/docs/es/intlayer_with_next-i18next.md +0 -1
  160. package/docs/es/intlayer_with_nextjs_14.md +28 -0
  161. package/docs/es/intlayer_with_nextjs_15.md +28 -0
  162. package/docs/es/intlayer_with_nextjs_16.md +28 -0
  163. package/docs/es/intlayer_with_nextjs_no_locale_path.md +1143 -0
  164. package/docs/es/plugins/sync-json.md +6 -2
  165. package/docs/fr/configuration.md +6 -1
  166. package/docs/fr/dictionary/content_file.md +3 -1
  167. package/docs/fr/intlayer_with_next-i18next.md +0 -1
  168. package/docs/fr/intlayer_with_nextjs_14.md +28 -0
  169. package/docs/fr/intlayer_with_nextjs_15.md +28 -0
  170. package/docs/fr/intlayer_with_nextjs_16.md +28 -0
  171. package/docs/fr/intlayer_with_nextjs_no_locale_path.md +1174 -0
  172. package/docs/fr/plugins/sync-json.md +9 -5
  173. package/docs/hi/configuration.md +6 -1
  174. package/docs/hi/dictionary/content_file.md +3 -1
  175. package/docs/hi/intlayer_with_next-i18next.md +0 -1
  176. package/docs/hi/intlayer_with_nextjs_14.md +28 -0
  177. package/docs/hi/intlayer_with_nextjs_15.md +28 -0
  178. package/docs/hi/intlayer_with_nextjs_16.md +28 -0
  179. package/docs/hi/intlayer_with_nextjs_no_locale_path.md +1151 -0
  180. package/docs/hi/plugins/sync-json.md +6 -2
  181. package/docs/id/configuration.md +6 -1
  182. package/docs/id/dictionary/content_file.md +3 -1
  183. package/docs/id/intlayer_with_next-i18next.md +0 -1
  184. package/docs/id/intlayer_with_nextjs_14.md +28 -0
  185. package/docs/id/intlayer_with_nextjs_15.md +28 -0
  186. package/docs/id/intlayer_with_nextjs_16.md +28 -0
  187. package/docs/id/intlayer_with_nextjs_no_locale_path.md +1154 -0
  188. package/docs/id/plugins/sync-json.md +6 -2
  189. package/docs/it/configuration.md +6 -1
  190. package/docs/it/dictionary/content_file.md +3 -1
  191. package/docs/it/intlayer_with_next-i18next.md +0 -1
  192. package/docs/it/intlayer_with_nextjs_14.md +28 -0
  193. package/docs/it/intlayer_with_nextjs_15.md +28 -0
  194. package/docs/it/intlayer_with_nextjs_16.md +28 -0
  195. package/docs/it/intlayer_with_nextjs_no_locale_path.md +1148 -0
  196. package/docs/it/plugins/sync-json.md +6 -2
  197. package/docs/ja/configuration.md +6 -1
  198. package/docs/ja/dictionary/content_file.md +3 -1
  199. package/docs/ja/intlayer_with_next-i18next.md +0 -1
  200. package/docs/ja/intlayer_with_nextjs_14.md +28 -0
  201. package/docs/ja/intlayer_with_nextjs_15.md +28 -0
  202. package/docs/ja/intlayer_with_nextjs_16.md +28 -0
  203. package/docs/ja/intlayer_with_nextjs_no_locale_path.md +1222 -0
  204. package/docs/ja/plugins/sync-json.md +6 -2
  205. package/docs/ko/configuration.md +6 -1
  206. package/docs/ko/dictionary/content_file.md +3 -1
  207. package/docs/ko/intlayer_with_next-i18next.md +0 -1
  208. package/docs/ko/intlayer_with_nextjs_14.md +28 -0
  209. package/docs/ko/intlayer_with_nextjs_15.md +28 -0
  210. package/docs/ko/intlayer_with_nextjs_16.md +28 -0
  211. package/docs/ko/intlayer_with_nextjs_no_locale_path.md +1205 -0
  212. package/docs/ko/plugins/sync-json.md +6 -2
  213. package/docs/pl/configuration.md +3 -1
  214. package/docs/pl/dictionary/content_file.md +3 -1
  215. package/docs/pl/intlayer_with_next-i18next.md +0 -1
  216. package/docs/pl/intlayer_with_nextjs_14.md +28 -0
  217. package/docs/pl/intlayer_with_nextjs_15.md +28 -0
  218. package/docs/pl/intlayer_with_nextjs_16.md +28 -0
  219. package/docs/pl/intlayer_with_nextjs_no_locale_path.md +1149 -0
  220. package/docs/pl/plugins/sync-json.md +6 -2
  221. package/docs/pt/configuration.md +6 -1
  222. package/docs/pt/dictionary/content_file.md +3 -1
  223. package/docs/pt/intlayer_with_next-i18next.md +0 -1
  224. package/docs/pt/intlayer_with_nextjs_14.md +28 -0
  225. package/docs/pt/intlayer_with_nextjs_15.md +28 -0
  226. package/docs/pt/intlayer_with_nextjs_16.md +28 -0
  227. package/docs/pt/intlayer_with_nextjs_no_locale_path.md +1152 -0
  228. package/docs/pt/plugins/sync-json.md +6 -2
  229. package/docs/ru/configuration.md +6 -1
  230. package/docs/ru/dictionary/content_file.md +6 -1
  231. package/docs/ru/intlayer_with_next-i18next.md +0 -1
  232. package/docs/ru/intlayer_with_nextjs_14.md +28 -0
  233. package/docs/ru/intlayer_with_nextjs_15.md +28 -0
  234. package/docs/ru/intlayer_with_nextjs_16.md +28 -0
  235. package/docs/ru/intlayer_with_nextjs_no_locale_path.md +1204 -0
  236. package/docs/ru/plugins/sync-json.md +6 -2
  237. package/docs/tr/configuration.md +6 -1
  238. package/docs/tr/dictionary/content_file.md +3 -1
  239. package/docs/tr/intlayer_with_next-i18next.md +0 -1
  240. package/docs/tr/intlayer_with_nextjs_14.md +28 -0
  241. package/docs/tr/intlayer_with_nextjs_15.md +28 -0
  242. package/docs/tr/intlayer_with_nextjs_16.md +28 -0
  243. package/docs/tr/intlayer_with_nextjs_no_locale_path.md +1159 -0
  244. package/docs/tr/plugins/sync-json.md +6 -2
  245. package/docs/uk/CI_CD.md +198 -0
  246. package/docs/uk/autoFill.md +307 -0
  247. package/docs/uk/bundle_optimization.md +185 -0
  248. package/docs/uk/cli/build.md +64 -0
  249. package/docs/uk/cli/ci.md +137 -0
  250. package/docs/uk/cli/configuration.md +63 -0
  251. package/docs/uk/cli/debug.md +46 -0
  252. package/docs/uk/cli/doc-review.md +43 -0
  253. package/docs/uk/cli/doc-translate.md +132 -0
  254. package/docs/uk/cli/editor.md +28 -0
  255. package/docs/uk/cli/fill.md +130 -0
  256. package/docs/uk/cli/index.md +190 -0
  257. package/docs/uk/cli/init.md +84 -0
  258. package/docs/uk/cli/list.md +90 -0
  259. package/docs/uk/cli/list_projects.md +128 -0
  260. package/docs/uk/cli/live.md +41 -0
  261. package/docs/uk/cli/login.md +157 -0
  262. package/docs/uk/cli/pull.md +78 -0
  263. package/docs/uk/cli/push.md +98 -0
  264. package/docs/uk/cli/sdk.md +71 -0
  265. package/docs/uk/cli/test.md +76 -0
  266. package/docs/uk/cli/transform.md +65 -0
  267. package/docs/uk/cli/version.md +24 -0
  268. package/docs/uk/cli/watch.md +37 -0
  269. package/docs/uk/compiler.md +133 -0
  270. package/docs/uk/component_i18n.md +194 -0
  271. package/docs/uk/configuration.md +742 -0
  272. package/docs/uk/dictionary/condition.md +237 -0
  273. package/docs/uk/dictionary/content_file.md +1134 -0
  274. package/docs/uk/dictionary/enumeration.md +245 -0
  275. package/docs/uk/dictionary/file.md +232 -0
  276. package/docs/uk/dictionary/function_fetching.md +212 -0
  277. package/docs/uk/dictionary/gender.md +273 -0
  278. package/docs/uk/dictionary/insertion.md +187 -0
  279. package/docs/uk/dictionary/markdown.md +383 -0
  280. package/docs/uk/dictionary/nesting.md +273 -0
  281. package/docs/uk/dictionary/translation.md +332 -0
  282. package/docs/uk/formatters.md +595 -0
  283. package/docs/uk/how_works_intlayer.md +256 -0
  284. package/docs/uk/index.md +175 -0
  285. package/docs/uk/interest_of_intlayer.md +297 -0
  286. package/docs/uk/intlayer_CMS.md +569 -0
  287. package/docs/uk/intlayer_visual_editor.md +292 -0
  288. package/docs/uk/intlayer_with_angular.md +710 -0
  289. package/docs/uk/intlayer_with_astro.md +256 -0
  290. package/docs/uk/intlayer_with_create_react_app.md +1258 -0
  291. package/docs/uk/intlayer_with_express.md +429 -0
  292. package/docs/uk/intlayer_with_fastify.md +446 -0
  293. package/docs/uk/intlayer_with_lynx+react.md +548 -0
  294. package/docs/uk/intlayer_with_nestjs.md +283 -0
  295. package/docs/uk/intlayer_with_next-i18next.md +640 -0
  296. package/docs/uk/intlayer_with_next-intl.md +456 -0
  297. package/docs/uk/intlayer_with_nextjs_14.md +1646 -0
  298. package/docs/uk/intlayer_with_nextjs_15.md +1910 -0
  299. package/docs/uk/intlayer_with_nextjs_16.md +1763 -0
  300. package/docs/uk/intlayer_with_nextjs_no_locale_path.md +1159 -0
  301. package/docs/uk/intlayer_with_nextjs_page_router.md +1541 -0
  302. package/docs/uk/intlayer_with_nuxt.md +711 -0
  303. package/docs/uk/intlayer_with_react_native+expo.md +715 -0
  304. package/docs/uk/intlayer_with_react_router_v7.md +600 -0
  305. package/docs/uk/intlayer_with_react_router_v7_fs_routes.md +669 -0
  306. package/docs/uk/intlayer_with_svelte_kit.md +579 -0
  307. package/docs/uk/intlayer_with_tanstack.md +818 -0
  308. package/docs/uk/intlayer_with_vite+preact.md +1748 -0
  309. package/docs/uk/intlayer_with_vite+react.md +1449 -0
  310. package/docs/uk/intlayer_with_vite+solid.md +302 -0
  311. package/docs/uk/intlayer_with_vite+svelte.md +520 -0
  312. package/docs/uk/intlayer_with_vite+vue.md +1113 -0
  313. package/docs/uk/introduction.md +222 -0
  314. package/docs/uk/locale_mapper.md +242 -0
  315. package/docs/uk/mcp_server.md +211 -0
  316. package/docs/uk/packages/express-intlayer/t.md +465 -0
  317. package/docs/uk/packages/intlayer/getConfiguration.md +145 -0
  318. package/docs/uk/packages/intlayer/getEnumeration.md +159 -0
  319. package/docs/uk/packages/intlayer/getHTMLTextDir.md +121 -0
  320. package/docs/uk/packages/intlayer/getLocaleLang.md +81 -0
  321. package/docs/uk/packages/intlayer/getLocaleName.md +135 -0
  322. package/docs/uk/packages/intlayer/getLocalizedUrl.md +338 -0
  323. package/docs/uk/packages/intlayer/getMultilingualUrls.md +359 -0
  324. package/docs/uk/packages/intlayer/getPathWithoutLocale.md +75 -0
  325. package/docs/uk/packages/intlayer/getPrefix.md +213 -0
  326. package/docs/uk/packages/intlayer/getTranslation.md +190 -0
  327. package/docs/uk/packages/intlayer/getTranslationContent.md +189 -0
  328. package/docs/uk/packages/next-intlayer/t.md +365 -0
  329. package/docs/uk/packages/next-intlayer/useDictionary.md +276 -0
  330. package/docs/uk/packages/next-intlayer/useIntlayer.md +263 -0
  331. package/docs/uk/packages/next-intlayer/useLocale.md +166 -0
  332. package/docs/uk/packages/react-intlayer/t.md +311 -0
  333. package/docs/uk/packages/react-intlayer/useDictionary.md +295 -0
  334. package/docs/uk/packages/react-intlayer/useI18n.md +250 -0
  335. package/docs/uk/packages/react-intlayer/useIntlayer.md +251 -0
  336. package/docs/uk/packages/react-intlayer/useLocale.md +210 -0
  337. package/docs/uk/per_locale_file.md +345 -0
  338. package/docs/uk/plugins/sync-json.md +398 -0
  339. package/docs/uk/readme.md +265 -0
  340. package/docs/uk/releases/v6.md +305 -0
  341. package/docs/uk/releases/v7.md +624 -0
  342. package/docs/uk/roadmap.md +346 -0
  343. package/docs/uk/testing.md +204 -0
  344. package/docs/uk/vs_code_extension.md +133 -0
  345. package/docs/vi/configuration.md +6 -1
  346. package/docs/vi/dictionary/content_file.md +6 -1
  347. package/docs/vi/intlayer_with_next-i18next.md +0 -1
  348. package/docs/vi/intlayer_with_nextjs_14.md +28 -0
  349. package/docs/vi/intlayer_with_nextjs_15.md +28 -0
  350. package/docs/vi/intlayer_with_nextjs_16.md +28 -0
  351. package/docs/vi/intlayer_with_nextjs_no_locale_path.md +1151 -0
  352. package/docs/vi/plugins/sync-json.md +6 -2
  353. package/docs/zh/configuration.md +6 -1
  354. package/docs/zh/dictionary/content_file.md +6 -1
  355. package/docs/zh/intlayer_with_next-i18next.md +0 -1
  356. package/docs/zh/intlayer_with_nextjs_14.md +28 -0
  357. package/docs/zh/intlayer_with_nextjs_15.md +28 -0
  358. package/docs/zh/intlayer_with_nextjs_16.md +28 -0
  359. package/docs/zh/intlayer_with_nextjs_no_locale_path.md +1206 -0
  360. package/docs/zh/plugins/sync-json.md +9 -5
  361. package/frequent_questions/ar/SSR_Next_no_[locale].md +1 -1
  362. package/frequent_questions/ar/error-vite-env-only.md +77 -0
  363. package/frequent_questions/de/SSR_Next_no_[locale].md +1 -1
  364. package/frequent_questions/de/error-vite-env-only.md +77 -0
  365. package/frequent_questions/en/SSR_Next_no_[locale].md +1 -1
  366. package/frequent_questions/en/error-vite-env-only.md +77 -0
  367. package/frequent_questions/en-GB/SSR_Next_no_[locale].md +1 -1
  368. package/frequent_questions/en-GB/error-vite-env-only.md +77 -0
  369. package/frequent_questions/es/SSR_Next_no_[locale].md +1 -1
  370. package/frequent_questions/es/error-vite-env-only.md +76 -0
  371. package/frequent_questions/fr/SSR_Next_no_[locale].md +1 -1
  372. package/frequent_questions/fr/error-vite-env-only.md +77 -0
  373. package/frequent_questions/hi/SSR_Next_no_[locale].md +1 -1
  374. package/frequent_questions/hi/error-vite-env-only.md +77 -0
  375. package/frequent_questions/id/SSR_Next_no_[locale].md +1 -1
  376. package/frequent_questions/id/error-vite-env-only.md +77 -0
  377. package/frequent_questions/it/SSR_Next_no_[locale].md +1 -1
  378. package/frequent_questions/it/error-vite-env-only.md +77 -0
  379. package/frequent_questions/ja/SSR_Next_no_[locale].md +1 -1
  380. package/frequent_questions/ja/error-vite-env-only.md +77 -0
  381. package/frequent_questions/ko/SSR_Next_no_[locale].md +1 -1
  382. package/frequent_questions/ko/error-vite-env-only.md +77 -0
  383. package/frequent_questions/pl/SSR_Next_no_[locale].md +1 -1
  384. package/frequent_questions/pl/error-vite-env-only.md +77 -0
  385. package/frequent_questions/pt/SSR_Next_no_[locale].md +1 -1
  386. package/frequent_questions/pt/error-vite-env-only.md +77 -0
  387. package/frequent_questions/ru/SSR_Next_no_[locale].md +1 -1
  388. package/frequent_questions/ru/error-vite-env-only.md +77 -0
  389. package/frequent_questions/tr/SSR_Next_no_[locale].md +1 -1
  390. package/frequent_questions/tr/error-vite-env-only.md +77 -0
  391. package/frequent_questions/uk/SSR_Next_no_[locale].md +104 -0
  392. package/frequent_questions/uk/array_as_content_declaration.md +72 -0
  393. package/frequent_questions/uk/build_dictionaries.md +58 -0
  394. package/frequent_questions/uk/build_error_CI_CD.md +74 -0
  395. package/frequent_questions/uk/bun_set_up.md +53 -0
  396. package/frequent_questions/uk/customized_locale_list.md +64 -0
  397. package/frequent_questions/uk/domain_routing.md +113 -0
  398. package/frequent_questions/uk/error-vite-env-only.md +77 -0
  399. package/frequent_questions/uk/esbuild_error.md +29 -0
  400. package/frequent_questions/uk/get_locale_cookie.md +142 -0
  401. package/frequent_questions/uk/intlayer_command_undefined.md +155 -0
  402. package/frequent_questions/uk/locale_incorect_in_url.md +73 -0
  403. package/frequent_questions/uk/package_version_error.md +181 -0
  404. package/frequent_questions/uk/static_rendering.md +44 -0
  405. package/frequent_questions/uk/translated_path_url.md +55 -0
  406. package/frequent_questions/uk/unknown_command.md +97 -0
  407. package/frequent_questions/vi/SSR_Next_no_[locale].md +1 -1
  408. package/frequent_questions/vi/error-vite-env-only.md +77 -0
  409. package/frequent_questions/zh/SSR_Next_no_[locale].md +1 -1
  410. package/frequent_questions/zh/error-vite-env-only.md +77 -0
  411. package/legal/uk/privacy_notice.md +83 -0
  412. package/legal/uk/terms_of_service.md +55 -0
  413. package/package.json +6 -6
  414. package/src/generated/blog.entry.ts +29 -0
  415. package/src/generated/docs.entry.ts +119 -0
  416. package/src/generated/frequentQuestions.entry.ts +35 -0
  417. package/src/generated/legal.entry.ts +2 -0
@@ -0,0 +1,1206 @@
1
+ ---
2
+ createdAt: 2026-01-10
3
+ updatedAt: 2026-01-10
4
+ title: 如何翻译你的 Next.js 16 应用(页面路径中不包含 [locale]) – i18n 指南 2026
5
+ description: 了解如何在页面路径中不包含 [locale] 的情况下,让你的 Next.js 16 网站支持多语言。按照文档进行国际化 (i18n) 并进行翻译。
6
+ keywords:
7
+ - 国际化
8
+ - 文档
9
+ - Intlayer
10
+ - Next.js 16
11
+ - JavaScript
12
+ - React
13
+ slugs:
14
+ - doc
15
+ - environment
16
+ - nextjs
17
+ - no-locale-path
18
+ applicationTemplate: https://github.com/aymericzip/intlayer-next-no-lolale-path-template
19
+ youtubeVideo: https://www.youtube.com/watch?v=e_PPG7PTqGU
20
+ history:
21
+ - version: 1.0.0
22
+ date: 2026-01-10
23
+ changes: 初始发布
24
+ ---
25
+
26
+ # 使用 Intlayer 翻译你的 Next.js 16 网站(页面路径中不包含 [locale]) | 国际化 (i18n)
27
+
28
+ <Tab defaultTab="video">
29
+ <TabItem label="视频" value="video">
30
+
31
+ <iframe title="适用于 Next.js 的最佳 i18n 解决方案?探索 Intlayer" class="m-auto aspect-16/9 w-full overflow-hidden rounded-lg border-0" allow="autoplay; gyroscope;" loading="lazy" width="1080" height="auto" src="https://www.youtube.com/embed/e_PPG7PTqGU?autoplay=0&amp;origin=http://intlayer.org&amp;controls=0&amp;rel=1"/>
32
+
33
+ </TabItem>
34
+ <TabItem label="代码" value="code">
35
+
36
+ <iframe
37
+ src="https://stackblitz.com/github/aymericzip/intlayer-next-16-no-locale-path-template?embed=1&ctl=1&file=intlayer.config.ts"
38
+ className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
39
+ title="演示 CodeSandbox - 使用 Intlayer 国际化您的应用"
40
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
41
+ loading="lazy"
42
+ />
43
+
44
+ </TabItem>
45
+ </Tab>
46
+
47
+ 查看 GitHub 上的 [应用模板](https://github.com/aymericzip/intlayer-next-no-lolale-path-template)。
48
+
49
+ ## 目录
50
+
51
+ <TOC/>
52
+
53
+ ## 什么是 Intlayer?
54
+
55
+ **Intlayer** 是一个创新的开源国际化(i18n)库,旨在简化现代 Web 应用的多语言支持。Intlayer 与最新的 **Next.js 16** 框架无缝集成,包括其强大的 **App Router**。它针对 **Server Components** 进行了优化以实现高效渲染,并且与 [**Turbopack**](https://nextjs.org/docs/architecture/turbopack) 完全兼容。
56
+
57
+ 使用 Intlayer,您可以:
58
+
59
+ - **通过组件级的声明式字典,轻松管理翻译。**
60
+ - **动态本地化元数据**、路由和内容。
61
+ - **在客户端和服务器端组件中都能访问翻译。**
62
+ - **通过自动生成的类型确保 TypeScript 支持**,提升自动补全和错误检测。
63
+ - **利用高级功能**,如动态语言检测和切换。
64
+
65
+ > Intlayer 与 Next.js 12、13、14 和 16 兼容。如果您使用 Next.js Page Router,可参考此 [指南](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_with_nextjs_page_router.md)。对于使用 App Router 的 Next.js 12、13、14,请参考此 [指南](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_with_nextjs_14.md)。
66
+
67
+ ---
68
+
69
+ ## 在 Next.js 应用中设置 Intlayer 的逐步指南
70
+
71
+ ### 第一步:安装依赖
72
+
73
+ 使用 npm 安装所需的包:
74
+
75
+ ```bash packageManager="npm"
76
+ npm install intlayer next-intlayer
77
+ npx intlayer init
78
+ ```
79
+
80
+ ```bash packageManager="pnpm"
81
+ pnpm add intlayer next-intlayer
82
+ pnpm intlayer init
83
+ ```
84
+
85
+ ```bash packageManager="yarn"
86
+ yarn add intlayer next-intlayer
87
+ yarn intlayer init
88
+ ```
89
+
90
+ ```bash packageManager="bun"
91
+ bun add intlayer next-intlayer
92
+ bunx intlayer init
93
+ ```
94
+
95
+ - **intlayer**
96
+
97
+ 核心包,提供用于配置管理、翻译、[内容声明](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) 的国际化工具。
98
+
99
+ - **next-intlayer**
100
+
101
+ 将 Intlayer 与 Next.js 集成的包。它为 Next.js 的国际化提供了 context providers(上下文提供者)和 hooks(钩子)。此外,它还包含用于将 Intlayer 集成到 Webpack 或 Turbopack 的 Next.js 插件,以及用于检测用户首选 locale、管理 cookies 和处理 URL 重定向的 proxy。
102
+
103
+ ### 步骤 2:配置您的项目
104
+
105
+ 下面是我们将创建的最终结构:
106
+
107
+ ```bash
108
+ .
109
+ ├── src
110
+ │ ├── app
111
+ │ │ ├── layout.tsx
112
+ │ │ ├── page.content.ts
113
+ │ │ └── page.tsx
114
+ │ ├── components
115
+ │ │ ├── clientComponentExample
116
+ │ │ │ ├── client-component-example.content.ts
117
+ │ │ │ └── ClientComponentExample.tsx
118
+ │ │ ├── localeSwitcher
119
+ │ │ │ ├── localeSwitcher.content.ts
120
+ │ │ │ └── LocaleSwitcher.tsx
121
+ │ │ └── serverComponentExample
122
+ │ │ ├── server-component-example.content.ts
123
+ │ │ └── ServerComponentExample.tsx
124
+ │ └── proxy.ts
125
+ ├── intlayer.config.ts
126
+ ├── next.config.ts
127
+ ├── package.json
128
+ └── tsconfig.json
129
+ ```
130
+
131
+ > 如果你不想使用区域路由,intlayer 可以作为一个简单的 provider / hook 来使用。更多细节参见 [本指南](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/intlayer_with_nextjs_no_locale_path.md)。
132
+
133
+ 创建一个配置文件来配置应用的语言:
134
+
135
+ ```typescript fileName="intlayer.config.ts" codeFormat="typescript"
136
+ import { Locales, type IntlayerConfig } from "intlayer";
137
+
138
+ const config: IntlayerConfig = {
139
+ internationalization: {
140
+ locales: [
141
+ Locales.ENGLISH,
142
+ Locales.FRENCH,
143
+ Locales.SPANISH,
144
+ // 你的其他语言
145
+ ],
146
+ defaultLocale: Locales.ENGLISH,
147
+ },
148
+ routing: {
149
+ mode: "search-params", // 或 `no-prefix` - 对中间件检测有用
150
+ },
151
+ };
152
+
153
+ export default config;
154
+ ```
155
+
156
+ ```javascript fileName="intlayer.config.mjs" codeFormat="esm"
157
+ import { Locales } from "intlayer";
158
+
159
+ /** @type {import('intlayer').IntlayerConfig} */
160
+ const config = {
161
+ internationalization: {
162
+ locales: [
163
+ Locales.ENGLISH,
164
+ Locales.FRENCH,
165
+ Locales.SPANISH,
166
+ // 你的其他语言
167
+ ],
168
+ defaultLocale: Locales.ENGLISH,
169
+ },
170
+ routing: {
171
+ mode: "search-params", // 或 `no-prefix` - 对中间件检测有用
172
+ },
173
+ };
174
+
175
+ export default config;
176
+ ```
177
+
178
+ ```javascript fileName="intlayer.config.cjs" codeFormat="commonjs"
179
+ const { Locales } = require("intlayer");
180
+
181
+ /** @type {import('intlayer').IntlayerConfig} */
182
+ const config = {
183
+ internationalization: {
184
+ locales: [
185
+ Locales.ENGLISH,
186
+ Locales.FRENCH,
187
+ Locales.SPANISH,
188
+ // 你的其他 locales
189
+ ],
190
+ defaultLocale: Locales.ENGLISH,
191
+ },
192
+ routing: {
193
+ mode: "search-params", // 或 `no-prefix` - 对中间件检测有用
194
+ },
195
+ };
196
+
197
+ module.exports = config;
198
+ ```
199
+
200
+ > 通过此配置文件,您可以设置本地化 URL、代理重定向、cookie 名称、内容声明的位置和扩展名、在控制台禁用 Intlayer 日志等。有关可用参数的完整列表,请参阅[配置文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md)。
201
+
202
+ ### 第 3 步:在 Next.js 配置中集成 Intlayer
203
+
204
+ 配置您的 Next.js 设置以使用 Intlayer:
205
+
206
+ ```typescript fileName="next.config.ts" codeFormat="typescript"
207
+ import type { NextConfig } from "next";
208
+ import { withIntlayer } from "next-intlayer/server";
209
+
210
+ const nextConfig: NextConfig = {
211
+ /* 在此处填写配置选项 */
212
+ };
213
+
214
+ export default withIntlayer(nextConfig);
215
+ ```
216
+
217
+ ```typescript fileName="next.config.mjs" codeFormat="esm"
218
+ import { withIntlayer } from "next-intlayer/server";
219
+
220
+ /** @type {import('next').NextConfig} */
221
+ const nextConfig = {
222
+ /* 在此处添加配置选项 */
223
+ };
224
+
225
+ export default withIntlayer(nextConfig);
226
+ ```
227
+
228
+ ```typescript fileName="next.config.cjs" codeFormat="commonjs"
229
+ const { withIntlayer } = require("next-intlayer/server");
230
+
231
+ /** @type {import('next').NextConfig} */
232
+ const nextConfig = {
233
+ /* 在此处添加配置选项 */
234
+ };
235
+
236
+ module.exports = withIntlayer(nextConfig);
237
+ ```
238
+
239
+ > `withIntlayer()` Next.js 插件用于将 Intlayer 集成到 Next.js 中。它负责构建内容声明文件,并在开发模式下监视这些文件。它会在 [Webpack](https://webpack.js.org/) 或 [Turbopack](https://nextjs.org/docs/app/api-reference/turbopack) 环境中定义 Intlayer 的环境变量。此外,它还提供别名以优化性能,并确保与 server components 的兼容性。
240
+
241
+ > `withIntlayer()` 函数是一个返回 Promise 的函数。它允许在构建开始前准备 intlayer 字典。如果你想与其他插件一起使用它,可以对其使用 await。示例:
242
+ >
243
+ > ```ts
244
+ > const nextConfig = await withIntlayer(nextConfig);
245
+ > const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
246
+ >
247
+ > export default nextConfigWithOtherPlugins;
248
+ > ```
249
+ >
250
+ > 如果你想以同步方式使用它,可以使用 `withIntlayerSync()` 函数。示例:
251
+ >
252
+ > ```ts
253
+ > const nextConfig = withIntlayerSync(nextConfig);
254
+ > const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
255
+ >
256
+ > export default nextConfigWithOtherPlugins;
257
+ > ```
258
+ >
259
+ > Intlayer 会根据命令行标志 `--webpack`、`--turbo` 或 `--turbopack` 以及你当前的 **Next.js** 版本自动检测项目是使用 **webpack** 还是 **Turbopack**。
260
+ >
261
+ > 自 `next>=16` 起,如果你使用 **Rspack**,必须通过禁用 Turbopack 明确强制 Intlayer 使用 webpack 配置:
262
+ >
263
+ > ```ts
264
+ > withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
265
+ > ```
266
+
267
+ ### 第4步:定义动态 locale 路由
268
+
269
+ 从 `RootLayout` 中删除所有内容,并用下面的代码替换:
270
+
271
+ ```tsx {3} fileName="src/app/layout.tsx" codeFormat="typescript"
272
+ import type { Metadata } from "next";
273
+ import type { ReactNode } from "react";
274
+ import "./globals.css";
275
+ import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";
276
+ import { getHTMLTextDir, getIntlayer } from "intlayer";
277
+ import { getLocale } from "next-intlayer/server";
278
+ export { generateStaticParams } from "next-intlayer";
279
+
280
+ export const generateMetadata = async ({
281
+ params,
282
+ }: LocalPromiseParams): Promise<Metadata> => {
283
+ const { locale } = await params;
284
+ const { title, description, keywords } = getIntlayer("metadata", locale);
285
+
286
+ return {
287
+ title,
288
+ description,
289
+ keywords,
290
+ };
291
+ };
292
+
293
+ const RootLayout = async ({
294
+ children,
295
+ }: Readonly<{
296
+ children: ReactNode;
297
+ }>) => {
298
+ const locale = await getLocale();
299
+
300
+ return (
301
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
302
+ <IntlayerClientProvider defaultLocale={locale}>
303
+ <body>{children}</body>
304
+ </IntlayerClientProvider>
305
+ </html>
306
+ );
307
+ };
308
+
309
+ export default RootLayout;
310
+ ```
311
+
312
+ ```jsx {3} fileName="src/app/layout.mjx" codeFormat="esm"
313
+ import "./globals.css";
314
+ import { IntlayerClientProvider } from "next-intlayer";
315
+ import { getHTMLTextDir, getIntlayer } from "intlayer";
316
+ import { getLocale } from "next-intlayer/server";
317
+ import { headers, cookies } from "next/headers";
318
+ export { generateStaticParams } from "next/intlayer";
319
+
320
+ export const generateMetadata = async ({ params }) => {
321
+ const { locale } = await params;
322
+ const { title, description, keywords } = getIntlayer("metadata", locale);
323
+
324
+ return {
325
+ title,
326
+ description,
327
+ keywords,
328
+ };
329
+ };
330
+
331
+ const RootLayout = async ({ children }) => {
332
+ // 在 Next.js 15+ 中等待 headers 和 cookies
333
+ const headerList = await headers();
334
+ const cookieList = await cookies();
335
+
336
+ const locale = await getLocale({
337
+ // 首先检查 intlayer cookie(默认: 'INTLAYER_LOCALE')
338
+ getCookie: (name) => cookieList.get(name)?.value,
339
+
340
+ // 然后检查 intlayer header(默认: 'x-intlayer-locale')
341
+ // 最后检查 accept-language 请求头('accept-language')
342
+ getHeader: (name) => headerList.get(name),
343
+ });
344
+
345
+ return (
346
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
347
+ <IntlayerClientProvider defaultLocale={locale}>
348
+ <body>{children}</body>
349
+ </IntlayerClientProvider>
350
+ </html>
351
+ );
352
+ };
353
+
354
+ export default RootLayout;
355
+ ```
356
+
357
+ ```jsx {1,8} fileName="src/app/layout.csx" codeFormat="commonjs"
358
+ require("./globals.css");
359
+ const { IntlayerClientProvider } = require("next-intlayer");
360
+ const { getHTMLTextDir, getIntlayer } = require("intlayer");
361
+ const { getLocale } = require("next-intlayer/server");
362
+ const { headers, cookies } = require("next/headers");
363
+ const { generateStaticParams } = require("next-intlayer");
364
+
365
+ const generateMetadata = async ({ params }) => {
366
+ const { locale } = await params;
367
+ const { title, description, keywords } = getIntlayer("metadata", locale);
368
+
369
+ return {
370
+ title,
371
+ description,
372
+ keywords,
373
+ };
374
+ };
375
+
376
+ const RootLayout = async ({ children }) => {
377
+ // 在 Next.js 15+ 中等待 headers 和 cookies
378
+ const headerList = await headers();
379
+ const cookieList = await cookies();
380
+
381
+ const locale = await getLocale({
382
+ // 首先检查 intlayer cookie(默认: 'INTLAYER_LOCALE')
383
+ getCookie: (name) => cookieList.get(name)?.value,
384
+
385
+ // 然后检查 intlayer header(默认: 'x-intlayer-locale')
386
+ // 最后检查 accept-language header('accept-language')
387
+ getHeader: (name) => headerList.get(name),
388
+ });
389
+
390
+ return (
391
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
392
+ <IntlayerClientProvider defaultLocale={locale}>
393
+ <body>{children}</body>
394
+ </IntlayerClientProvider>
395
+ </html>
396
+ );
397
+ };
398
+
399
+ module.exports = {
400
+ default: RootLayout,
401
+ generateStaticParams,
402
+ generateMetadata,
403
+ };
404
+ ```
405
+
406
+ ### 步骤 5:声明您的内容
407
+
408
+ 创建并管理您的内容声明以存储翻译:
409
+
410
+ ```tsx fileName="src/app/metadata.content.ts" contentDeclarationFormat="typescript"
411
+ import { t, type Dictionary } from "intlayer";
412
+ import { Metadata } from "next";
413
+
414
+ const metadataContent = {
415
+ key: "metadata",
416
+ content: {
417
+ title: t({
418
+ zh: "我的项目标题",
419
+ en: "My Project Title",
420
+ fr: "Le Titre de mon Projet",
421
+ es: "El Título de mi Proyecto",
422
+ }),
423
+
424
+ description: t({
425
+ zh: "了解我们创新的平台,旨在简化您的工作流程并提高生产力。",
426
+ en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",
427
+ zh: "探索我们的创新平台,旨在简化您的工作流程并提升生产力。",
428
+ fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
429
+ es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",
430
+ }),
431
+
432
+ keywords: t({
433
+ zh: ["创新", "生产力", "工作流程", "SaaS"],
434
+ en: ["innovation", "productivity", "workflow", "SaaS"],
435
+ fr: ["innovation", "productivité", "flux de travail", "SaaS"],
436
+ es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],
437
+ }),
438
+ },
439
+ } as Dictionary<Metadata>;
440
+
441
+ export default metadataContent;
442
+ ```
443
+
444
+ ```tsx fileName="src/app/metadata.content.mjs" contentDeclarationFormat="typescript"
445
+ import { t, type Dictionary } from "intlayer";
446
+
447
+ /** @type {import('intlayer').Dictionary<import('next').Metadata>} */
448
+ const metadataContent = {
449
+ key: "metadata",
450
+ content: {
451
+ title: t({
452
+ zh: "我的项目标题",
453
+ en: "My Project Title",
454
+ fr: "Le Titre de mon Projet",
455
+ es: "El Título de mi Proyecto",
456
+ }),
457
+
458
+ description: t({
459
+ zh: "探索我们创新的平台,旨在简化您的工作流程并提高生产力。",
460
+ en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",
461
+ fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
462
+ es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",
463
+ }),
464
+
465
+ keywords: t({
466
+ zh: ["创新", "生产力", "工作流程", "SaaS"],
467
+ en: ["innovation", "productivity", "workflow", "SaaS"],
468
+ fr: ["innovation", "productivité", "flux de travail", "SaaS"],
469
+ es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],
470
+ }),
471
+ },
472
+ };
473
+
474
+ export default metadataContent;
475
+ ```
476
+
477
+ ```javascript fileName="src/app/metadata.content.cjs" contentDeclarationFormat="commonjs"
478
+ const { t } = require("intlayer");
479
+
480
+ /** @type {import('intlayer').Dictionary<import('next').Metadata>} */
481
+ const metadataContent = {
482
+ key: "metadata",
483
+ content: {
484
+ title: t({
485
+ zh: "我的项目标题",
486
+ en: "My Project Title",
487
+ fr: "Le Titre de mon Projet",
488
+ es: "El Título de mi Proyecto",
489
+ }),
490
+
491
+ description: t({
492
+ zh: "了解我们的创新平台,旨在简化您的工作流程并提升生产力。",
493
+ en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",
494
+ fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
495
+ es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",
496
+ }),
497
+
498
+ keywords: t({
499
+ zh: ["创新", "生产力", "工作流", "SaaS"],
500
+ en: ["innovation", "productivity", "workflow", "SaaS"],
501
+ fr: ["innovation", "productivité", "flux de travail", "SaaS"],
502
+ es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],
503
+ }),
504
+ },
505
+ };
506
+
507
+ module.exports = metadataContent;
508
+ ```
509
+
510
+ ```json fileName="src/app/metadata.content.json" contentDeclarationFormat="json"
511
+ {
512
+ "key": "metadata",
513
+ "content": {
514
+ "title": {
515
+ "nodeType": "translation",
516
+ "translation": {
517
+ "zh": "我的项目标题",
518
+ "en": "My Project Title",
519
+ "fr": "Le Titre de mon Projet",
520
+ "es": "El Título de mi Proyecto"
521
+ }
522
+ },
523
+ "description": {
524
+ "nodeType": "translation",
525
+ "translation": {
526
+ "zh": "探索我们创新的平台,旨在简化您的工作流程并提升生产力。",
527
+ "en": "Discover our innovative platform designed to streamline your workflow and boost productivity.",
528
+ "zh": "探索我们的创新平台,旨在简化您的工作流程并提升您的生产力。",
529
+ "fr": "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",
530
+ "es": "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad."
531
+ }
532
+ },
533
+ "keywords": {
534
+ "nodeType": "translation",
535
+ "translation": {
536
+ "zh": ["创新", "生产力", "工作流程", "SaaS"],
537
+ "en": ["innovation", "productivity", "workflow", "SaaS"],
538
+ "fr": ["innovation", "productivité", "flux de travail", "SaaS"],
539
+ "es": ["innovación", "productividad", "flujo de trabajo", "SaaS"]
540
+ }
541
+ }
542
+ }
543
+ }
544
+ ```
545
+
546
+ ```tsx fileName="src/app/page.content.ts" contentDeclarationFormat="typescript"
547
+ import { t, type Dictionary } from "intlayer";
548
+
549
+ const pageContent = {
550
+ key: "page",
551
+ content: {
552
+ getStarted: {
553
+ main: t({
554
+ zh: "通过编辑开始",
555
+ en: "Get started by editing",
556
+ fr: "Commencez par éditer",
557
+ es: "Comience por editar",
558
+ }),
559
+ pageLink: "src/app/page.tsx",
560
+ },
561
+ },
562
+ } satisfies Dictionary;
563
+
564
+ export default pageContent;
565
+ ```
566
+
567
+ ```javascript fileName="src/app/page.content.mjs" contentDeclarationFormat="esm"
568
+ import { t } from "intlayer";
569
+
570
+ /** @type {import('intlayer').Dictionary} */
571
+ const pageContent = {
572
+ key: "page",
573
+ content: {
574
+ getStarted: {
575
+ main: t({
576
+ zh: "通过编辑开始",
577
+ en: "Get started by editing",
578
+ fr: "Commencez par éditer",
579
+ es: "Comience por editar",
580
+ }),
581
+ pageLink: "src/app/page.tsx",
582
+ },
583
+ },
584
+ };
585
+
586
+ export default pageContent;
587
+ ```
588
+
589
+ ```javascript fileName="src/app/page.content.cjs" contentDeclarationFormat="commonjs"
590
+ const { t } = require("intlayer");
591
+
592
+ /** @type {import('intlayer').Dictionary} */
593
+ const pageContent = {
594
+ key: "page",
595
+ content: {
596
+ getStarted: {
597
+ main: t({
598
+ zh: "通过编辑开始",
599
+ en: "Get started by editing",
600
+ fr: "Commencez par éditer",
601
+ es: "Comience por editar",
602
+ }),
603
+ pageLink: "src/app/page.tsx",
604
+ },
605
+ },
606
+ };
607
+
608
+ module.exports = pageContent;
609
+ ```
610
+
611
+ ```json fileName="src/app/page.content.json" contentDeclarationFormat="json"
612
+ {
613
+ "$schema": "https://intlayer.org/schema.json",
614
+ "key": "page",
615
+ "content": {
616
+ "getStarted": {
617
+ "nodeType": "translation",
618
+ "translation": {
619
+ "zh": "通过编辑开始",
620
+ "en": "Get started by editing",
621
+ "fr": "Commencez par éditer",
622
+ "es": "Comience por editar"
623
+ }
624
+ },
625
+ "pageLink": "src/app/page.tsx"
626
+ }
627
+ }
628
+ ```
629
+
630
+ > 你的内容声明可以在应用的任何位置定义,只要它们被包含到 `contentDir` 目录(默认 `./src`)中。并且与内容声明文件扩展名匹配(默认 `.content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}`)。
631
+
632
+ > 有关详细信息,请参阅 [内容声明文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/dictionary/content_file.md)。
633
+
634
+ ### 步骤 6:在代码中使用内容
635
+
636
+ 在应用程序中随处访问你的内容字典:
637
+
638
+ ```tsx fileName="src/app/page.tsx" codeFormat="typescript"
639
+ import type { FC } from "react";
640
+ import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";
641
+ import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";
642
+ import {
643
+ IntlayerServerProvider,
644
+ useIntlayer,
645
+ getLocale,
646
+ } from "next-intlayer/server";
647
+ import { NextPage } from "next";
648
+ import { headers, cookies } from "next/headers";
649
+
650
+ const PageContent: FC = () => {
651
+ const content = useIntlayer("page");
652
+
653
+ return (
654
+ <>
655
+ <p>{content.getStarted.main}</p>
656
+ <code>{content.getStarted.pageLink}</code>
657
+ </>
658
+ );
659
+ };
660
+
661
+ const Page: NextPage = async () => {
662
+ // 在 Next.js 15+ 中等待 headers 和 cookies
663
+ const headerList = await headers();
664
+ const cookieList = await cookies();
665
+
666
+ const locale = await getLocale({
667
+ // 首先检查 intlayer cookie(默认: 'INTLAYER_LOCALE')
668
+ getCookie: (name) => cookieList.get(name)?.value,
669
+
670
+ // 然后检查 intlayer header(默认:'x-intlayer-locale')
671
+ // 最后检查 accept-language header('accept-language')
672
+ getHeader: (name) => headerList.get(name),
673
+ });
674
+
675
+ return (
676
+ <IntlayerServerProvider locale={locale}>
677
+ <PageContent />
678
+ <ServerComponentExample />
679
+ <ClientComponentExample />
680
+ </IntlayerServerProvider>
681
+ );
682
+ };
683
+
684
+ export default Page;
685
+ ```
686
+
687
+ ```jsx fileName="src/app/page.mjx" codeFormat="esm"
688
+ import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";
689
+ import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";
690
+ import { IntlayerServerProvider, useIntlayer, getLocale } from "next-intlayer/server";
691
+ import { headers, cookies } from "next/headers";
692
+ import { NextPage } from "next";
693
+
694
+ const Page: NextPage = async () => {
695
+ const content = useIntlayer("page");
696
+
697
+ return (
698
+ <>
699
+ <p>{content.getStarted.main}</p>
700
+ <code>{content.getStarted.pageLink}</code>
701
+ </>
702
+ );
703
+ };
704
+
705
+ const Page = async () => {
706
+
707
+ // 在 Next.js 15+ 中等待 headers 和 cookies
708
+ const headerList = await headers();
709
+ const cookieList = await cookies();
710
+
711
+ const locale = await getLocale({
712
+ // 首先检查 intlayer cookie(默认:'INTLAYER_LOCALE')
713
+ getCookie: (name) => cookieList.get(name)?.value,
714
+
715
+ // 然后检查 intlayer header(默认:'x-intlayer-locale')
716
+ // 最后检查 accept-language 头('accept-language')
717
+ getHeader: (name) => headerList.get(name),
718
+ });
719
+
720
+ return (
721
+ <IntlayerServerProvider locale={locale}>
722
+ <PageContent />
723
+ <ServerComponentExample />
724
+ <ClientComponentExample />
725
+ </IntlayerServerProvider>
726
+ );
727
+ };
728
+
729
+ export default Page;
730
+ ```
731
+
732
+ ```jsx fileName="src/app/page.csx" codeFormat="commonjs"
733
+ import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";
734
+ import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";
735
+ import { IntlayerServerProvider, useIntlayer, getLocale } from "next-intlayer/server";
736
+ import { NextPage } from "next";
737
+ import { headers, cookies } from "next/headers";
738
+
739
+ const Page: NextPage = async () => {
740
+ const content = useIntlayer("page");
741
+
742
+ return (
743
+ <>
744
+ <p>{content.getStarted.main}</p>
745
+ <code>{content.getStarted.pageLink}</code>
746
+ </>
747
+ );
748
+ };
749
+
750
+ const Page: NextPage = async () => {
751
+ // 在 Next.js 15+ 中等待 headers 和 cookies
752
+ const headerList = await headers();
753
+ const cookieList = await cookies();
754
+
755
+ const locale = await getLocale({
756
+ // 首先检查 intlayer cookie(默认: 'INTLAYER_LOCALE')
757
+ getCookie: (name) => cookieList.get(name)?.value,
758
+
759
+ // 然后检查 intlayer header(默认: 'x-intlayer-locale')
760
+ // 最后检查 accept-language header('accept-language')
761
+ getHeader: (name) => headerList.get(name),
762
+ });
763
+
764
+ return (
765
+ <IntlayerServerProvider locale={locale}>
766
+ <PageContent />
767
+ <ServerComponentExample />
768
+ <ClientComponentExample />
769
+ </IntlayerServerProvider>
770
+ );
771
+ };
772
+ ```
773
+
774
+ - **`IntlayerClientProvider`** 用于将 locale 提供给客户端组件。它可以放在任何父组件中,包括 layout。然而,建议将其放在 layout 中,因为 Next.js 在页面之间会共享 layout 代码,这样更高效。将 `IntlayerClientProvider` 放在 layout 中可以避免为每个页面重新初始化,从而提高性能并在整个应用中保持一致的本地化上下文。
775
+ - **`IntlayerServerProvider`** 用于将 locale 提供给服务端子组件。它不能设置在 layout 中。
776
+
777
+ > Layout 和 page 不能共享同一个 server context,因为 server context 系统基于每次请求的数据存储(通过 [React's cache](https://react.dev/reference/react/cache) 机制),导致每个 "context" 会为应用的不同部分被重新创建。将 provider 放在共享 layout 中会破坏此隔离,阻止 server context 值正确传播到你的 server components。
778
+
779
+ ```tsx {4,7} fileName="src/components/clientComponentExample/ClientComponentExample.tsx" codeFormat="typescript"
780
+ "use client";
781
+
782
+ import type { FC } from "react";
783
+ import { useIntlayer } from "next-intlayer";
784
+
785
+ export const ClientComponentExample: FC = () => {
786
+ const content = useIntlayer("client-component-example"); // 创建相关内容声明
787
+
788
+ return (
789
+ <div>
790
+ <h2>{content.title}</h2>
791
+ <p>{content.content}</p>
792
+ </div>
793
+ );
794
+ };
795
+ ```
796
+
797
+ ```jsx {3,6} fileName="src/components/clientComponentExample/ClientComponentExample.mjx" codeFormat="esm"
798
+ "use client";
799
+
800
+ import { useIntlayer } from "next-intlayer";
801
+
802
+ const ClientComponentExample = () => {
803
+ const content = useIntlayer("client-component-example"); // 创建相关内容声明
804
+
805
+ return (
806
+ <div>
807
+ <h2>{content.title}</h2>
808
+ <p>{content.content}</p>
809
+ </div>
810
+ );
811
+ };
812
+ ```
813
+
814
+ ```jsx {3,6} fileName="src/components/clientComponentExample/ClientComponentExample.csx" codeFormat="commonjs"
815
+ "use client";
816
+
817
+ const { useIntlayer } = require("next-intlayer");
818
+
819
+ const ClientComponentExample = () => {
820
+ const content = useIntlayer("client-component-example"); // 创建相关内容声明
821
+
822
+ return (
823
+ <div>
824
+ <h2>{content.title}</h2>
825
+ <p>{content.content}</p>
826
+ </div>
827
+ );
828
+ };
829
+ ```
830
+
831
+ ```tsx {2} fileName="src/components/serverComponentExample/ServerComponentExample.tsx" codeFormat="typescript"
832
+ import type { FC } from "react";
833
+ import { useIntlayer } from "next-intlayer/server";
834
+
835
+ export const ServerComponentExample: FC = () => {
836
+ const content = useIntlayer("server-component-example"); // 创建相关内容声明
837
+
838
+ return (
839
+ <div>
840
+ <h2>{content.title}</h2>
841
+ <p>{content.content}</p>
842
+ </div>
843
+ );
844
+ };
845
+ ```
846
+
847
+ ```jsx {1} fileName="src/components/serverComponentExample/ServerComponentExample.mjx" codeFormat="esm"
848
+ import { useIntlayer } from "next-intlayer/server";
849
+
850
+ const ServerComponentExample = () => {
851
+ const content = useIntlayer("server-component-example"); // 创建相关内容声明
852
+
853
+ return (
854
+ <div>
855
+ <h2>{content.title}</h2>
856
+ <p>{content.content}</p>
857
+ </div>
858
+ );
859
+ };
860
+ ```
861
+
862
+ ```jsx {1} fileName="src/components/serverComponentExample/ServerComponentExample.csx" codeFormat="commonjs"
863
+ const { useIntlayer } = require("next-intlayer/server");
864
+
865
+ const ServerComponentExample = () => {
866
+ const content = useIntlayer("server-component-example"); // 创建相关内容声明
867
+
868
+ return (
869
+ <div>
870
+ <h2>{content.title}</h2>
871
+ <p>{content.content}</p>
872
+ </div>
873
+ );
874
+ };
875
+ ```
876
+
877
+ > 如果您想在 `string` 属性(例如 `alt`、`title`、`href`、`aria-label` 等)中使用内容,必须调用函数的值,例如:
878
+
879
+ > ```jsx
880
+ > <img src={content.image.src.value} alt={content.image.value} />
881
+ > ```
882
+
883
+ > 若要了解有关 `useIntlayer` hook 的更多信息,请参阅 [文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/next-intlayer/useIntlayer.md)。
884
+
885
+ ### (可选)步骤 7:配置 Proxy 以进行 locale 检测
886
+
887
+ 设置 Proxy 以检测用户的首选 locale:
888
+
889
+ ```typescript fileName="src/proxy.ts" codeFormat="typescript"
890
+ export { intlayerProxy as proxy } from "next-intlayer/proxy";
891
+
892
+ export const config = {
893
+ matcher:
894
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
895
+ };
896
+ ```
897
+
898
+ ```javascript fileName="src/proxy.mjs" codeFormat="esm"
899
+ export { intlayerProxy as proxy } from "next-intlayer/proxy";
900
+
901
+ export const config = {
902
+ matcher:
903
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
904
+ };
905
+ ```
906
+
907
+ ```javascript fileName="src/proxy.cjs" codeFormat="commonjs"
908
+ const { intlayerProxy } = require("next-intlayer/proxy");
909
+
910
+ const config = {
911
+ matcher:
912
+ "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
913
+ };
914
+
915
+ module.exports = { proxy: intlayerProxy, config };
916
+ ```
917
+
918
+ > `intlayerProxy` 用于检测用户偏好的 locale,并根据 [配置](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/configuration.md) 将用户重定向到相应的 URL。除此之外,它还可以将用户偏好的 locale 保存在 cookie 中。
919
+
920
+ > 如果需要将多个代理串联在一起(例如将 `intlayerProxy` 与身份验证或自定义代理一起使用),Intlayer 现在提供了一个名为 `multipleProxies` 的辅助函数。
921
+
922
+ ```ts
923
+ import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";
924
+ import { customProxy } from "@utils/customProxy";
925
+
926
+ export const proxy = multipleProxies([intlayerProxy, customProxy]);
927
+ ```
928
+
929
+ ### (可选)步骤 8:更改您内容的语言
930
+
931
+ 要在 Next.js 中更改内容的语言,推荐的方法是使用 `Link` 组件将用户重定向到相应的本地化页面。`Link` 组件支持页面预取,这有助于避免整页重新加载。
932
+
933
+ ```tsx fileName="src/components/localeSwitcher/LocaleSwitcher.tsx" codeFormat="typescript"
934
+ "use client";
935
+
936
+ import type { FC } from "react";
937
+ import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";
938
+ import { useLocale } from "next-intlayer";
939
+
940
+ export const LocaleSwitcher: FC = () => {
941
+ const { locale, availableLocales, setLocale } = useLocale({
942
+ onChange: () => window.location.reload(),
943
+ });
944
+
945
+ return (
946
+ <div>
947
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
948
+ <div id="localePopover" popover="auto">
949
+ {availableLocales.map((localeItem) => (
950
+ <button
951
+ key={localeItem}
952
+ aria-current={locale === localeItem ? "page" : undefined}
953
+ onClick={() => setLocale(localeItem)}
954
+ >
955
+ <span>
956
+ {/* Locale(例如:FR) */}
957
+ {localeItem}
958
+ </span>
959
+ <span>
960
+ {/* 以该语言自身的 Locale 表示的语言名称(例如:Français) */}
961
+ {getLocaleName(localeItem, locale)}
962
+ </span>
963
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
964
+ {/* 以当前 Locale 表示的语言名称 — 例如:当当前 locale 设置为 Locales.SPANISH 时显示:Francés */}
965
+ {getLocaleName(localeItem)}
966
+ </span>
967
+ <span dir="ltr" lang={Locales.ENGLISH}>
968
+ {/* 以英语显示的语言 - 例如 French */}
969
+ {getLocaleName(localeItem, Locales.ENGLISH)}
970
+ </span>
971
+ </button>
972
+ ))}
973
+ </div>
974
+ </div>
975
+ );
976
+ };
977
+ ```
978
+
979
+ ```jsx fileName="src/components/localeSwitcher/LocaleSwitcher.msx" codeFormat="esm"
980
+ "use client";
981
+
982
+ import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";
983
+ import { useLocale } from "next-intlayer";
984
+
985
+ export const LocaleSwitcher = () => {
986
+ const { locale, availableLocales, setLocale } = useLocale({
987
+ onChange: () => window.location.reload(),
988
+ });
989
+
990
+ return (
991
+ <div>
992
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
993
+ <div id="localePopover" popover="auto">
994
+ {availableLocales.map((localeItem) => (
995
+ <button
996
+ key={localeItem}
997
+ aria-current={locale === localeItem ? "page" : undefined}
998
+ onClick={() => setLocale(localeItem)}
999
+ >
1000
+ <span>
1001
+ {/* Locale 缩写 - 例如:FR */}
1002
+ {localeItem}
1003
+ </span>
1004
+ <span>
1005
+ {/* 以该语言自身的 Locale 表示的语言 - 例如:Français */}
1006
+ {getLocaleName(localeItem, locale)}
1007
+ </span>
1008
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1009
+ {/* 以当前 Locale 表示的语言 - 例如(当当前 locale 为 Locales.SPANISH 时):Francés */}
1010
+ {getLocaleName(localeItem)}
1011
+ </span>
1012
+ <span dir="ltr" lang={Locales.ENGLISH}>
1013
+ {/* 以英文表示的语言 - 例如:French */}
1014
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1015
+ </span>
1016
+ </button>
1017
+ ))}
1018
+ </div>
1019
+ </div>
1020
+ );
1021
+ };
1022
+ ```
1023
+
1024
+ ```jsx fileName="src/components/localeSwitcher/LocaleSwitcher.csx" codeFormat="commonjs"
1025
+ "use client";
1026
+
1027
+ const { Locales, getHTMLTextDir, getLocaleName } = require("intlayer");
1028
+ const { useLocale } = require("next-intlayer");
1029
+
1030
+ export const LocaleSwitcher = () => {
1031
+ const path
1032
+ const { locale availableLocales, setLocale } = useLocale({
1033
+ onChange: ()=> window.location.reload(),
1034
+ });
1035
+
1036
+ return (
1037
+ <div>
1038
+ <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
1039
+ <div id="localePopover" popover="auto">
1040
+ {availableLocales.map((localeItem) => (
1041
+ <button
1042
+ key={localeItem}
1043
+ aria-current={locale === localeItem ? "page" : undefined}
1044
+ onClick={() => setLocale(localeItem)}
1045
+ >
1046
+ <span>
1047
+ {/* 区域(Locale)- 例如:FR */}
1048
+ {localeItem}
1049
+ </span>
1050
+ <span>
1051
+ {/* 以该语言自身显示的语言名 - 例如:Français */}
1052
+ {getLocaleName(localeItem, locale)}
1053
+ </span>
1054
+ <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
1055
+ {/* 以当前区域显示的语言名 - 例如:在当前区域设为 Locales.SPANISH 时显示 Francés */}
1056
+ {getLocaleName(localeItem)}
1057
+ </span>
1058
+ <span dir="ltr" lang={Locales.ENGLISH}>
1059
+ {/* 以英语显示的语言名 - 例如:French */}
1060
+ {getLocaleName(localeItem, Locales.ENGLISH)}
1061
+ </span>
1062
+ </button>
1063
+ ))}
1064
+ </div>
1065
+ </div>
1066
+ );
1067
+ };
1068
+ ```
1069
+
1070
+ > 另一种方法是使用 `useLocale` hook 提供的 `setLocale` 函数。此函数不会允许预获取页面。有关更多详细信息,请参阅 [`useLocale` hook 文档](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/next-intlayer/useLocale.md)。
1071
+
1072
+ > 文档参考:
1073
+ >
1074
+ > - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/next-intlayer/useLocale.md)
1075
+ > - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocaleName.md)
1076
+ > - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getLocalizedUrl.md)
1077
+ > - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/packages/intlayer/getHTMLTextDir.md)
1078
+ > - [`hrefLang` attribute](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
1079
+ > - [`lang` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)
1080
+ > - [`dir` attribute`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir)
1081
+ > - [`aria-current` attribute`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
1082
+
1083
+ ###(可选)步骤 9:在 Server Actions 中获取当前 locale
1084
+
1085
+ 如果你需要在 Server Action 中使用活动 locale(例如,用于本地化电子邮件或运行与 locale 相关的逻辑),请从 `next-intlayer/server` 调用 `getLocale`:
1086
+
1087
+ ```tsx fileName="src/app/actions/getLocale.ts" codeFormat="typescript"
1088
+ "use server";
1089
+
1090
+ import { getLocale } from "next-intlayer/server";
1091
+
1092
+ export const myServerAction = async () => {
1093
+ const locale = await getLocale();
1094
+
1095
+ // 使用该 locale 执行一些操作
1096
+ };
1097
+ ```
1098
+
1099
+ > `getLocale` 函数采用级联策略来确定用户的语言环境:
1100
+ >
1101
+ > 1. 首先,它会检查请求头中是否存在可能由代理设置的 locale 值
1102
+ > 2. 如果在请求头中未找到 locale,则查找存储在 cookies 中的 locale
1103
+ > 3. 如果未找到 cookie,它会尝试从用户的浏览器设置中检测首选语言
1104
+ > 4. 最后,它会回退到应用程序配置的默认 locale
1105
+ >
1106
+ > 这可确保基于可用上下文选择最合适的 locale。
1107
+
1108
+ ### (可选)步骤 10:优化你的 bundle 大小
1109
+
1110
+ 在使用 `next-intlayer` 时,字典默认会被包含到每个页面的 bundle 中。为了优化 bundle 大小,Intlayer 提供了一个可选的 SWC 插件,它使用宏智能替换 `useIntlayer` 调用。这样只有实际使用这些字典的页面的 bundle 才会包含相应字典。
1111
+
1112
+ 要启用此优化,请安装 `@intlayer/swc` 包。安装后,`next-intlayer` 会自动检测并使用该插件:
1113
+
1114
+ ```bash packageManager="npm"
1115
+ npm install @intlayer/swc --save-dev
1116
+ npx intlayer init
1117
+ ```
1118
+
1119
+ ```bash packageManager="pnpm"
1120
+ pnpm add @intlayer/swc --save-dev
1121
+ pnpm intlayer init
1122
+ ```
1123
+
1124
+ ```bash packageManager="yarn"
1125
+ yarn add @intlayer/swc --save-dev
1126
+ yarn intlayer init
1127
+ ```
1128
+
1129
+ ```bash packageManager="bun"
1130
+ bun add @intlayer/swc --dev
1131
+ bunx intlayer init
1132
+ ```
1133
+
1134
+ > 注意:此优化仅适用于 Next.js 13 及更高版本。
1135
+
1136
+ > 注意:该包默认不安装,因为 SWC 插件在 Next.js 中仍然是实验性的。将来可能会发生变化。
1137
+
1138
+ > 注意:如果你将选项设置为 `importMode: 'dynamic'` 或 `importMode: 'live'`,它将依赖 Suspense,因此你必须在一个 `Suspense` 边界中包裹你的 `useIntlayer` 调用。这意味着你不能在页面 / 布局组件的顶层直接使用 `useIntlayer`。
1139
+
1140
+ ### 在 Turbopack 上监视字典更改
1141
+
1142
+ 当使用 Turbopack 作为通过 `next dev` 命令运行的开发服务器时,字典更改默认不会被自动检测。
1143
+
1144
+ 这个限制是因为 Turbopack 无法并行运行 webpack 插件来监视内容文件的更改。为了解决这个问题,你需要使用 `intlayer watch` 命令同时运行开发服务器和 Intlayer 构建监视器。
1145
+
1146
+ ```json5 fileName="package.json"
1147
+ {
1148
+ // ... 你现有的 package.json 配置
1149
+ "scripts": {
1150
+ // ... 你现有的 scripts 配置
1151
+ "dev": "intlayer watch --with 'next dev'",
1152
+ },
1153
+ }
1154
+ ```
1155
+
1156
+ > 如果你使用的是 next-intlayer@<=6.x.x,你需要保留 `--turbopack` 标志以使 Next.js 16 应用程序能与 Turbopack 正常工作。我们建议使用 next-intlayer@>=7.x.x 来避免此限制。
1157
+
1158
+ ### 配置 TypeScript
1159
+
1160
+ Intlayer 使用模块扩展(module augmentation)来利用 TypeScript 的优势并增强你的 codebase 的类型安全性。
1161
+
1162
+ ![自动完成](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)
1163
+
1164
+ ![翻译错误](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)
1165
+
1166
+ 确保你的 TypeScript 配置包含自动生成的类型。
1167
+
1168
+ ```json5 fileName="tsconfig.json"
1169
+ {
1170
+ // ... 你现有的 TypeScript 配置
1171
+ "include": [
1172
+ // ... 你现有的 TypeScript 配置
1173
+ ".intlayer/**/*.ts", // 包含自动生成的类型
1174
+ ],
1175
+ }
1176
+ ```
1177
+
1178
+ ### Git 配置
1179
+
1180
+ 建议将 Intlayer 生成的文件忽略(ignore)。这样可以避免将这些文件提交到你的 Git 仓库。
1181
+
1182
+ 为此,你可以将以下内容添加到你的 `.gitignore` 文件中:
1183
+
1184
+ ```plaintext fileName=".gitignore"
1185
+ # 忽略 Intlayer 生成的文件
1186
+ .intlayer
1187
+ ```
1188
+
1189
+ ### VS Code Extension
1190
+
1191
+ 为了提升在 Intlayer 的开发体验,你可以安装官方的 **Intlayer VS Code Extension**。
1192
+
1193
+ [从 VS Code Marketplace 安装](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
1194
+
1195
+ 此扩展提供:
1196
+
1197
+ - **Autocompletion**:翻译键自动补全。
1198
+ - **Real-time error detection**:实时检测缺失的翻译。
1199
+ - **内联预览** 翻译后的内容。
1200
+ - **快速操作** 以便轻松创建和更新翻译。
1201
+
1202
+ 有关如何使用该扩展的更多详细信息,请参阅 [Intlayer VS Code 扩展文档](https://intlayer.org/doc/vs-code-extension)。
1203
+
1204
+ ### 更进一步
1205
+
1206
+ 要深入了解,您可以实现 [可视化编辑器](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) 将内容外部化。