@intlayer/docs 7.0.7 → 7.0.8

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 (726) hide show
  1. package/blog/ar/i18n_using_next-i18next.md +1068 -0
  2. package/blog/ar/i18n_using_next-intl.md +768 -0
  3. package/blog/ar/intlayer_with_react-intl.md +0 -4
  4. package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +5 -4
  5. package/blog/de/i18n_using_next-i18next.md +1107 -0
  6. package/blog/de/i18n_using_next-intl.md +760 -0
  7. package/blog/de/intlayer_with_react-intl.md +0 -4
  8. package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  9. package/blog/en/i18n_using_next-i18next.md +1073 -0
  10. package/blog/en/i18n_using_next-intl.md +757 -0
  11. package/blog/en/intlayer_with_i18next.md +71 -8
  12. package/blog/en/intlayer_with_next-i18next.md +71 -8
  13. package/blog/en/intlayer_with_next-intl.md +71 -8
  14. package/blog/en/intlayer_with_react-i18next.md +69 -8
  15. package/blog/en/intlayer_with_react-intl.md +68 -9
  16. package/blog/en/intlayer_with_vue-i18n.md +68 -7
  17. package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
  18. package/blog/en/vue-i18n_vs_intlayer.md +2 -0
  19. package/blog/en-GB/i18n_using_next-i18next.md +1074 -0
  20. package/blog/en-GB/i18n_using_next-intl.md +757 -0
  21. package/blog/en-GB/intlayer_with_i18next.md +15 -6
  22. package/blog/en-GB/intlayer_with_next-i18next.md +16 -6
  23. package/blog/en-GB/intlayer_with_next-intl.md +16 -6
  24. package/blog/en-GB/intlayer_with_react-i18next.md +16 -7
  25. package/blog/en-GB/intlayer_with_react-intl.md +14 -9
  26. package/blog/en-GB/intlayer_with_vue-i18n.md +16 -7
  27. package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  28. package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
  29. package/blog/en-GB/vue-i18n_vs_intlayer.md +2 -0
  30. package/blog/es/i18n_using_next-i18next.md +1066 -0
  31. package/blog/es/i18n_using_next-intl.md +757 -0
  32. package/blog/es/intlayer_with_react-intl.md +0 -4
  33. package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  34. package/blog/fr/i18n_using_next-i18next.md +1078 -0
  35. package/blog/fr/i18n_using_next-intl.md +759 -0
  36. package/blog/fr/intlayer_with_react-intl.md +0 -4
  37. package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  38. package/blog/hi/i18n_using_next-i18next.md +1068 -0
  39. package/blog/hi/i18n_using_next-intl.md +758 -0
  40. package/blog/hi/intlayer_with_react-intl.md +0 -4
  41. package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  42. package/blog/id/i18n_using_next-i18next.md +1078 -0
  43. package/blog/id/i18n_using_next-intl.md +757 -0
  44. package/blog/id/index.md +69 -0
  45. package/blog/id/internationalization_and_SEO.md +364 -0
  46. package/blog/id/intlayer_with_react-intl.md +0 -4
  47. package/blog/id/list_i18n_technologies/CMS/drupal.md +143 -0
  48. package/blog/id/list_i18n_technologies/CMS/wix.md +167 -0
  49. package/blog/id/list_i18n_technologies/CMS/wordpress.md +188 -0
  50. package/blog/id/list_i18n_technologies/frameworks/angular.md +125 -0
  51. package/blog/id/list_i18n_technologies/frameworks/flutter.md +150 -0
  52. package/blog/id/list_i18n_technologies/frameworks/react-native.md +217 -0
  53. package/blog/id/list_i18n_technologies/frameworks/react.md +155 -0
  54. package/blog/id/list_i18n_technologies/frameworks/svelte.md +131 -0
  55. package/blog/id/list_i18n_technologies/frameworks/vue.md +130 -0
  56. package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +1500 -0
  57. package/blog/id/nextjs-multilingual-seo-comparison.md +361 -0
  58. package/blog/id/rag_powered_documentation_assistant.md +288 -0
  59. package/blog/id/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
  60. package/blog/id/vue-i18n_vs_intlayer.md +278 -0
  61. package/blog/id/what_is_internationalization.md +166 -0
  62. package/blog/it/i18n_using_next-i18next.md +1078 -0
  63. package/blog/it/i18n_using_next-intl.md +758 -0
  64. package/blog/it/intlayer_with_react-intl.md +0 -4
  65. package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +4 -0
  66. package/blog/it/vue-i18n_vs_intlayer.md +2 -0
  67. package/blog/ja/i18n_using_next-i18next.md +1078 -0
  68. package/blog/ja/i18n_using_next-intl.md +758 -0
  69. package/blog/ja/intlayer_with_react-intl.md +0 -4
  70. package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  71. package/blog/ko/i18n_using_next-i18next.md +1075 -0
  72. package/blog/ko/i18n_using_next-intl.md +759 -0
  73. package/blog/ko/intlayer_with_react-intl.md +0 -4
  74. package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  75. package/blog/pl/i18n_using_next-i18next.md +1078 -0
  76. package/blog/pl/i18n_using_next-intl.md +758 -0
  77. package/blog/pl/index.md +69 -0
  78. package/blog/pl/internationalization_and_SEO.md +363 -0
  79. package/blog/pl/intlayer_with_react-intl.md +0 -4
  80. package/blog/pl/list_i18n_technologies/CMS/drupal.md +143 -0
  81. package/blog/pl/list_i18n_technologies/CMS/wix.md +167 -0
  82. package/blog/pl/list_i18n_technologies/CMS/wordpress.md +196 -0
  83. package/blog/pl/list_i18n_technologies/frameworks/angular.md +125 -0
  84. package/blog/pl/list_i18n_technologies/frameworks/flutter.md +151 -0
  85. package/blog/pl/list_i18n_technologies/frameworks/react-native.md +217 -0
  86. package/blog/pl/list_i18n_technologies/frameworks/react.md +155 -0
  87. package/blog/pl/list_i18n_technologies/frameworks/svelte.md +131 -0
  88. package/blog/pl/list_i18n_technologies/frameworks/vue.md +130 -0
  89. package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +1501 -0
  90. package/blog/pl/nextjs-multilingual-seo-comparison.md +362 -0
  91. package/blog/pl/rag_powered_documentation_assistant.md +288 -0
  92. package/blog/pl/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
  93. package/blog/pl/vue-i18n_vs_intlayer.md +278 -0
  94. package/blog/pl/what_is_internationalization.md +167 -0
  95. package/blog/pt/i18n_using_next-i18next.md +1067 -0
  96. package/blog/pt/i18n_using_next-intl.md +760 -0
  97. package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  98. package/blog/ru/i18n_using_next-i18next.md +1106 -0
  99. package/blog/ru/i18n_using_next-intl.md +759 -0
  100. package/blog/ru/intlayer_with_react-intl.md +0 -4
  101. package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  102. package/blog/tr/i18n_using_next-i18next.md +1078 -0
  103. package/blog/tr/i18n_using_next-intl.md +760 -0
  104. package/blog/tr/intlayer_with_react-intl.md +0 -4
  105. package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  106. package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
  107. package/blog/tr/vue-i18n_vs_intlayer.md +2 -0
  108. package/blog/vi/i18n_using_next-i18next.md +1080 -0
  109. package/blog/vi/i18n_using_next-intl.md +758 -0
  110. package/blog/vi/index.md +69 -0
  111. package/blog/vi/internationalization_and_SEO.md +363 -0
  112. package/blog/vi/intlayer_with_react-intl.md +0 -4
  113. package/blog/vi/list_i18n_technologies/CMS/drupal.md +143 -0
  114. package/blog/vi/list_i18n_technologies/CMS/wix.md +167 -0
  115. package/blog/vi/list_i18n_technologies/CMS/wordpress.md +188 -0
  116. package/blog/vi/list_i18n_technologies/frameworks/angular.md +125 -0
  117. package/blog/vi/list_i18n_technologies/frameworks/flutter.md +150 -0
  118. package/blog/vi/list_i18n_technologies/frameworks/react-native.md +217 -0
  119. package/blog/vi/list_i18n_technologies/frameworks/react.md +155 -0
  120. package/blog/vi/list_i18n_technologies/frameworks/svelte.md +131 -0
  121. package/blog/vi/list_i18n_technologies/frameworks/vue.md +130 -0
  122. package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +1520 -0
  123. package/blog/vi/nextjs-multilingual-seo-comparison.md +362 -0
  124. package/blog/vi/rag_powered_documentation_assistant.md +288 -0
  125. package/blog/vi/react-i18next_vs_react-intl_vs_intlayer.md +164 -0
  126. package/blog/vi/vue-i18n_vs_intlayer.md +278 -0
  127. package/blog/vi/what_is_internationalization.md +168 -0
  128. package/blog/zh/i18n_using_next-i18next.md +1105 -0
  129. package/blog/zh/i18n_using_next-intl.md +758 -0
  130. package/blog/zh/intlayer_with_react-intl.md +0 -4
  131. package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +2 -0
  132. package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +2 -0
  133. package/dist/cjs/common.cjs +0 -4
  134. package/dist/cjs/common.cjs.map +1 -1
  135. package/dist/cjs/generated/blog.entry.cjs +38 -6
  136. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  137. package/dist/cjs/generated/docs.entry.cjs +0 -6
  138. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  139. package/dist/cjs/generated/frequentQuestions.entry.cjs +0 -6
  140. package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
  141. package/dist/cjs/generated/legal.entry.cjs +0 -6
  142. package/dist/cjs/generated/legal.entry.cjs.map +1 -1
  143. package/dist/esm/generated/blog.entry.mjs +38 -0
  144. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  145. package/dist/types/generated/blog.entry.d.ts +2 -0
  146. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  147. package/docs/ar/component_i18n.md +1 -1
  148. package/docs/ar/configuration.md +6 -0
  149. package/docs/ar/intlayer_cli.md +8 -3
  150. package/docs/ar/intlayer_with_next-i18next.md +619 -0
  151. package/docs/ar/intlayer_with_next-intl.md +446 -0
  152. package/docs/ar/intlayer_with_nextjs_16.md +21 -0
  153. package/docs/ar/intlayer_with_tanstack.md +4 -0
  154. package/docs/ar/intlayer_with_vite+react.md +4 -0
  155. package/docs/de/component_i18n.md +1 -1
  156. package/docs/de/configuration.md +6 -0
  157. package/docs/de/intlayer_cli.md +8 -3
  158. package/docs/de/intlayer_with_next-i18next.md +627 -0
  159. package/docs/de/intlayer_with_next-intl.md +451 -0
  160. package/docs/de/intlayer_with_nextjs_16.md +21 -0
  161. package/docs/de/intlayer_with_tanstack.md +4 -0
  162. package/docs/de/intlayer_with_vite+react.md +4 -0
  163. package/docs/en/component_i18n.md +1 -1
  164. package/docs/en/intlayer_cli.md +8 -1
  165. package/docs/en/intlayer_with_astro.md +10 -2
  166. package/docs/en/intlayer_with_create_react_app.md +8 -0
  167. package/docs/en/intlayer_with_lynx+react.md +8 -0
  168. package/docs/en/intlayer_with_nestjs.md +10 -0
  169. package/docs/en/intlayer_with_nextjs_14.md +10 -2
  170. package/docs/en/intlayer_with_nextjs_15.md +21 -4
  171. package/docs/en/intlayer_with_nextjs_16.md +17 -0
  172. package/docs/en/intlayer_with_nuxt.md +8 -0
  173. package/docs/en/intlayer_with_react_native+expo.md +10 -2
  174. package/docs/en/intlayer_with_react_router_v7.md +8 -0
  175. package/docs/en/intlayer_with_tanstack.md +10 -0
  176. package/docs/en/intlayer_with_vite+preact.md +10 -2
  177. package/docs/en/intlayer_with_vite+react.md +21 -4
  178. package/docs/en/intlayer_with_vite+vue.md +10 -2
  179. package/docs/en-GB/component_i18n.md +1 -1
  180. package/docs/en-GB/configuration.md +6 -0
  181. package/docs/en-GB/intlayer_cli.md +8 -3
  182. package/docs/en-GB/intlayer_with_angular.md +4 -4
  183. package/docs/en-GB/intlayer_with_express.md +4 -4
  184. package/docs/en-GB/intlayer_with_lynx+react.md +12 -12
  185. package/{blog/en/_intlayer_with_next-i18next.md → docs/en-GB/intlayer_with_next-i18next.md} +241 -42
  186. package/{blog/en/_intlayer_with_next-intl.md → docs/en-GB/intlayer_with_next-intl.md} +144 -29
  187. package/docs/en-GB/intlayer_with_nextjs_16.md +21 -0
  188. package/docs/en-GB/intlayer_with_tanstack.md +5 -1
  189. package/docs/en-GB/intlayer_with_vite+react.md +4 -0
  190. package/docs/en-GB/packages/next-intlayer/t.md +2 -2
  191. package/docs/es/component_i18n.md +1 -1
  192. package/docs/es/configuration.md +6 -0
  193. package/docs/es/intlayer_cli.md +8 -3
  194. package/docs/es/intlayer_with_next-i18next.md +628 -0
  195. package/docs/es/intlayer_with_next-intl.md +446 -0
  196. package/docs/es/intlayer_with_nextjs_16.md +21 -0
  197. package/docs/es/intlayer_with_tanstack.md +4 -0
  198. package/docs/es/intlayer_with_vite+react.md +4 -0
  199. package/docs/fr/configuration.md +6 -0
  200. package/docs/fr/intlayer_cli.md +8 -3
  201. package/docs/fr/intlayer_with_next-i18next.md +628 -0
  202. package/docs/fr/intlayer_with_next-intl.md +446 -0
  203. package/docs/fr/intlayer_with_nextjs_16.md +23 -2
  204. package/docs/fr/intlayer_with_tanstack.md +4 -0
  205. package/docs/fr/intlayer_with_vite+react.md +4 -0
  206. package/docs/hi/component_i18n.md +1 -1
  207. package/docs/hi/configuration.md +6 -0
  208. package/docs/hi/intlayer_cli.md +8 -0
  209. package/docs/hi/intlayer_with_next-i18next.md +628 -0
  210. package/docs/hi/intlayer_with_next-intl.md +446 -0
  211. package/docs/hi/intlayer_with_nextjs_16.md +21 -0
  212. package/docs/hi/intlayer_with_tanstack.md +4 -0
  213. package/docs/hi/intlayer_with_vite+react.md +4 -0
  214. package/docs/id/CI_CD.md +198 -0
  215. package/docs/id/autoFill.md +284 -0
  216. package/docs/id/component_i18n.md +186 -0
  217. package/docs/id/configuration.md +710 -0
  218. package/docs/id/dictionary/condition.md +231 -0
  219. package/docs/id/dictionary/content_file.md +1092 -0
  220. package/docs/id/dictionary/enumeration.md +245 -0
  221. package/docs/id/dictionary/file.md +237 -0
  222. package/docs/id/dictionary/function_fetching.md +214 -0
  223. package/docs/id/dictionary/gender.md +273 -0
  224. package/docs/id/dictionary/insertion.md +192 -0
  225. package/docs/id/dictionary/markdown.md +381 -0
  226. package/docs/id/dictionary/nesting.md +273 -0
  227. package/docs/id/dictionary/translation.md +310 -0
  228. package/docs/id/formatters.md +596 -0
  229. package/docs/id/how_works_intlayer.md +256 -0
  230. package/docs/id/index.md +176 -0
  231. package/docs/id/interest_of_intlayer.md +293 -0
  232. package/docs/id/intlayer_CMS.md +549 -0
  233. package/docs/id/intlayer_cli.md +850 -0
  234. package/docs/id/intlayer_visual_editor.md +288 -0
  235. package/docs/id/intlayer_with_angular.md +694 -0
  236. package/docs/id/intlayer_with_astro.md +252 -0
  237. package/docs/id/intlayer_with_create_react_app.md +1233 -0
  238. package/docs/id/intlayer_with_express.md +411 -0
  239. package/docs/id/intlayer_with_lynx+react.md +518 -0
  240. package/docs/id/intlayer_with_nestjs.md +272 -0
  241. package/docs/id/intlayer_with_next-i18next.md +628 -0
  242. package/docs/id/intlayer_with_next-intl.md +446 -0
  243. package/docs/id/intlayer_with_nextjs_14.md +1617 -0
  244. package/docs/id/intlayer_with_nextjs_15.md +1698 -0
  245. package/docs/id/intlayer_with_nextjs_16.md +21 -0
  246. package/docs/id/intlayer_with_nextjs_page_router.md +1478 -0
  247. package/docs/id/intlayer_with_nuxt.md +808 -0
  248. package/docs/id/intlayer_with_react_native+expo.md +699 -0
  249. package/docs/id/intlayer_with_react_router_v7.md +496 -0
  250. package/docs/id/intlayer_with_tanstack.md +564 -0
  251. package/docs/id/intlayer_with_vite+preact.md +1737 -0
  252. package/docs/id/intlayer_with_vite+react.md +1413 -0
  253. package/docs/id/intlayer_with_vite+solid.md +289 -0
  254. package/docs/id/intlayer_with_vite+svelte.md +289 -0
  255. package/docs/id/intlayer_with_vite+vue.md +1088 -0
  256. package/docs/id/introduction.md +218 -0
  257. package/docs/id/locale_mapper.md +242 -0
  258. package/docs/id/mcp_server.md +211 -0
  259. package/docs/id/packages/express-intlayer/t.md +458 -0
  260. package/docs/id/packages/intlayer/getConfiguration.md +145 -0
  261. package/docs/id/packages/intlayer/getEnumeration.md +159 -0
  262. package/docs/id/packages/intlayer/getHTMLTextDir.md +122 -0
  263. package/docs/id/packages/intlayer/getLocaleLang.md +81 -0
  264. package/docs/id/packages/intlayer/getLocaleName.md +119 -0
  265. package/docs/id/packages/intlayer/getLocalizedUrl.md +309 -0
  266. package/docs/id/packages/intlayer/getMultilingualUrls.md +223 -0
  267. package/docs/id/packages/intlayer/getPathWithoutLocale.md +75 -0
  268. package/docs/id/packages/intlayer/getTranslation.md +190 -0
  269. package/docs/id/packages/intlayer/getTranslationContent.md +188 -0
  270. package/docs/id/packages/next-intlayer/t.md +352 -0
  271. package/docs/id/packages/next-intlayer/useDictionary.md +271 -0
  272. package/docs/id/packages/next-intlayer/useIntlayer.md +264 -0
  273. package/docs/id/packages/next-intlayer/useLocale.md +166 -0
  274. package/docs/id/packages/react-intlayer/t.md +303 -0
  275. package/docs/id/packages/react-intlayer/useDictionary.md +287 -0
  276. package/docs/id/packages/react-intlayer/useI18n.md +267 -0
  277. package/docs/id/packages/react-intlayer/useIntlayer.md +254 -0
  278. package/docs/id/packages/react-intlayer/useLocale.md +210 -0
  279. package/docs/id/per_locale_file.md +323 -0
  280. package/docs/id/readme.md +261 -0
  281. package/docs/id/releases/v6.md +305 -0
  282. package/docs/id/roadmap.md +362 -0
  283. package/docs/id/testing.md +202 -0
  284. package/docs/id/vs_code_extension.md +126 -0
  285. package/docs/it/component_i18n.md +1 -1
  286. package/docs/it/configuration.md +6 -0
  287. package/docs/it/intlayer_cli.md +8 -3
  288. package/docs/it/intlayer_with_next-i18next.md +628 -0
  289. package/docs/it/intlayer_with_next-intl.md +446 -0
  290. package/docs/it/intlayer_with_nextjs_16.md +21 -0
  291. package/docs/it/intlayer_with_tanstack.md +4 -0
  292. package/docs/it/intlayer_with_vite+react.md +4 -0
  293. package/docs/ja/component_i18n.md +1 -1
  294. package/docs/ja/configuration.md +6 -0
  295. package/docs/ja/intlayer_cli.md +8 -3
  296. package/docs/ja/intlayer_with_next-i18next.md +627 -0
  297. package/docs/ja/intlayer_with_next-intl.md +446 -0
  298. package/docs/ja/intlayer_with_nextjs_16.md +21 -0
  299. package/docs/ja/intlayer_with_tanstack.md +4 -0
  300. package/docs/ja/intlayer_with_vite+react.md +4 -0
  301. package/docs/ko/configuration.md +6 -0
  302. package/docs/ko/intlayer_cli.md +8 -3
  303. package/docs/ko/intlayer_with_next-i18next.md +627 -0
  304. package/docs/ko/intlayer_with_next-intl.md +446 -0
  305. package/docs/ko/intlayer_with_nextjs_16.md +21 -0
  306. package/docs/ko/intlayer_with_tanstack.md +4 -0
  307. package/docs/ko/intlayer_with_vite+react.md +4 -0
  308. package/docs/pl/CI_CD.md +198 -0
  309. package/docs/pl/autoFill.md +284 -0
  310. package/docs/pl/component_i18n.md +186 -0
  311. package/docs/pl/configuration.md +710 -0
  312. package/docs/pl/dictionary/condition.md +232 -0
  313. package/docs/pl/dictionary/content_file.md +1130 -0
  314. package/docs/pl/dictionary/enumeration.md +245 -0
  315. package/docs/pl/dictionary/file.md +234 -0
  316. package/docs/pl/dictionary/function_fetching.md +214 -0
  317. package/docs/pl/dictionary/gender.md +276 -0
  318. package/docs/pl/dictionary/insertion.md +188 -0
  319. package/docs/pl/dictionary/markdown.md +408 -0
  320. package/docs/pl/dictionary/nesting.md +273 -0
  321. package/docs/pl/dictionary/translation.md +310 -0
  322. package/docs/pl/formatters.md +596 -0
  323. package/docs/pl/how_works_intlayer.md +256 -0
  324. package/docs/pl/index.md +176 -0
  325. package/docs/pl/interest_of_intlayer.md +291 -0
  326. package/docs/pl/intlayer_CMS.md +549 -0
  327. package/docs/pl/intlayer_cli.md +857 -0
  328. package/docs/pl/intlayer_visual_editor.md +288 -0
  329. package/docs/pl/intlayer_with_angular.md +690 -0
  330. package/docs/pl/intlayer_with_astro.md +280 -0
  331. package/docs/pl/intlayer_with_create_react_app.md +1235 -0
  332. package/docs/pl/intlayer_with_express.md +411 -0
  333. package/docs/pl/intlayer_with_lynx+react.md +518 -0
  334. package/docs/pl/intlayer_with_nestjs.md +272 -0
  335. package/docs/pl/intlayer_with_next-i18next.md +628 -0
  336. package/docs/pl/intlayer_with_next-intl.md +446 -0
  337. package/docs/pl/intlayer_with_nextjs_14.md +1594 -0
  338. package/docs/pl/intlayer_with_nextjs_15.md +1701 -0
  339. package/docs/pl/intlayer_with_nextjs_16.md +21 -0
  340. package/docs/pl/intlayer_with_nextjs_page_router.md +1513 -0
  341. package/docs/pl/intlayer_with_nuxt.md +885 -0
  342. package/docs/pl/intlayer_with_react_native+expo.md +698 -0
  343. package/docs/pl/intlayer_with_react_router_v7.md +503 -0
  344. package/docs/pl/intlayer_with_tanstack.md +562 -0
  345. package/docs/pl/intlayer_with_vite+preact.md +1736 -0
  346. package/docs/pl/intlayer_with_vite+react.md +1438 -0
  347. package/docs/pl/intlayer_with_vite+solid.md +290 -0
  348. package/docs/pl/intlayer_with_vite+svelte.md +289 -0
  349. package/docs/pl/intlayer_with_vite+vue.md +1116 -0
  350. package/docs/pl/introduction.md +209 -0
  351. package/docs/pl/locale_mapper.md +242 -0
  352. package/docs/pl/mcp_server.md +211 -0
  353. package/docs/pl/packages/express-intlayer/t.md +458 -0
  354. package/docs/pl/packages/intlayer/getConfiguration.md +146 -0
  355. package/docs/pl/packages/intlayer/getEnumeration.md +160 -0
  356. package/docs/pl/packages/intlayer/getHTMLTextDir.md +121 -0
  357. package/docs/pl/packages/intlayer/getLocaleLang.md +81 -0
  358. package/docs/pl/packages/intlayer/getLocaleName.md +118 -0
  359. package/docs/pl/packages/intlayer/getLocalizedUrl.md +300 -0
  360. package/docs/pl/packages/intlayer/getMultilingualUrls.md +221 -0
  361. package/docs/pl/packages/intlayer/getPathWithoutLocale.md +75 -0
  362. package/docs/pl/packages/intlayer/getTranslation.md +190 -0
  363. package/docs/pl/packages/intlayer/getTranslationContent.md +189 -0
  364. package/docs/pl/packages/next-intlayer/t.md +353 -0
  365. package/docs/pl/packages/next-intlayer/useDictionary.md +270 -0
  366. package/docs/pl/packages/next-intlayer/useIntlayer.md +263 -0
  367. package/docs/pl/packages/next-intlayer/useLocale.md +166 -0
  368. package/docs/pl/packages/react-intlayer/t.md +303 -0
  369. package/docs/pl/packages/react-intlayer/useDictionary.md +289 -0
  370. package/docs/pl/packages/react-intlayer/useI18n.md +249 -0
  371. package/docs/pl/packages/react-intlayer/useIntlayer.md +256 -0
  372. package/docs/pl/packages/react-intlayer/useLocale.md +210 -0
  373. package/docs/pl/per_locale_file.md +321 -0
  374. package/docs/pl/readme.md +261 -0
  375. package/docs/pl/releases/v6.md +305 -0
  376. package/docs/pl/roadmap.md +362 -0
  377. package/docs/pl/testing.md +202 -0
  378. package/docs/pl/vs_code_extension.md +126 -0
  379. package/docs/pt/component_i18n.md +1 -1
  380. package/docs/pt/configuration.md +6 -0
  381. package/docs/pt/intlayer_cli.md +8 -3
  382. package/docs/pt/intlayer_with_next-i18next.md +627 -0
  383. package/docs/pt/intlayer_with_next-intl.md +446 -0
  384. package/docs/pt/intlayer_with_nextjs_16.md +21 -0
  385. package/docs/pt/intlayer_with_tanstack.md +4 -0
  386. package/docs/pt/intlayer_with_vite+react.md +4 -0
  387. package/docs/ru/component_i18n.md +1 -1
  388. package/docs/ru/configuration.md +6 -0
  389. package/docs/ru/intlayer_cli.md +301 -22
  390. package/docs/ru/intlayer_with_next-i18next.md +629 -0
  391. package/docs/ru/intlayer_with_next-intl.md +448 -0
  392. package/docs/ru/intlayer_with_nextjs_16.md +21 -0
  393. package/docs/ru/intlayer_with_tanstack.md +4 -0
  394. package/docs/ru/intlayer_with_vite+react.md +4 -0
  395. package/docs/tr/component_i18n.md +1 -1
  396. package/docs/tr/configuration.md +6 -0
  397. package/docs/tr/intlayer_cli.md +8 -0
  398. package/docs/tr/intlayer_with_next-i18next.md +627 -0
  399. package/docs/tr/intlayer_with_next-intl.md +446 -0
  400. package/docs/tr/intlayer_with_nextjs_16.md +21 -0
  401. package/docs/tr/intlayer_with_tanstack.md +4 -0
  402. package/docs/tr/intlayer_with_vite+react.md +4 -0
  403. package/docs/vi/CI_CD.md +198 -0
  404. package/docs/vi/autoFill.md +284 -0
  405. package/docs/vi/component_i18n.md +186 -0
  406. package/docs/vi/configuration.md +710 -0
  407. package/docs/vi/dictionary/condition.md +237 -0
  408. package/docs/vi/dictionary/content_file.md +1115 -0
  409. package/docs/vi/dictionary/enumeration.md +255 -0
  410. package/docs/vi/dictionary/file.md +234 -0
  411. package/docs/vi/dictionary/function_fetching.md +212 -0
  412. package/docs/vi/dictionary/gender.md +275 -0
  413. package/docs/vi/dictionary/insertion.md +191 -0
  414. package/docs/vi/dictionary/markdown.md +381 -0
  415. package/docs/vi/dictionary/nesting.md +273 -0
  416. package/docs/vi/dictionary/translation.md +309 -0
  417. package/docs/vi/formatters.md +595 -0
  418. package/docs/vi/how_works_intlayer.md +256 -0
  419. package/docs/vi/index.md +174 -0
  420. package/docs/vi/interest_of_intlayer.md +292 -0
  421. package/docs/vi/intlayer_CMS.md +549 -0
  422. package/docs/vi/intlayer_cli.md +850 -0
  423. package/docs/vi/intlayer_visual_editor.md +288 -0
  424. package/docs/vi/intlayer_with_angular.md +692 -0
  425. package/docs/vi/intlayer_with_astro.md +252 -0
  426. package/docs/vi/intlayer_with_create_react_app.md +1230 -0
  427. package/docs/vi/intlayer_with_express.md +409 -0
  428. package/docs/vi/intlayer_with_lynx+react.md +520 -0
  429. package/docs/vi/intlayer_with_nestjs.md +272 -0
  430. package/docs/vi/intlayer_with_next-i18next.md +628 -0
  431. package/docs/vi/intlayer_with_next-intl.md +446 -0
  432. package/docs/vi/intlayer_with_nextjs_14.md +1584 -0
  433. package/docs/vi/intlayer_with_nextjs_15.md +1738 -0
  434. package/docs/vi/intlayer_with_nextjs_16.md +21 -0
  435. package/docs/vi/intlayer_with_nextjs_page_router.md +1504 -0
  436. package/docs/vi/intlayer_with_nuxt.md +821 -0
  437. package/docs/vi/intlayer_with_react_native+expo.md +700 -0
  438. package/docs/vi/intlayer_with_react_router_v7.md +498 -0
  439. package/docs/vi/intlayer_with_tanstack.md +562 -0
  440. package/docs/vi/intlayer_with_vite+preact.md +1722 -0
  441. package/docs/vi/intlayer_with_vite+react.md +1407 -0
  442. package/docs/vi/intlayer_with_vite+solid.md +287 -0
  443. package/docs/vi/intlayer_with_vite+svelte.md +289 -0
  444. package/docs/vi/intlayer_with_vite+vue.md +1071 -0
  445. package/docs/vi/introduction.md +215 -0
  446. package/docs/vi/locale_mapper.md +242 -0
  447. package/docs/vi/mcp_server.md +211 -0
  448. package/docs/vi/packages/express-intlayer/t.md +457 -0
  449. package/docs/vi/packages/intlayer/getConfiguration.md +145 -0
  450. package/docs/vi/packages/intlayer/getEnumeration.md +162 -0
  451. package/docs/vi/packages/intlayer/getHTMLTextDir.md +121 -0
  452. package/docs/vi/packages/intlayer/getLocaleLang.md +81 -0
  453. package/docs/vi/packages/intlayer/getLocaleName.md +129 -0
  454. package/docs/vi/packages/intlayer/getLocalizedUrl.md +309 -0
  455. package/docs/vi/packages/intlayer/getMultilingualUrls.md +221 -0
  456. package/docs/vi/packages/intlayer/getPathWithoutLocale.md +75 -0
  457. package/docs/vi/packages/intlayer/getTranslation.md +201 -0
  458. package/docs/vi/packages/intlayer/getTranslationContent.md +188 -0
  459. package/docs/vi/packages/next-intlayer/t.md +352 -0
  460. package/docs/vi/packages/next-intlayer/useDictionary.md +273 -0
  461. package/docs/vi/packages/next-intlayer/useIntlayer.md +264 -0
  462. package/docs/vi/packages/next-intlayer/useLocale.md +166 -0
  463. package/docs/vi/packages/react-intlayer/t.md +304 -0
  464. package/docs/vi/packages/react-intlayer/useDictionary.md +288 -0
  465. package/docs/vi/packages/react-intlayer/useI18n.md +295 -0
  466. package/docs/vi/packages/react-intlayer/useIntlayer.md +256 -0
  467. package/docs/vi/packages/react-intlayer/useLocale.md +210 -0
  468. package/docs/vi/per_locale_file.md +326 -0
  469. package/docs/vi/readme.md +261 -0
  470. package/docs/vi/releases/v6.md +305 -0
  471. package/docs/vi/roadmap.md +346 -0
  472. package/docs/vi/testing.md +202 -0
  473. package/docs/vi/vs_code_extension.md +126 -0
  474. package/docs/zh/configuration.md +6 -0
  475. package/docs/zh/intlayer_cli.md +8 -3
  476. package/docs/zh/intlayer_with_next-i18next.md +628 -0
  477. package/docs/zh/intlayer_with_next-intl.md +448 -0
  478. package/docs/zh/intlayer_with_nextjs_16.md +21 -0
  479. package/docs/zh/intlayer_with_tanstack.md +4 -0
  480. package/docs/zh/intlayer_with_vite+react.md +4 -0
  481. package/frequent_questions/ar/SSR_Next_no_[locale].md +1 -2
  482. package/frequent_questions/ar/array_as_content_declaration.md +1 -2
  483. package/frequent_questions/ar/build_dictionaries.md +1 -2
  484. package/frequent_questions/ar/build_error_CI_CD.md +1 -2
  485. package/frequent_questions/ar/bun_set_up.md +1 -2
  486. package/frequent_questions/ar/customized_locale_list.md +1 -2
  487. package/frequent_questions/ar/domain_routing.md +1 -2
  488. package/frequent_questions/ar/esbuild_error.md +1 -2
  489. package/frequent_questions/ar/get_locale_cookie.md +1 -2
  490. package/frequent_questions/ar/intlayer_command_undefined.md +1 -2
  491. package/frequent_questions/ar/locale_incorect_in_url.md +1 -2
  492. package/frequent_questions/ar/static_rendering.md +1 -3
  493. package/frequent_questions/ar/translated_path_url.md +1 -2
  494. package/frequent_questions/ar/unknown_command.md +1 -2
  495. package/frequent_questions/de/SSR_Next_no_[locale].md +1 -2
  496. package/frequent_questions/de/array_as_content_declaration.md +1 -2
  497. package/frequent_questions/de/build_dictionaries.md +1 -2
  498. package/frequent_questions/de/build_error_CI_CD.md +1 -2
  499. package/frequent_questions/de/bun_set_up.md +1 -2
  500. package/frequent_questions/de/customized_locale_list.md +1 -2
  501. package/frequent_questions/de/domain_routing.md +1 -2
  502. package/frequent_questions/de/esbuild_error.md +1 -2
  503. package/frequent_questions/de/get_locale_cookie.md +1 -2
  504. package/frequent_questions/de/intlayer_command_undefined.md +1 -2
  505. package/frequent_questions/de/locale_incorect_in_url.md +1 -2
  506. package/frequent_questions/de/static_rendering.md +1 -3
  507. package/frequent_questions/de/translated_path_url.md +1 -2
  508. package/frequent_questions/de/unknown_command.md +1 -2
  509. package/frequent_questions/en/SSR_Next_no_[locale].md +1 -2
  510. package/frequent_questions/en/array_as_content_declaration.md +1 -2
  511. package/frequent_questions/en/build_dictionaries.md +1 -2
  512. package/frequent_questions/en/build_error_CI_CD.md +1 -2
  513. package/frequent_questions/en/bun_set_up.md +1 -2
  514. package/frequent_questions/en/customized_locale_list.md +1 -2
  515. package/frequent_questions/en/domain_routing.md +1 -2
  516. package/frequent_questions/en/esbuild_error.md +1 -2
  517. package/frequent_questions/en/get_locale_cookie.md +1 -2
  518. package/frequent_questions/en/intlayer_command_undefined.md +1 -2
  519. package/frequent_questions/en/locale_incorect_in_url.md +1 -2
  520. package/frequent_questions/en/static_rendering.md +1 -3
  521. package/frequent_questions/en/translated_path_url.md +1 -2
  522. package/frequent_questions/en/unknown_command.md +1 -2
  523. package/frequent_questions/en-GB/SSR_Next_no_[locale].md +1 -2
  524. package/frequent_questions/en-GB/array_as_content_declaration.md +1 -2
  525. package/frequent_questions/en-GB/build_dictionaries.md +1 -2
  526. package/frequent_questions/en-GB/build_error_CI_CD.md +1 -2
  527. package/frequent_questions/en-GB/bun_set_up.md +1 -2
  528. package/frequent_questions/en-GB/customized_locale_list.md +1 -2
  529. package/frequent_questions/en-GB/domain_routing.md +1 -2
  530. package/frequent_questions/en-GB/esbuild_error.md +1 -2
  531. package/frequent_questions/en-GB/get_locale_cookie.md +1 -2
  532. package/frequent_questions/en-GB/intlayer_command_undefined.md +1 -2
  533. package/frequent_questions/en-GB/locale_incorect_in_url.md +1 -2
  534. package/frequent_questions/en-GB/static_rendering.md +1 -3
  535. package/frequent_questions/en-GB/translated_path_url.md +1 -2
  536. package/frequent_questions/en-GB/unknown_command.md +1 -2
  537. package/frequent_questions/es/SSR_Next_no_[locale].md +1 -2
  538. package/frequent_questions/es/array_as_content_declaration.md +1 -2
  539. package/frequent_questions/es/build_dictionaries.md +1 -2
  540. package/frequent_questions/es/build_error_CI_CD.md +1 -2
  541. package/frequent_questions/es/bun_set_up.md +1 -2
  542. package/frequent_questions/es/customized_locale_list.md +1 -2
  543. package/frequent_questions/es/domain_routing.md +1 -2
  544. package/frequent_questions/es/esbuild_error.md +1 -2
  545. package/frequent_questions/es/get_locale_cookie.md +1 -2
  546. package/frequent_questions/es/intlayer_command_undefined.md +1 -2
  547. package/frequent_questions/es/locale_incorect_in_url.md +1 -2
  548. package/frequent_questions/es/static_rendering.md +1 -3
  549. package/frequent_questions/es/translated_path_url.md +1 -2
  550. package/frequent_questions/es/unknown_command.md +1 -2
  551. package/frequent_questions/fr/SSR_Next_no_[locale].md +1 -2
  552. package/frequent_questions/fr/array_as_content_declaration.md +1 -2
  553. package/frequent_questions/fr/build_dictionaries.md +1 -2
  554. package/frequent_questions/fr/build_error_CI_CD.md +1 -2
  555. package/frequent_questions/fr/bun_set_up.md +1 -2
  556. package/frequent_questions/fr/customized_locale_list.md +1 -2
  557. package/frequent_questions/fr/domain_routing.md +1 -2
  558. package/frequent_questions/fr/esbuild_error.md +1 -2
  559. package/frequent_questions/fr/get_locale_cookie.md +1 -2
  560. package/frequent_questions/fr/intlayer_command_undefined.md +1 -2
  561. package/frequent_questions/fr/locale_incorect_in_url.md +1 -2
  562. package/frequent_questions/fr/static_rendering.md +1 -3
  563. package/frequent_questions/fr/translated_path_url.md +1 -2
  564. package/frequent_questions/fr/unknown_command.md +1 -2
  565. package/frequent_questions/hi/SSR_Next_no_[locale].md +1 -2
  566. package/frequent_questions/hi/array_as_content_declaration.md +1 -2
  567. package/frequent_questions/hi/build_dictionaries.md +1 -2
  568. package/frequent_questions/hi/build_error_CI_CD.md +1 -2
  569. package/frequent_questions/hi/bun_set_up.md +1 -2
  570. package/frequent_questions/hi/customized_locale_list.md +1 -2
  571. package/frequent_questions/hi/domain_routing.md +1 -2
  572. package/frequent_questions/hi/esbuild_error.md +1 -2
  573. package/frequent_questions/hi/get_locale_cookie.md +1 -2
  574. package/frequent_questions/hi/intlayer_command_undefined.md +1 -2
  575. package/frequent_questions/hi/locale_incorect_in_url.md +1 -2
  576. package/frequent_questions/hi/static_rendering.md +1 -3
  577. package/frequent_questions/hi/translated_path_url.md +1 -2
  578. package/frequent_questions/hi/unknown_command.md +1 -2
  579. package/frequent_questions/id/SSR_Next_no_[locale].md +104 -0
  580. package/frequent_questions/id/array_as_content_declaration.md +71 -0
  581. package/frequent_questions/id/build_dictionaries.md +58 -0
  582. package/frequent_questions/id/build_error_CI_CD.md +74 -0
  583. package/frequent_questions/id/bun_set_up.md +53 -0
  584. package/frequent_questions/id/customized_locale_list.md +64 -0
  585. package/frequent_questions/id/domain_routing.md +113 -0
  586. package/frequent_questions/id/esbuild_error.md +29 -0
  587. package/frequent_questions/id/get_locale_cookie.md +142 -0
  588. package/frequent_questions/id/intlayer_command_undefined.md +155 -0
  589. package/frequent_questions/id/locale_incorect_in_url.md +73 -0
  590. package/frequent_questions/id/static_rendering.md +44 -0
  591. package/frequent_questions/id/translated_path_url.md +55 -0
  592. package/frequent_questions/id/unknown_command.md +97 -0
  593. package/frequent_questions/it/SSR_Next_no_[locale].md +1 -2
  594. package/frequent_questions/it/array_as_content_declaration.md +1 -2
  595. package/frequent_questions/it/build_dictionaries.md +1 -2
  596. package/frequent_questions/it/build_error_CI_CD.md +1 -2
  597. package/frequent_questions/it/bun_set_up.md +1 -2
  598. package/frequent_questions/it/customized_locale_list.md +1 -2
  599. package/frequent_questions/it/domain_routing.md +1 -2
  600. package/frequent_questions/it/esbuild_error.md +1 -2
  601. package/frequent_questions/it/get_locale_cookie.md +1 -2
  602. package/frequent_questions/it/intlayer_command_undefined.md +1 -2
  603. package/frequent_questions/it/locale_incorect_in_url.md +1 -2
  604. package/frequent_questions/it/static_rendering.md +1 -3
  605. package/frequent_questions/it/translated_path_url.md +1 -2
  606. package/frequent_questions/it/unknown_command.md +1 -2
  607. package/frequent_questions/ja/SSR_Next_no_[locale].md +1 -2
  608. package/frequent_questions/ja/array_as_content_declaration.md +1 -2
  609. package/frequent_questions/ja/build_dictionaries.md +1 -2
  610. package/frequent_questions/ja/build_error_CI_CD.md +1 -2
  611. package/frequent_questions/ja/bun_set_up.md +1 -2
  612. package/frequent_questions/ja/customized_locale_list.md +1 -2
  613. package/frequent_questions/ja/domain_routing.md +1 -2
  614. package/frequent_questions/ja/esbuild_error.md +1 -2
  615. package/frequent_questions/ja/get_locale_cookie.md +1 -2
  616. package/frequent_questions/ja/intlayer_command_undefined.md +1 -2
  617. package/frequent_questions/ja/locale_incorect_in_url.md +1 -2
  618. package/frequent_questions/ja/static_rendering.md +1 -3
  619. package/frequent_questions/ja/translated_path_url.md +1 -2
  620. package/frequent_questions/ja/unknown_command.md +1 -2
  621. package/frequent_questions/ko/SSR_Next_no_[locale].md +1 -2
  622. package/frequent_questions/ko/array_as_content_declaration.md +1 -2
  623. package/frequent_questions/ko/build_dictionaries.md +1 -2
  624. package/frequent_questions/ko/build_error_CI_CD.md +1 -2
  625. package/frequent_questions/ko/bun_set_up.md +1 -2
  626. package/frequent_questions/ko/customized_locale_list.md +1 -2
  627. package/frequent_questions/ko/domain_routing.md +1 -2
  628. package/frequent_questions/ko/esbuild_error.md +1 -2
  629. package/frequent_questions/ko/get_locale_cookie.md +1 -2
  630. package/frequent_questions/ko/intlayer_command_undefined.md +1 -2
  631. package/frequent_questions/ko/locale_incorect_in_url.md +1 -2
  632. package/frequent_questions/ko/static_rendering.md +1 -3
  633. package/frequent_questions/ko/translated_path_url.md +1 -2
  634. package/frequent_questions/ko/unknown_command.md +1 -2
  635. package/frequent_questions/pl/SSR_Next_no_[locale].md +104 -0
  636. package/frequent_questions/pl/array_as_content_declaration.md +71 -0
  637. package/frequent_questions/pl/build_dictionaries.md +58 -0
  638. package/frequent_questions/pl/build_error_CI_CD.md +74 -0
  639. package/frequent_questions/pl/bun_set_up.md +54 -0
  640. package/frequent_questions/pl/customized_locale_list.md +64 -0
  641. package/frequent_questions/pl/domain_routing.md +113 -0
  642. package/frequent_questions/pl/esbuild_error.md +29 -0
  643. package/frequent_questions/pl/get_locale_cookie.md +142 -0
  644. package/frequent_questions/pl/intlayer_command_undefined.md +155 -0
  645. package/frequent_questions/pl/locale_incorect_in_url.md +73 -0
  646. package/frequent_questions/pl/static_rendering.md +44 -0
  647. package/frequent_questions/pl/translated_path_url.md +55 -0
  648. package/frequent_questions/pl/unknown_command.md +97 -0
  649. package/frequent_questions/pt/SSR_Next_no_[locale].md +1 -2
  650. package/frequent_questions/pt/array_as_content_declaration.md +1 -2
  651. package/frequent_questions/pt/build_dictionaries.md +1 -2
  652. package/frequent_questions/pt/build_error_CI_CD.md +1 -2
  653. package/frequent_questions/pt/bun_set_up.md +1 -2
  654. package/frequent_questions/pt/customized_locale_list.md +1 -2
  655. package/frequent_questions/pt/domain_routing.md +1 -2
  656. package/frequent_questions/pt/esbuild_error.md +1 -2
  657. package/frequent_questions/pt/get_locale_cookie.md +1 -2
  658. package/frequent_questions/pt/intlayer_command_undefined.md +1 -2
  659. package/frequent_questions/pt/locale_incorect_in_url.md +1 -2
  660. package/frequent_questions/pt/static_rendering.md +1 -3
  661. package/frequent_questions/pt/translated_path_url.md +1 -2
  662. package/frequent_questions/pt/unknown_command.md +1 -2
  663. package/frequent_questions/ru/SSR_Next_no_[locale].md +1 -2
  664. package/frequent_questions/ru/array_as_content_declaration.md +1 -2
  665. package/frequent_questions/ru/build_dictionaries.md +1 -2
  666. package/frequent_questions/ru/build_error_CI_CD.md +1 -2
  667. package/frequent_questions/ru/bun_set_up.md +1 -2
  668. package/frequent_questions/ru/customized_locale_list.md +1 -2
  669. package/frequent_questions/ru/domain_routing.md +1 -2
  670. package/frequent_questions/ru/esbuild_error.md +1 -2
  671. package/frequent_questions/ru/get_locale_cookie.md +1 -2
  672. package/frequent_questions/ru/intlayer_command_undefined.md +1 -2
  673. package/frequent_questions/ru/locale_incorect_in_url.md +1 -2
  674. package/frequent_questions/ru/static_rendering.md +1 -2
  675. package/frequent_questions/ru/translated_path_url.md +1 -2
  676. package/frequent_questions/ru/unknown_command.md +1 -2
  677. package/frequent_questions/tr/SSR_Next_no_[locale].md +1 -2
  678. package/frequent_questions/tr/array_as_content_declaration.md +1 -2
  679. package/frequent_questions/tr/build_dictionaries.md +1 -2
  680. package/frequent_questions/tr/build_error_CI_CD.md +1 -2
  681. package/frequent_questions/tr/bun_set_up.md +1 -2
  682. package/frequent_questions/tr/customized_locale_list.md +1 -2
  683. package/frequent_questions/tr/domain_routing.md +1 -2
  684. package/frequent_questions/tr/esbuild_error.md +1 -2
  685. package/frequent_questions/tr/get_locale_cookie.md +1 -2
  686. package/frequent_questions/tr/intlayer_command_undefined.md +1 -2
  687. package/frequent_questions/tr/locale_incorect_in_url.md +1 -2
  688. package/frequent_questions/tr/static_rendering.md +1 -2
  689. package/frequent_questions/tr/translated_path_url.md +1 -2
  690. package/frequent_questions/tr/unknown_command.md +1 -2
  691. package/frequent_questions/vi/SSR_Next_no_[locale].md +106 -0
  692. package/frequent_questions/vi/array_as_content_declaration.md +71 -0
  693. package/frequent_questions/vi/build_dictionaries.md +58 -0
  694. package/frequent_questions/vi/build_error_CI_CD.md +74 -0
  695. package/frequent_questions/vi/bun_set_up.md +53 -0
  696. package/frequent_questions/vi/customized_locale_list.md +64 -0
  697. package/frequent_questions/vi/domain_routing.md +113 -0
  698. package/frequent_questions/vi/esbuild_error.md +29 -0
  699. package/frequent_questions/vi/get_locale_cookie.md +142 -0
  700. package/frequent_questions/vi/intlayer_command_undefined.md +155 -0
  701. package/frequent_questions/vi/locale_incorect_in_url.md +73 -0
  702. package/frequent_questions/vi/static_rendering.md +44 -0
  703. package/frequent_questions/vi/translated_path_url.md +55 -0
  704. package/frequent_questions/vi/unknown_command.md +97 -0
  705. package/frequent_questions/zh/SSR_Next_no_[locale].md +1 -2
  706. package/frequent_questions/zh/array_as_content_declaration.md +1 -2
  707. package/frequent_questions/zh/build_dictionaries.md +1 -2
  708. package/frequent_questions/zh/build_error_CI_CD.md +1 -2
  709. package/frequent_questions/zh/bun_set_up.md +1 -2
  710. package/frequent_questions/zh/customized_locale_list.md +1 -2
  711. package/frequent_questions/zh/domain_routing.md +1 -2
  712. package/frequent_questions/zh/esbuild_error.md +1 -2
  713. package/frequent_questions/zh/get_locale_cookie.md +1 -2
  714. package/frequent_questions/zh/intlayer_command_undefined.md +1 -2
  715. package/frequent_questions/zh/locale_incorect_in_url.md +1 -2
  716. package/frequent_questions/zh/static_rendering.md +1 -3
  717. package/frequent_questions/zh/translated_path_url.md +1 -2
  718. package/frequent_questions/zh/unknown_command.md +1 -2
  719. package/legal/id/privacy_notice.md +83 -0
  720. package/legal/id/terms_of_service.md +55 -0
  721. package/legal/pl/privacy_notice.md +83 -0
  722. package/legal/pl/terms_of_service.md +55 -0
  723. package/legal/vi/privacy_notice.md +83 -0
  724. package/legal/vi/terms_of_service.md +55 -0
  725. package/package.json +19 -18
  726. package/src/generated/blog.entry.ts +38 -0
@@ -0,0 +1,1078 @@
1
+ ---
2
+ createdAt: 2025-11-01
3
+ updatedAt: 2025-11-01
4
+ title: Comment internationaliser votre application Next.js avec next-i18next
5
+ description: Configurez l'i18n avec next-i18next : meilleures pratiques et conseils SEO pour les applications Next.js multilingues, couvrant l'internationalisation, l'organisation du contenu et la configuration technique.
6
+ slugs:
7
+ - blog
8
+ - nextjs-internationalization-using-next-i18next
9
+ applicationTemplate: https://github.com/aymericzip/next-i18next-template
10
+ history:
11
+ - version: 7.0.6
12
+ date: 2025-11-01
13
+ changes: Version initiale
14
+ ---
15
+
16
+ # Comment internationaliser votre application Next.js avec next-i18next en 2025
17
+
18
+ ## Table des matières
19
+
20
+ <TOC/>
21
+
22
+ ## Qu'est-ce que next-i18next ?
23
+
24
+ **next-i18next** est une solution d'internationalisation (i18n) populaire pour les applications Next.js. Alors que le package original `next-i18next` était conçu pour le Pages Router, ce guide vous montre comment implémenter i18next avec le moderne **App Router** en utilisant directement `i18next` et `react-i18next`.
25
+
26
+ Avec cette approche, vous pouvez :
27
+
28
+ - **Organiser les traductions** en utilisant des namespaces (par exemple, `common.json`, `about.json`) pour une meilleure gestion du contenu.
29
+ - **Charger les traductions efficacement** en ne chargeant que les namespaces nécessaires pour chaque page, réduisant ainsi la taille du bundle.
30
+ - **Supporter à la fois les composants serveur et client** avec une gestion appropriée du SSR et de l'hydratation.
31
+ - **Assurer le support TypeScript** avec une configuration locale et des clés de traduction typées en toute sécurité.
32
+ - **Optimiser pour le SEO** avec une internationalisation appropriée des métadonnées, sitemap et robots.txt.
33
+
34
+ > En alternative, vous pouvez également vous référer au [guide next-intl](https://github.com/aymericzip/intlayer/blob/main/docs/blog/fr/i18n_using_next-intl.md), ou utiliser directement [Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_with_nextjs_16.md).
35
+
36
+ > Voir la comparaison dans [next-i18next vs next-intl vs Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md).
37
+
38
+ ## Pratiques à suivre
39
+
40
+ Avant de plonger dans l'implémentation, voici quelques pratiques que vous devriez suivre :
41
+
42
+ - **Définir les attributs HTML `lang` et `dir`**
43
+ - Dans votre layout, calculez `dir` en utilisant `getLocaleDirection(locale)` et définissez `<html lang={locale} dir={dir}>` pour une accessibilité et un SEO appropriés.
44
+ - **Séparer les messages par namespace**
45
+ Organisez les fichiers JSON par locale et namespace (par exemple, `common.json`, `about.json`) pour ne charger que ce dont vous avez besoin.
46
+ - **Minimiser la charge côté client**
47
+ Sur les pages, envoyez uniquement les namespaces nécessaires à `NextIntlClientProvider` (par exemple, `pick(messages, ['common', 'about'])`).
48
+ - **Préférer les pages statiques**
49
+ Utilisez autant que possible des pages statiques pour de meilleures performances et un meilleur SEO.
50
+ - **I18n dans les composants serveur**
51
+ Les composants serveur, comme les pages ou tous les composants non marqués comme `client`, sont statiques et peuvent être pré-rendus lors de la compilation. Nous devrons donc leur passer les fonctions de traduction en tant que props.
52
+ - **Configurer les types TypeScript**
53
+ - Pour vos locales, assurez la sécurité des types dans toute votre application.
54
+ - **Proxy pour la redirection**
55
+ Utilisez un proxy pour gérer la détection de la locale et le routage, et rediriger l'utilisateur vers l'URL préfixée par la locale appropriée.
56
+ - **Internationalisation de vos métadonnées, sitemap, robots.txt**
57
+ Internationalisez vos métadonnées, sitemap, robots.txt en utilisant la fonction `generateMetadata` fournie par Next.js afin d'assurer une meilleure découverte par les moteurs de recherche dans toutes les locales.
58
+ - **Localiser les liens**
59
+ Localisez les liens en utilisant le composant `Link` pour rediriger l'utilisateur vers l'URL préfixée par la locale appropriée. Il est important d'assurer la découverte de vos pages dans toutes les locales.
60
+ - **Automatiser les tests et les traductions**
61
+ Automatiser les tests et les traductions permet de gagner du temps dans la maintenance de votre application multilingue.
62
+
63
+ > Consultez notre documentation listant tout ce que vous devez savoir sur l'internationalisation et le SEO : [Internationalisation (i18n) avec next-intl](https://github.com/aymericzip/intlayer/blob/main/docs/blog/fr/internationalization_and_SEO.md).
64
+
65
+ ---
66
+
67
+ ## Guide étape par étape pour configurer i18next dans une application Next.js
68
+
69
+ <iframe
70
+ src="https://stackblitz.com/github/aymericzip/next-i18next-template?embed=1&ctl=1&file=src/app/i18n.ts"
71
+ className="m-auto overflow-hidden rounded-lg border-0 max-md:size-full max-md:h-[700px] md:aspect-16/9 md:w-full"
72
+ title="Demo CodeSandbox - Comment internationaliser votre application avec Intlayer"
73
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
74
+ loading="lazy"
75
+
76
+ > Voir [Application Template](https://github.com/aymericzip/next-i18next-template) sur GitHub.
77
+
78
+ Voici la structure du projet que nous allons créer :
79
+
80
+ ```bash
81
+ .
82
+ ├── i18n.config.ts
83
+ └── src # Src est optionnel
84
+ ├── locales
85
+ │ ├── en
86
+ │ │ ├── common.json
87
+ │ │ └── about.json
88
+ │ └── fr
89
+ │ ├── common.json
90
+ │ └── about.json
91
+ ├── types
92
+ │ └── i18next.d.ts
93
+ ├── app
94
+ │ ├── proxy.ts
95
+ │ ├── i18n
96
+ │ │ └── server.ts
97
+ │ └── [locale]
98
+ │ ├── layout.tsx
99
+ │ ├── (home) # / (Groupe de routes pour ne pas polluer toutes les pages avec les messages home)
100
+ │ │ ├── layout.tsx
101
+ │ │ └── page.tsx
102
+ │ └── about # /about
103
+ │ ├── layout.tsx
104
+ │ └── page.tsx
105
+ └── components
106
+ ├── I18nProvider.tsx
107
+ ├── ClientComponent.tsx
108
+ └── ServerComponent.tsx
109
+ ```
110
+
111
+ ### Étape 1 : Installer les dépendances
112
+
113
+ Installez les paquets nécessaires en utilisant npm :
114
+
115
+ ```bash packageManager="npm"
116
+ npm install i18next react-i18next i18next-resources-to-backend
117
+ ```
118
+
119
+ ```bash packageManager="pnpm"
120
+ pnpm add i18next react-i18next i18next-resources-to-backend
121
+ ```
122
+
123
+ ```bash packageManager="yarn"
124
+ yarn add i18next react-i18next i18next-resources-to-backend
125
+ ```
126
+
127
+ - **i18next** : Le framework principal d'internationalisation qui gère le chargement et la gestion des traductions.
128
+ - **react-i18next** : Les bindings React pour i18next qui fournissent des hooks comme `useTranslation` pour les composants clients.
129
+ - **i18next-resources-to-backend** : Un plugin qui permet le chargement dynamique des fichiers de traduction, vous permettant de charger uniquement les namespaces dont vous avez besoin.
130
+
131
+ ### Étape 2 : Configurez votre projet
132
+
133
+ Créez un fichier de configuration pour définir vos locales supportées, la locale par défaut, et des fonctions utilitaires pour la localisation des URLs. Ce fichier sert de source unique de vérité pour votre configuration i18n et garantit la sécurité des types dans toute votre application.
134
+
135
+ Centraliser la configuration des locales évite les incohérences et facilite l'ajout ou la suppression de locales à l'avenir. Les fonctions utilitaires assurent une génération cohérente des URLs pour le SEO et le routage.
136
+
137
+ ```ts fileName="i18n.config.ts"
138
+ // Définir les locales supportées comme un tableau const pour la sécurité des types
139
+ // L'assertion 'as const' permet à TypeScript d'inférer des types littéraux au lieu de string[]
140
+ export const locales = ["en", "fr"] as const;
141
+
142
+ // Extraire le type Locale à partir du tableau locales
143
+ // Cela crée un type union : "en" | "fr"
144
+ export type Locale = (typeof locales)[number];
145
+
146
+ // Définir la locale par défaut utilisée lorsqu'aucune locale n'est spécifiée
147
+ export const defaultLocale: Locale = "en";
148
+
149
+ // Langues de droite à gauche nécessitant une gestion spéciale de la direction du texte
150
+ export const rtlLocales = ["ar", "he", "fa", "ur"] as const;
151
+
152
+ // Vérifie si une locale nécessite une direction de texte RTL (de droite à gauche)
153
+ // Utilisé pour des langues comme l'arabe, l'hébreu, le persan et l'ourdou
154
+ export const isRtl = (locale: string) =>
155
+ (rtlLocales as readonly string[]).includes(locale);
156
+
157
+ // Génère un chemin localisé pour une locale et un chemin donnés
158
+ // Les chemins de la locale par défaut n'ont pas de préfixe (ex. "/about" au lieu de "/en/about")
159
+ // Les autres locales sont préfixées (ex. "/fr/about")
160
+ export function localizedPath(locale: string, path: string) {
161
+ return locale === defaultLocale ? path : `/${locale}${path}`;
162
+ }
163
+
164
+ // URL de base pour les URLs absolues (utilisé dans les sitemaps, métadonnées, etc.)
165
+ const ORIGIN = "https://example.com";
166
+
167
+ // Génère une URL absolue avec le préfixe de la locale
168
+ // Utilisé pour les métadonnées SEO, sitemaps, et URLs canoniques
169
+ export function absoluteUrl(locale: string, path: string) {
170
+ return `${ORIGIN}${localizedPath(locale, path)}`;
171
+ }
172
+
173
+ // Utilisé pour définir le cookie de la locale dans le navigateur
174
+ export function getCookie(locale: Locale) {
175
+ return [
176
+ `NEXT_LOCALE=${locale}`,
177
+ "Path=/",
178
+ `Max-Age=${60 * 60 * 24 * 365}`, // 1 an
179
+ "SameSite=Lax",
180
+ ].join("; ");
181
+ }
182
+ ```
183
+
184
+ ### Étape 3 : Centraliser les espaces de noms de traduction
185
+
186
+ Créez une source unique de vérité pour chaque namespace que votre application expose. Réutiliser cette liste permet de garder le code serveur, client et les outils synchronisés et active une typage fort pour les helpers de traduction.
187
+
188
+ ```ts fileName="src/i18n.namespaces.ts"
189
+ export const namespaces = ["common", "about"] as const;
190
+
191
+ export type Namespace = (typeof namespaces)[number];
192
+ ```
193
+
194
+ ### Étape 4 : Typage fort des clés de traduction avec TypeScript
195
+
196
+ Augmentez `i18next` pour pointer vers vos fichiers de langue canoniques (généralement en anglais). TypeScript en déduit alors les clés valides par namespace, ce qui permet de vérifier les appels à `t()` de bout en bout.
197
+
198
+ ```ts fileName="src/types/i18next.d.ts"
199
+ import "i18next";
200
+
201
+ declare module "i18next" {
202
+ interface CustomTypeOptions {
203
+ defaultNS: "common";
204
+ resources: {
205
+ common: typeof import("@/locales/en/common.json");
206
+ about: typeof import("@/locales/en/about.json");
207
+ };
208
+ }
209
+ }
210
+ ```
211
+
212
+ > Astuce : Stockez cette déclaration sous `src/types` (créez le dossier s'il n'existe pas). Next.js inclut déjà `src` dans `tsconfig.json`, donc l'augmentation est prise en compte automatiquement. Sinon, ajoutez ce qui suit dans votre fichier `tsconfig.json` :
213
+
214
+ ```json5 fileName="tsconfig.json"
215
+ {
216
+ "include": ["src/types/**/*.ts"],
217
+ }
218
+ ```
219
+
220
+ Avec cela en place, vous pouvez compter sur l'autocomplétion et les vérifications à la compilation :
221
+
222
+ ```tsx
223
+ import { useTranslation, type TFunction } from "react-i18next";
224
+
225
+ const { t } = useTranslation("about");
226
+
227
+ // OK, typé : t("counter.increment")
228
+ // ERREUR, erreur de compilation : t("doesNotExist")
229
+ export type AboutTranslator = TFunction<"about">;
230
+ ```
231
+
232
+ ### Étape 5 : Configurer l'initialisation i18n côté serveur
233
+
234
+ Créez une fonction d'initialisation côté serveur qui charge les traductions pour les composants serveur. Cette fonction crée une instance i18next distincte pour le rendu côté serveur, garantissant que les traductions sont chargées avant le rendu.
235
+
236
+ Les composants serveur ont besoin de leur propre instance i18next car ils s'exécutent dans un contexte différent des composants client. Le préchargement des traductions côté serveur évite un affichage fugace de contenu non traduit et améliore le SEO en s'assurant que les moteurs de recherche voient le contenu traduit.
237
+
238
+ ```ts fileName="src/app/i18n/server.ts"
239
+ import { createInstance } from "i18next";
240
+ import { initReactI18next } from "react-i18next/initReactI18next";
241
+ import resourcesToBackend from "i18next-resources-to-backend";
242
+ import { defaultLocale } from "@/i18n.config";
243
+ import { namespaces, type Namespace } from "@/i18n.namespaces";
244
+
245
+ // Configurer le chargement dynamique des ressources pour i18next
246
+ // Cette fonction importe dynamiquement les fichiers JSON de traduction en fonction de la locale et du namespace
247
+ // Exemple : locale="fr", namespace="about" -> importe "@/locales/fr/about.json"
248
+ const backend = resourcesToBackend(
249
+ (locale: string, namespace: string) =>
250
+ import(`@/locales/${locale}/${namespace}.json`)
251
+ );
252
+
253
+ const DEFAULT_NAMESPACES = [
254
+ namespaces[0],
255
+ ] as const satisfies readonly Namespace[];
256
+
257
+ /**
258
+ * Initialiser une instance i18next pour le rendu côté serveur
259
+ *
260
+ * @returns Instance i18next initialisée prête pour une utilisation côté serveur
261
+ */
262
+ export async function initI18next(
263
+ locale: string,
264
+ ns: readonly Namespace[] = DEFAULT_NAMESPACES
265
+ ) {
266
+ // Crée une nouvelle instance i18next (séparée de l'instance côté client)
267
+ const i18n = createInstance();
268
+
269
+ // Initialise avec l'intégration React et le chargeur backend
270
+ await i18n
271
+ .use(initReactI18next) // Active le support des hooks React
272
+ .use(backend) // Active le chargement dynamique des ressources
273
+ .init({
274
+ lng: locale,
275
+ fallbackLng: defaultLocale,
276
+ ns, // Charge uniquement les namespaces spécifiés pour de meilleures performances
277
+ defaultNS: "common", // Namespace par défaut lorsqu'aucun n'est spécifié
278
+ interpolation: { escapeValue: false }, // N'échappe pas le HTML (React gère la protection XSS)
279
+ react: { useSuspense: false }, // Désactive Suspense pour la compatibilité SSR
280
+ returnNull: false, // Retourne une chaîne vide au lieu de null pour les clés manquantes
281
+ initImmediate: false, // Différer l'initialisation jusqu'au chargement des ressources (SSR plus rapide)
282
+ });
283
+ return i18n;
284
+ }
285
+ ```
286
+
287
+ ### Étape 6 : Créer un Provider i18n côté client
288
+
289
+ Créez un provider composant client qui enveloppe votre application avec le contexte i18next. Ce provider reçoit des traductions préchargées depuis le serveur afin d'éviter un flash de contenu non traduit (FOUC) et d'éviter les requêtes en double.
290
+
291
+ Les composants client ont besoin de leur propre instance i18next qui s'exécute dans le navigateur. En acceptant des ressources préchargées depuis le serveur, nous assurons une hydratation fluide et évitons le flash de contenu. Le provider gère également dynamiquement les changements de locale et le chargement des namespaces.
292
+
293
+ ```tsx fileName="src/components/I18nProvider.tsx"
294
+ "use client";
295
+
296
+ import { useEffect, useState } from "react";
297
+ import { I18nextProvider } from "react-i18next";
298
+ import { createInstance, type ResourceLanguage } from "i18next";
299
+ import { initReactI18next } from "react-i18next/initReactI18next";
300
+ import resourcesToBackend from "i18next-resources-to-backend";
301
+ import { defaultLocale } from "@/i18n.config";
302
+ import { namespaces as allNamespaces, type Namespace } from "@/i18n.namespaces";
303
+
304
+ // Configurer le chargement dynamique des ressources côté client
305
+ // Même modèle que côté serveur, mais cette instance s'exécute dans le navigateur
306
+ const backend = resourcesToBackend(
307
+ (locale: string, namespace: string) =>
308
+ import(`@/locales/${locale}/${namespace}.json`)
309
+ );
310
+
311
+ type Props = {
312
+ locale: string;
313
+ namespaces?: readonly Namespace[];
314
+ // Ressources préchargées depuis le serveur (évite le FOUC - Flash of Untranslated Content)
315
+ // Format : { namespace : translationBundle }
316
+ resources?: Record<Namespace, ResourceLanguage>;
317
+ children: React.ReactNode;
318
+ };
319
+
320
+ /**
321
+ * Fournisseur i18n côté client qui enveloppe l'application avec le contexte i18next
322
+ * Reçoit les ressources préchargées depuis le serveur pour éviter de recharger les traductions
323
+ */
324
+ export default function I18nProvider({
325
+ locale,
326
+ namespaces = [allNamespaces[0]] as const,
327
+ resources,
328
+ children,
329
+ }: Props) {
330
+ // Crée une instance i18n une seule fois en utilisant l'initialiseur lazy de useState
331
+ // Cela garantit que l'instance est créée une seule fois, pas à chaque rendu
332
+ const [i18n] = useState(() => {
333
+ const i18nInstance = createInstance();
334
+
335
+ i18nInstance
336
+ .use(initReactI18next)
337
+ .use(backend)
338
+ .init({
339
+ lng: locale,
340
+ fallbackLng: defaultLocale,
341
+ ns: namespaces,
342
+ // Si des ressources sont fournies (depuis le serveur), les utiliser pour éviter un chargement côté client
343
+ // Cela prévient le FOUC et améliore la performance du chargement initial
344
+ resources: resources ? { [locale]: resources } : undefined,
345
+ defaultNS: "common",
346
+ interpolation: { escapeValue: false },
347
+ react: { useSuspense: false },
348
+ returnNull: false, // Empêche le retour de valeurs indéfinies
349
+ });
350
+
351
+ return i18nInstance;
352
+ });
353
+
354
+ // Met à jour la langue lorsque la prop locale change
355
+ useEffect(() => {
356
+ i18n.changeLanguage(locale);
357
+ }, [locale, i18n]);
358
+
359
+ // Assure que tous les namespaces requis sont chargés côté client
360
+ // Utilisation de join("|") comme dépendance pour comparer correctement les tableaux
361
+ useEffect(() => {
362
+ i18n.loadNamespaces(namespaces);
363
+ }, [namespaces.join("|"), i18n]);
364
+
365
+ // Fournir l'instance i18n à tous les composants enfants via le contexte React
366
+ return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;
367
+ }
368
+ ```
369
+
370
+ ### Étape 7 : Définir les routes dynamiques pour les locales
371
+
372
+ Configurez le routage dynamique pour les locales en créant un répertoire `[locale]` dans votre dossier app. Cela permet à Next.js de gérer le routage basé sur la locale où chaque locale devient un segment d'URL (par exemple, `/en/about`, `/fr/about`).
373
+
374
+ L'utilisation de routes dynamiques permet à Next.js de générer des pages statiques pour toutes les locales au moment de la compilation, améliorant ainsi les performances et le SEO. Le composant layout définit les attributs HTML `lang` et `dir` en fonction de la locale, ce qui est crucial pour l'accessibilité et la compréhension par les moteurs de recherche.
375
+
376
+ ```tsx fileName="src/app/[locale]/layout.tsx"
377
+ import type { ReactNode } from "react";
378
+ import { locales, defaultLocale, isRtl, type Locale } from "@/i18n.config";
379
+
380
+ // Désactiver les paramètres dynamiques - toutes les locales doivent être connues au moment de la compilation
381
+ // Cela garantit la génération statique pour toutes les routes de locales
382
+ export const dynamicParams = false;
383
+
384
+ /**
385
+ * Génère des paramètres statiques pour toutes les locales au moment de la compilation
386
+ * Next.js pré-rendra les pages pour chaque locale retournée ici
387
+ * Exemple : [{ locale: "en" }, { locale: "fr" }]
388
+ */
389
+ export function generateStaticParams() {
390
+ return locales.map((locale) => ({ locale }));
391
+ }
392
+
393
+ /**
394
+ * Composant de layout racine qui gère les attributs HTML spécifiques à la locale
395
+ * Définit l'attribut lang et la direction du texte (ltr/rtl) en fonction de la locale
396
+ */
397
+ export default function LocaleLayout({
398
+ children,
399
+ params,
400
+ }: {
401
+ children: ReactNode;
402
+ params: { locale: string };
403
+ }) {
404
+ // Valider la locale à partir des paramètres de l'URL
405
+ // Si une locale invalide est fournie, revenir à la locale par défaut
406
+ const locale: Locale = (locales as readonly string[]).includes(params.locale)
407
+ ? (params.locale as any)
408
+ : defaultLocale;
409
+
410
+ // Déterminer la direction du texte en fonction de la locale
411
+ // Les langues RTL comme l'arabe nécessitent dir="rtl" pour un rendu correct du texte
412
+ const dir = isRtl(locale) ? "rtl" : "ltr";
413
+
414
+ return (
415
+ <html lang={locale} dir={dir}>
416
+ <body>{children}</body>
417
+ </html>
418
+ );
419
+ }
420
+ ```
421
+
422
+ ### Étape 8 : Créez vos fichiers de traduction
423
+
424
+ Créez des fichiers JSON pour chaque locale et namespace. Cette structure vous permet d'organiser les traductions de manière logique et de ne charger que ce dont vous avez besoin pour chaque page.
425
+
426
+ Organiser les traductions par namespace (par exemple, `common.json`, `about.json`) permet le découpage du code (code splitting) et réduit la taille du bundle. Vous ne chargez que les traductions nécessaires pour chaque page, ce qui améliore les performances.
427
+
428
+ ```json fileName="src/locales/en/common.json"
429
+ {
430
+ "appTitle": "Next.js i18n App",
431
+ "appDescription": "Example Next.js application with internationalization using i18next"
432
+ }
433
+ ```
434
+
435
+ ```json fileName="src/locales/fr/common.json"
436
+ {
437
+ "appTitle": "Application Next.js i18n",
438
+ "appDescription": "Exemple d'application Next.js avec internationalisation utilisant i18next"
439
+ }
440
+ ```
441
+
442
+ ```json fileName="src/locales/en/home.json"
443
+ {
444
+ "title": "Home",
445
+ "description": "Home page description",
446
+ "welcome": "Welcome",
447
+ "greeting": "Hello, world!",
448
+ "aboutPage": "About Page",
449
+ "documentation": "Documentation"
450
+ }
451
+ ```
452
+
453
+ ```json fileName="src/locales/fr/home.json"
454
+ {
455
+ "title": "Accueil",
456
+ "description": "Description de la page d'accueil",
457
+ "welcome": "Bienvenue",
458
+ "greeting": "Bonjour le monde!",
459
+ "aboutPage": "Page À propos",
460
+ "documentation": "Documentation"
461
+ }
462
+ ```
463
+
464
+ ```json fileName="src/locales/en/about.json"
465
+ {
466
+ "title": "About",
467
+ "description": "About page description",
468
+ "counter": {
469
+ "label": "Counter",
470
+ "increment": "Increment",
471
+ "description": "Click the button to increase the counter"
472
+ }
473
+ }
474
+ ```
475
+
476
+ ```json fileName="src/locales/fr/about.json"
477
+ {
478
+ "title": "À propos",
479
+ "description": "Description de la page À propos",
480
+ "counter": {
481
+ "label": "Compteur",
482
+ "increment": "Incrémenter",
483
+ "description": "Cliquez sur le bouton pour augmenter le compteur"
484
+ }
485
+ }
486
+ ```
487
+
488
+ ### Étape 9 : Utiliser les traductions dans vos pages
489
+
490
+ Créez un composant de page qui initialise i18next côté serveur et transmet les traductions aux composants serveur et client. Cela garantit que les traductions sont chargées avant le rendu et évite les clignotements de contenu.
491
+
492
+ L'initialisation côté serveur charge les traductions avant que la page ne soit rendue, améliorant ainsi le SEO et évitant le FOUC (Flash Of Unstyled Content). En passant les ressources préchargées au fournisseur client, on évite les requêtes redondantes et on assure une hydratation fluide.
493
+
494
+ ```tsx fileName="src/app/[locale]/about/index.tsx"
495
+ import I18nProvider from "@/components/I18nProvider";
496
+ import { initI18next } from "@/app/i18n/server";
497
+ import type { Locale } from "@/i18n.config";
498
+ import { namespaces as allNamespaces, type Namespace } from "@/i18n.namespaces";
499
+ import type { ResourceLanguage } from "i18next";
500
+ import ClientComponent from "@/components/ClientComponent";
501
+ import ServerComponent from "@/components/ServerComponent";
502
+
503
+ /**
504
+ * Composant serveur de la page qui gère l'initialisation de i18n
505
+ * Précharge les traductions côté serveur et les transmet aux composants clients
506
+ */
507
+ export default async function AboutPage({
508
+ params: { locale },
509
+ }: {
510
+ params: { locale: Locale };
511
+ }) {
512
+ // Définir les namespaces de traduction nécessaires pour cette page
513
+ // Réutiliser la liste centralisée pour la sécurité de type et l'autocomplétion
514
+ const pageNamespaces = allNamespaces;
515
+
516
+ // Initialiser i18next côté serveur avec les namespaces requis
517
+ // Cela charge les fichiers JSON de traduction côté serveur
518
+ const i18n = await initI18next(locale, pageNamespaces);
519
+
520
+ // Obtenir une fonction de traduction fixe pour l'espace de noms "about"
521
+ // getFixedT verrouille l'espace de noms, donc t("title") au lieu de t("about:title")
522
+ const tAbout = i18n.getFixedT(locale, "about");
523
+
524
+ // Extraire les bundles de traduction de l'instance i18n
525
+ // Ces données sont passées à I18nProvider pour hydrater l'i18n côté client
526
+ // Évite le FOUC (Flash of Untranslated Content) et empêche les requêtes en double
527
+ const resources = Object.fromEntries(
528
+ pageNamespaces.map((ns) => [ns, i18n.getResourceBundle(locale, ns)])
529
+ ) satisfies Record<Namespace, ResourceLanguage>;
530
+
531
+ return (
532
+ <I18nProvider
533
+ locale={locale}
534
+ namespaces={pageNamespaces}
535
+ resources={resources}
536
+ >
537
+ <main>
538
+ <h1>{tAbout("title")}</h1>
539
+
540
+ <ClientComponent />
541
+ <ServerComponent t={tAbout} locale={locale} count={0} />
542
+ </main>
543
+ </I18nProvider>
544
+ );
545
+ }
546
+ ```
547
+
548
+ ### Étape 10 : Utiliser les traductions dans les composants client
549
+
550
+ Les composants client peuvent utiliser le hook `useTranslation` pour accéder aux traductions. Ce hook fournit l'accès à la fonction de traduction ainsi qu'à l'instance i18n, ce qui vous permet de traduire du contenu et d'accéder aux informations de locale.
551
+
552
+ Les composants client ont besoin des hooks React pour accéder aux traductions. Le hook `useTranslation` s'intègre parfaitement avec i18next et offre des mises à jour réactives lorsque la locale change.
553
+
554
+ > Assurez-vous que la page/le provider inclut uniquement les namespaces dont vous avez besoin (par exemple, `about`).
555
+ > Si vous utilisez React < 19, mémoïsez les formateurs lourds comme `Intl.NumberFormat`.
556
+
557
+ ```tsx fileName="src/components/ClientComponent.tsx"
558
+ "use client";
559
+
560
+ import { useState } from "react";
561
+ import { useTranslation } from "react-i18next";
562
+
563
+ /**
564
+ * Exemple de composant client utilisant les hooks React pour les traductions
565
+ * Peut utiliser des hooks comme useState, useEffect et useTranslation
566
+ */
567
+ const ClientComponent = () => {
568
+ // Le hook useTranslation donne accès à la fonction de traduction et à l'instance i18n
569
+ // Spécifie le namespace pour ne charger que les traductions du namespace "about"
570
+ const { t, i18n } = useTranslation("about");
571
+ const [count, setCount] = useState(0);
572
+
573
+ // Crée un formateur de nombres sensible à la locale
574
+ // i18n.language fournit la locale actuelle (ex : "en", "fr")
575
+ // Intl.NumberFormat formate les nombres selon les conventions de la locale
576
+ const numberFormat = new Intl.NumberFormat(i18n.language);
577
+
578
+ return (
579
+ <div className="flex flex-col items-center gap-4">
580
+ {/* Formater le nombre en utilisant le format spécifique à la locale */}
581
+ <p className="text-5xl font-bold text-white m-0">
582
+ {numberFormat.format(count)}
583
+ </p>
584
+ <button
585
+ type="button"
586
+ className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
587
+ aria-label={t("counter.label")}
588
+ onClick={() => setCount((c) => c + 1)}
589
+ >
590
+ {t("counter.increment")}
591
+ </button>
592
+ </div>
593
+ );
594
+ };
595
+
596
+ export default ClientComponent;
597
+ ```
598
+
599
+ ### Étape 11 : Utiliser les traductions dans les composants serveur
600
+
601
+ Les composants serveur ne peuvent pas utiliser les hooks React, ils reçoivent donc les traductions via les props de leurs composants parents. Cette approche maintient les composants serveur synchrones et permet de les imbriquer à l'intérieur des composants client.
602
+
603
+ Les composants serveur qui pourraient être imbriqués sous des frontières client doivent être synchrones. En passant les chaînes traduites et les informations de locale via les props, nous évitons les opérations asynchrones et assurons un rendu correct.
604
+
605
+ ```tsx fileName="src/components/ServerComponent.tsx"
606
+ import type { TFunction } from "i18next";
607
+
608
+ type ServerComponentProps = {
609
+ // Fonction de traduction passée depuis le composant serveur parent
610
+ // Les composants serveur ne peuvent pas utiliser les hooks, donc les traductions arrivent via les props
611
+ t: TFunction<"about">;
612
+ locale: string;
613
+ count: number;
614
+ };
615
+
616
+ /**
617
+ * Exemple de composant serveur - reçoit les traductions via les props
618
+ * Peut être imbriqué dans des composants client (composants serveur asynchrones)
619
+ * Ne peut pas utiliser les hooks React, donc toutes les données doivent provenir des props ou d'opérations asynchrones
620
+ */
621
+ const ServerComponent = ({ t, locale, count }: ServerComponentProps) => {
622
+ // Formater le nombre côté serveur en utilisant la locale
623
+ // Cela s'exécute sur le serveur lors du SSR, améliorant le chargement initial de la page
624
+ const formatted = new Intl.NumberFormat(locale).format(count);
625
+
626
+ return (
627
+ <div className="flex flex-col items-center gap-4">
628
+ <p className="text-5xl font-bold text-white m-0">{formatted}</p>
629
+ {/* Utiliser la fonction de traduction passée en prop */}
630
+ <div className="flex flex-col items-center gap-2">
631
+ <span className="text-xl font-semibold text-white">
632
+ {t("counter.label")}
633
+ </span>
634
+ <span className="text-sm opacity-80 italic">
635
+ {t("counter.description")}
636
+ </span>
637
+ </div>
638
+ </div>
639
+ );
640
+ };
641
+
642
+ export default ServerComponent;
643
+ ```
644
+
645
+ ---
646
+
647
+ ### (Optionnel) Étape 12 : Changer la langue de votre contenu
648
+
649
+ Pour changer la langue de votre contenu dans Next.js, la méthode recommandée est d'utiliser des URLs préfixées par la locale et les liens Next.js. L'exemple ci-dessous lit la locale actuelle depuis la route, la supprime du pathname, et affiche un lien par locale disponible.
650
+
651
+ ```tsx fileName="src/components/LocaleSwitcher.tsx"
652
+ "use client";
653
+
654
+ import Link from "next/link";
655
+ import { useParams, usePathname } from "next/navigation";
656
+ import { useMemo } from "react";
657
+ import { defaultLocale, getCookie, type Locale, locales } from "@/i18n.config";
658
+
659
+ export default function LocaleSwitcher() {
660
+ const params = useParams();
661
+ const pathname = usePathname();
662
+
663
+ const activeLocale = (params?.locale as Locale | undefined) ?? defaultLocale;
664
+
665
+ const getLocaleLabel = (locale: Locale): string => {
666
+ try {
667
+ const displayNames = new Intl.DisplayNames([locale], {
668
+ type: "language",
669
+ });
670
+ return displayNames.of(locale) ?? locale.toUpperCase();
671
+ } catch {
672
+ return locale.toUpperCase();
673
+ }
674
+ };
675
+
676
+ const basePath = useMemo(() => {
677
+ if (!pathname) return "/";
678
+
679
+ const segments = pathname.split("/").filter(Boolean);
680
+
681
+ if (segments.length === 0) return "/";
682
+
683
+ const maybeLocale = segments[0] as Locale;
684
+
685
+ if ((locales as readonly string[]).includes(maybeLocale)) {
686
+ const rest = segments.slice(1).join("/");
687
+ return rest ? `/${rest}` : "/";
688
+ }
689
+
690
+ return pathname;
691
+ }, [pathname]);
692
+
693
+ return (
694
+ <nav aria-label="Sélecteur de langue">
695
+ {(locales as readonly Locale[]).map((locale) => {
696
+ const isActive = locale === activeLocale;
697
+
698
+ const href =
699
+ locale === defaultLocale ? basePath : `/${locale}${basePath}`;
700
+
701
+ return (
702
+ <Link
703
+ key={locale}
704
+ href={href}
705
+ aria-current={isActive ? "page" : undefined}
706
+ onClick={() => {
707
+ document.cookie = getCookie(locale);
708
+ }}
709
+ >
710
+ {getLocaleLabel(locale)}
711
+ </Link>
712
+ );
713
+ })}
714
+ </nav>
715
+ );
716
+ }
717
+ ```
718
+
719
+ ### (Optionnel) Étape 13 : Construire un composant Link localisé
720
+
721
+ Réutiliser les URLs localisées dans toute votre application permet de garder une navigation cohérente et optimisée pour le SEO. Enveloppez `next/link` dans un petit helper qui préfixe les routes internes avec la locale active tout en laissant les URLs externes intactes.
722
+
723
+ ```tsx fileName="src/components/LocalizedLink.tsx"
724
+ "use client";
725
+
726
+ import NextLink, { type LinkProps } from "next/link";
727
+ import { useParams } from "next/navigation";
728
+ import type { ComponentProps, PropsWithChildren } from "react";
729
+ import {
730
+ defaultLocale,
731
+ type Locale,
732
+ locales,
733
+ localizedPath,
734
+ } from "@/i18n.config";
735
+
736
+ const isExternal = (href: string) => /^https?:\/\//.test(href);
737
+
738
+ type LocalizedLinkProps = PropsWithChildren<
739
+ Omit<LinkProps, "href"> &
740
+ Omit<ComponentProps<"a">, "href"> & { href: string; locale?: Locale }
741
+ >;
742
+
743
+ export default function LocalizedLink({
744
+ href,
745
+ locale,
746
+ children,
747
+ ...props
748
+ }: LocalizedLinkProps) {
749
+ const params = useParams();
750
+ const fallback = (params?.locale as Locale | undefined) ?? defaultLocale;
751
+ const normalizedLocale = (locales as readonly string[]).includes(fallback)
752
+ ? ((locale ?? fallback) as Locale)
753
+ : defaultLocale;
754
+
755
+ const normalizedPath = href.startsWith("/") ? href : `/${href}`;
756
+ const localizedHref = isExternal(href)
757
+ ? href
758
+ : localizedPath(normalizedLocale, normalizedPath);
759
+
760
+ return (
761
+ <NextLink href={localizedHref} {...props}>
762
+ {children}
763
+ </NextLink>
764
+ );
765
+ }
766
+ ```
767
+
768
+ > Astuce : Comme `LocalizedLink` est un remplacement direct, migrez progressivement en échangeant les imports et en laissant le composant gérer les URLs spécifiques à la locale.
769
+
770
+ ### (Optionnel) Étape 14 : Accéder à la locale active dans les Server Actions
771
+
772
+ Les Server Actions ont souvent besoin de la locale courante pour les emails, la journalisation ou les intégrations tierces. Combinez le cookie de locale défini par votre proxy avec l'en-tête `Accept-Language` en tant que solution de secours.
773
+
774
+ ```ts fileName="src/app/actions/get-current-locale.ts"
775
+ "use server";
776
+
777
+ import { cookies, headers } from "next/headers";
778
+ import { defaultLocale, locales, type Locale } from "@/i18n.config";
779
+
780
+ const KNOWN_LOCALES = new Set(locales as readonly string[]);
781
+
782
+ const normalize = (value: string | undefined): Locale | undefined => {
783
+ if (!value) return undefined;
784
+ const base = value.toLowerCase().split("-")[0];
785
+ return KNOWN_LOCALES.has(base) ? (base as Locale) : undefined;
786
+ };
787
+
788
+ export async function getCurrentLocale(): Promise<Locale> {
789
+ const cookieLocale = normalize(cookies().get("NEXT_LOCALE")?.value);
790
+
791
+ if (cookieLocale) return cookieLocale;
792
+
793
+ const headerLocale = normalize(headers().get("accept-language"));
794
+ return headerLocale ?? defaultLocale;
795
+ }
796
+
797
+ // Exemple d'une action serveur qui utilise la locale courante
798
+ export async function stuffFromServer(formData: FormData) {
799
+ const locale = await getCurrentLocale();
800
+
801
+ // Utiliser la locale pour des effets secondaires localisés (emails, CRM, etc.)
802
+ console.log(`Stuff from server with locale ${locale}`);
803
+ }
804
+ ```
805
+
806
+ > Parce que l'assistant s'appuie sur les cookies et les en-têtes de Next.js, il fonctionne dans les Route Handlers, les Server Actions, et d'autres contextes réservés au serveur.
807
+
808
+ ### (Optionnel) Étape 15 : Internationalisez vos métadonnées
809
+
810
+ Traduire le contenu est important, mais l'objectif principal de l'internationalisation est de rendre votre site web plus visible dans le monde. L'i18n est un levier incroyable pour améliorer la visibilité de votre site via un SEO approprié.
811
+
812
+ Des métadonnées correctement internationalisées aident les moteurs de recherche à comprendre quelles langues sont disponibles sur vos pages. Cela inclut la mise en place des balises meta hreflang, la traduction des titres et descriptions, ainsi que la garantie que les URL canoniques sont correctement définies pour chaque locale.
813
+
814
+ Voici une liste de bonnes pratiques concernant le SEO multilingue :
815
+
816
+ - Définissez les balises meta hreflang dans la balise `<head>` pour aider les moteurs de recherche à comprendre quelles langues sont disponibles sur la page
817
+ - Listez toutes les traductions de pages dans le sitemap.xml en utilisant le schéma XML `http://www.w3.org/1999/xhtml`
818
+ - N'oubliez pas d'exclure les pages préfixées dans le fichier robots.txt (par exemple, `/dashboard`, `/fr/dashboard`, `/es/dashboard`)
819
+ - Utilisez un composant Link personnalisé pour rediriger vers la page la plus localisée (par exemple, en français `<a href="/fr/about">À propos</a>`)
820
+
821
+ Les développeurs oublient souvent de référencer correctement leurs pages selon les locales. Corrigeons cela :
822
+
823
+ ```tsx fileName="src/app/[locale]/about/layout.tsx"
824
+ import type { Metadata } from "next";
825
+ import {
826
+ locales,
827
+ defaultLocale,
828
+ localizedPath,
829
+ absoluteUrl,
830
+ } from "@/i18n.config";
831
+
832
+ /**
833
+ * Génère les métadonnées SEO pour chaque version locale de la page
834
+ * Cette fonction s'exécute pour chaque locale lors de la compilation
835
+ */
836
+ export async function generateMetadata({
837
+ params,
838
+ }: {
839
+ params: { locale: string };
840
+ }): Promise<Metadata> {
841
+ const { locale } = params;
842
+
843
+ // Importer dynamiquement le fichier de traduction pour cette locale
844
+ // Utilisé pour obtenir le titre et la description traduits pour les métadonnées
845
+ const messages = (await import(`@/locales/${locale}/about.json`)).default;
846
+
847
+ // Créer une correspondance hreflang pour toutes les locales
848
+ // Aide les moteurs de recherche à comprendre les alternatives linguistiques
849
+ // Format : { "en": "/about", "fr": "/fr/about" }
850
+ const languages = Object.fromEntries(
851
+ locales.map((locale) => [locale, localizedPath(locale, "/about")])
852
+ );
853
+
854
+ return {
855
+ title: messages.title,
856
+ description: messages.description,
857
+ alternates: {
858
+ // URL canonique pour cette version locale
859
+ canonical: absoluteUrl(locale, "/about"),
860
+ // Alternatives linguistiques pour le SEO (balises hreflang)
861
+ // "x-default" spécifie la version locale par défaut
862
+ languages: {
863
+ ...languages,
864
+ "x-default": absoluteUrl(defaultLocale, "/about"),
865
+ },
866
+ },
867
+ };
868
+ }
869
+
870
+ export default async function AboutPage() {
871
+ return <h1>À propos</h1>;
872
+ }
873
+ ```
874
+
875
+ ### (Optionnel) Étape 16 : Internationalisez votre sitemap
876
+
877
+ Générez un sitemap qui inclut toutes les versions locales de vos pages. Cela aide les moteurs de recherche à découvrir et indexer toutes les versions linguistiques de votre contenu.
878
+
879
+ Un sitemap correctement internationalisé garantit que les moteurs de recherche peuvent trouver et indexer toutes les versions linguistiques de vos pages. Cela améliore la visibilité dans les résultats de recherche internationaux.
880
+
881
+ ```ts fileName="src/app/sitemap.ts"
882
+ import type { MetadataRoute } from "next";
883
+ import { defaultLocale, locales } from "@/i18n";
884
+
885
+ const origin = "https://example.com";
886
+
887
+ const formatterLocalizedPath = (locale: string, path: string) =>
888
+ locale === defaultLocale ? `${origin}${path}` : `${origin}/${locale}${path}`;
889
+
890
+ /**
891
+ * Obtenir une carte de toutes les locales et leurs chemins localisés
892
+ *
893
+ * Exemple de sortie :
894
+ * {
895
+ * "en": "https://example.com",
896
+ * "fr": "https://example.com/fr",
897
+ * "es": "https://example.com/es",
898
+ * "x-default": "https://example.com"
899
+ * }
900
+ */
901
+ const getLocalizedMap = (path: string) =>
902
+ Object.fromEntries([
903
+ ...locales.map((locale) => [locale, formatterLocalizedPath(locale, path)]),
904
+ ["x-default", formatterLocalizedPath(defaultLocale, path)],
905
+ ]);
906
+
907
+ // Générer un sitemap avec toutes les variantes locales pour un meilleur SEO
908
+ // Le champ alternates informe les moteurs de recherche des versions linguistiques
909
+ export default function sitemap(): MetadataRoute.Sitemap {
910
+ return [
911
+ {
912
+ url: formatterLocalizedPath(defaultLocale, "/"),
913
+ lastModified: new Date(),
914
+ changeFrequency: "monthly",
915
+ priority: 1.0,
916
+ alternates: { languages: getLocalizedMap("/") },
917
+ },
918
+ {
919
+ url: formatterLocalizedPath(defaultLocale, "/about"),
920
+ lastModified: new Date(),
921
+ changeFrequency: "monthly",
922
+ priority: 0.7,
923
+ alternates: { languages: getLocalizedMap("/about") },
924
+ },
925
+ ];
926
+ }
927
+ ```
928
+
929
+ ### (Optionnel) Étape 17 : Internationalisez votre fichier robots.txt
930
+
931
+ Créez un fichier robots.txt qui gère correctement toutes les versions locales de vos routes protégées. Cela garantit que les moteurs de recherche n'indexent pas les pages d'administration ou de tableau de bord dans aucune langue.
932
+
933
+ Configurer correctement le fichier robots.txt pour toutes les locales empêche les moteurs de recherche d'indexer des pages sensibles dans n'importe quelle langue. Ceci est crucial pour la sécurité et la confidentialité.
934
+
935
+ ```ts fileName="src/app/robots.ts"
936
+ import type { MetadataRoute } from "next";
937
+ import { defaultLocale, locales } from "@/i18n";
938
+
939
+ const origin = "https://example.com";
940
+
941
+ // Génère les chemins pour toutes les locales (par exemple, /admin, /fr/admin, /es/admin)
942
+ const withAllLocales = (path: string) => [
943
+ path,
944
+ ...locales
945
+ .filter((locale) => locale !== defaultLocale)
946
+ .map((locale) => `/${locale}${path}`),
947
+ ];
948
+
949
+ const disallow = [...withAllLocales("/dashboard"), ...withAllLocales("/admin")];
950
+
951
+ export default function robots(): MetadataRoute.Robots {
952
+ return {
953
+ rules: { userAgent: "*", allow: ["/"], disallow },
954
+ host: origin,
955
+ sitemap: `${origin}/sitemap.xml`,
956
+ };
957
+ }
958
+ ```
959
+
960
+ ### (Optionnel) Étape 18 : Configurer un Middleware pour le Routage des Locales
961
+
962
+ Créez un proxy pour détecter automatiquement la locale préférée de l'utilisateur et le rediriger vers l'URL préfixée par la locale appropriée. Cela améliore l'expérience utilisateur en affichant le contenu dans sa langue préférée.
963
+
964
+ Le middleware garantit que les utilisateurs sont automatiquement redirigés vers leur langue préférée lorsqu'ils visitent votre site. Il sauvegarde également la préférence de l'utilisateur dans un cookie pour les visites futures.
965
+
966
+ ```ts fileName="src/proxy.ts"
967
+ import { NextResponse, type NextRequest } from "next/server";
968
+ import { defaultLocale, locales } from "@/i18n.config";
969
+
970
+ // Expression régulière pour correspondre aux fichiers avec extensions (ex : .js, .css, .png)
971
+ // Utilisée pour exclure les ressources statiques du routage par locale
972
+ const PUBLIC_FILE = /\.[^/]+$/;
973
+
974
+ /**
975
+ * Extraire la locale depuis l'en-tête Accept-Language
976
+ * Gère les formats comme "fr-CA", "en-US", etc.
977
+ * Reviens à la locale par défaut si la langue du navigateur n'est pas supportée
978
+ */
979
+ const pickLocale = (accept: string | null) => {
980
+ // Obtenir la première préférence de langue (ex : "fr-CA" depuis "fr-CA,en-US;q=0.9")
981
+ const raw = accept?.split(",")[0] ?? defaultLocale;
982
+ // Extraire le code de langue de base (ex : "fr" depuis "fr-CA")
983
+ const base = raw.toLowerCase().split("-")[0];
984
+ // Vérifier si cette locale est supportée, sinon utiliser la locale par défaut
985
+ return (locales as readonly string[]).includes(base) ? base : defaultLocale;
986
+ };
987
+
988
+ /**
989
+ * Proxy Next.js pour la détection et le routage des locales
990
+ * S'exécute à chaque requête avant le rendu de la page
991
+ * Redirige automatiquement vers les URLs préfixées par la locale si nécessaire
992
+ */
993
+ export function proxy(request: NextRequest) {
994
+ const { pathname } = request.nextUrl;
995
+
996
+ // Ignorer le proxy pour les internes Next.js, les routes API et les fichiers statiques
997
+ // Ceux-ci ne doivent pas être préfixés par une locale
998
+ if (
999
+ pathname.startsWith("/_next") ||
1000
+ pathname.startsWith("/api") ||
1001
+ pathname.startsWith("/static") ||
1002
+ PUBLIC_FILE.test(pathname)
1003
+ ) {
1004
+ return;
1005
+ }
1006
+
1007
+ // Vérifier si l'URL contient déjà un préfixe de locale
1008
+ // Exemple : "/fr/about" ou "/en" retournerait true
1009
+ const hasLocale = (locales as readonly string[]).some(
1010
+ (locale) => pathname === `/${locale}` || pathname.startsWith(`/${locale}/`)
1011
+ );
1012
+
1013
+ // S'il n'y a pas de préfixe de locale, détecter la locale et rediriger
1014
+ if (!hasLocale) {
1015
+ // Essayer d'obtenir la locale depuis le cookie en premier (préférence utilisateur)
1016
+ const cookieLocale = request.cookies.get("NEXT_LOCALE")?.value;
1017
+
1018
+ // Utiliser la locale du cookie si valide, sinon détecter depuis les en-têtes du navigateur
1019
+ const locale =
1020
+ cookieLocale && (locales as readonly string[]).includes(cookieLocale)
1021
+ ? cookieLocale
1022
+ : pickLocale(request.headers.get("accept-language"));
1023
+
1024
+ // Cloner l'URL pour modifier le pathname
1025
+ const url = request.nextUrl.clone();
1026
+ // Ajouter le préfixe de locale au pathname
1027
+ // Gérer le chemin racine spécialement pour éviter un double slash
1028
+ url.pathname = `/${locale}${pathname === "/" ? "" : pathname}`;
1029
+
1030
+ // Créer une réponse de redirection et définir le cookie de langue
1031
+ const res = NextResponse.redirect(url);
1032
+ res.cookies.set("NEXT_LOCALE", locale, { path: "/" });
1033
+ return res;
1034
+ }
1035
+ }
1036
+
1037
+ export const config = {
1038
+ matcher: [
1039
+ // Correspond à tous les chemins sauf :
1040
+ // - Les routes API (/api/*)
1041
+ // - Les internals de Next.js (/_next/*)
1042
+ // - Les fichiers statiques (/static/*)
1043
+ // - Les fichiers avec extensions (.*\\..*)
1044
+ "/((?!api|_next|static|.*\\..*).*)",
1045
+ ],
1046
+ };
1047
+ ```
1048
+
1049
+ ### (Optionnel) Étape 19 : Automatisez vos traductions avec Intlayer
1050
+
1051
+ Intlayer est une bibliothèque **gratuite** et **open-source** conçue pour assister le processus de localisation dans votre application. Alors que i18next gère le chargement et la gestion des traductions, Intlayer aide à automatiser le flux de travail des traductions.
1052
+
1053
+ Gérer les traductions manuellement peut être chronophage et source d’erreurs. Intlayer automatise les tests, la génération et la gestion des traductions, vous faisant gagner du temps et assurant la cohérence dans toute votre application.
1054
+
1055
+ Intlayer vous permet de :
1056
+
1057
+ - **Déclarer votre contenu où vous le souhaitez dans votre base de code**
1058
+ Intlayer permet de déclarer votre contenu où vous le souhaitez dans votre base de code en utilisant des fichiers `.content.{ts|js|json}`. Cela permettra une meilleure organisation de votre contenu, assurant une meilleure lisibilité et maintenabilité de votre base de code.
1059
+
1060
+ - **Tester les traductions manquantes**
1061
+ Intlayer fournit des fonctions de test qui peuvent être intégrées dans votre pipeline CI/CD ou dans vos tests unitaires. En savoir plus sur [tester vos traductions](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/testing.md).
1062
+
1063
+ - **Automatisez vos traductions**,
1064
+ Intlayer fournit une CLI et une extension VSCode pour automatiser vos traductions. Cela peut être intégré dans votre pipeline CI/CD. En savoir plus sur [l'automatisation de vos traductions](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_cli.md).
1065
+ Vous pouvez utiliser votre **propre clé API, et le fournisseur d'IA de votre choix**. Il offre également des traductions contextuelles, voir [remplissage de contenu](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/autoFill.md).
1066
+
1067
+ - **Connecter du contenu externe**
1068
+ - **Automatisez vos traductions**,
1069
+ Intlayer fournit une CLI et une extension VSCode pour automatiser vos traductions. Cela peut être intégré dans votre pipeline CI/CD. En savoir plus sur [l'automatisation de vos traductions](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_cli.md).
1070
+ Vous pouvez utiliser votre **propre clé API et le fournisseur d'IA de votre choix**. Il propose également des traductions contextuelles, voir [remplissage automatique de contenu](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/autoFill.md).
1071
+
1072
+ - **Connectez du contenu externe**
1073
+ Intlayer vous permet de connecter votre contenu à un système de gestion de contenu externe (CMS). Pour le récupérer de manière optimisée et l'insérer dans vos ressources JSON. En savoir plus sur [la récupération de contenu externe](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/dictionary/function_fetching.md).
1074
+
1075
+ - **Éditeur visuel**
1076
+ Intlayer propose un éditeur visuel gratuit pour éditer votre contenu via un éditeur visuel. En savoir plus sur [l'édition visuelle de vos traductions](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/intlayer_visual_editor.md).
1077
+
1078
+ Et plus encore. Pour découvrir toutes les fonctionnalités offertes par Intlayer, veuillez consulter la [documentation sur l'intérêt d'Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/fr/interest_of_intlayer.md).