@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: Cara menginternasionalisasi aplikasi Next.js Anda menggunakan next-i18next
5
+ description: Mengatur i18n dengan next-i18next - praktik terbaik dan tips SEO untuk aplikasi Next.js multibahasa, mencakup internasionalisasi, pengorganisasian konten, dan pengaturan teknis.
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: Versi awal
14
+ ---
15
+
16
+ # Cara menginternasionalisasi aplikasi Next.js Anda menggunakan next-i18next pada tahun 2025
17
+
18
+ ## Daftar Isi
19
+
20
+ <TOC/>
21
+
22
+ ## Apa itu next-i18next?
23
+
24
+ **next-i18next** adalah solusi internasionalisasi (i18n) yang populer untuk aplikasi Next.js. Meskipun paket `next-i18next` asli dirancang untuk Pages Router, panduan ini menunjukkan cara mengimplementasikan i18next dengan **App Router** modern menggunakan `i18next` dan `react-i18next` secara langsung.
25
+
26
+ Dengan pendekatan ini, Anda dapat:
27
+
28
+ - **Mengorganisir terjemahan** menggunakan namespace (misalnya, `common.json`, `about.json`) untuk manajemen konten yang lebih baik.
29
+ - **Memuat terjemahan secara efisien** dengan hanya memuat namespace yang diperlukan untuk setiap halaman, sehingga mengurangi ukuran bundle.
30
+ - **Mendukung komponen server dan klien** dengan penanganan SSR dan hidrasi yang tepat.
31
+ - **Memastikan dukungan TypeScript** dengan konfigurasi locale dan kunci terjemahan yang aman tipe.
32
+ - **Mengoptimalkan untuk SEO** dengan metadata yang tepat, sitemap, dan internasionalisasi robots.txt.
33
+
34
+ > Sebagai alternatif, Anda juga dapat merujuk ke [panduan next-intl](https://github.com/aymericzip/intlayer/blob/main/docs/blog/id/i18n_using_next-intl.md), atau langsung menggunakan [Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/intlayer_with_nextjs_16.md).
35
+
36
+ > Lihat perbandingan di [next-i18next vs next-intl vs Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/blog/id/next-i18next_vs_next-intl_vs_intlayer.md).
37
+
38
+ ## Praktik yang harus Anda ikuti
39
+
40
+ Sebelum kita masuk ke implementasi, berikut beberapa praktik yang harus Anda ikuti:
41
+
42
+ - **Atur atribut HTML `lang` dan `dir`**
43
+ Di layout Anda, hitung `dir` menggunakan `getLocaleDirection(locale)` dan atur `<html lang={locale} dir={dir}>` untuk aksesibilitas dan SEO yang tepat.
44
+ - **Pisahkan pesan berdasarkan namespace**
45
+ Atur file JSON per locale dan namespace (misalnya, `common.json`, `about.json`) agar hanya memuat apa yang Anda butuhkan.
46
+ - **Minimalkan payload klien**
47
+ Pada halaman, kirim hanya namespace yang diperlukan ke `NextIntlClientProvider` (misalnya, `pick(messages, ['common', 'about'])`).
48
+ - **Utamakan halaman statis**
49
+ Gunakan halaman statis sebanyak mungkin untuk kinerja dan SEO yang lebih baik.
50
+ - **I18n pada komponen server**
51
+ Komponen server, seperti halaman atau semua komponen yang tidak ditandai sebagai `client`, adalah statis dan dapat di-pre-render saat build time. Jadi kita harus mengoper fungsi terjemahan ke mereka sebagai props.
52
+ - **Siapkan tipe TypeScript**
53
+ Untuk locale Anda agar memastikan keamanan tipe di seluruh aplikasi Anda.
54
+ - **Proxy untuk pengalihan**
55
+ Gunakan proxy untuk menangani deteksi locale dan routing serta mengarahkan pengguna ke URL dengan prefix locale yang sesuai.
56
+ - **Internasionalisasi metadata, sitemap, robots.txt Anda**
57
+ Internasionalisasikan metadata, sitemap, robots.txt Anda menggunakan fungsi `generateMetadata` yang disediakan oleh Next.js untuk memastikan penemuan yang lebih baik oleh mesin pencari di semua locale.
58
+ - **Lokalisasi Tautan**
59
+ Lokalisasi tautan menggunakan komponen `Link` untuk mengarahkan pengguna ke URL dengan prefix locale yang sesuai. Ini penting untuk memastikan penemuan halaman Anda di semua locale.
60
+ - **Otomatisasi pengujian dan terjemahan**
61
+ Otomatisasi pengujian dan terjemahan membantu menghemat waktu dalam memelihara aplikasi multibahasa Anda.
62
+
63
+ > Lihat dokumentasi kami yang mencantumkan semua yang perlu Anda ketahui tentang internasionalisasi dan SEO: [Internasionalisasi (i18n) dengan next-intl](https://github.com/aymericzip/intlayer/blob/main/docs/blog/id/internationalization_and_SEO.md).
64
+
65
+ ---
66
+
67
+ ## Panduan Langkah demi Langkah untuk Mengatur i18next dalam Aplikasi 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 - Cara Menginternasionalisasi aplikasi Anda menggunakan Intlayer"
73
+ sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
74
+ loading="lazy"
75
+
76
+ > Lihat [Application Template](https://github.com/aymericzip/next-i18next-template) di GitHub.
77
+
78
+ Berikut adalah struktur proyek yang akan kita buat:
79
+
80
+ ```bash
81
+ .
82
+ ├── i18n.config.ts
83
+ └── src # Src adalah opsional
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) # / (Route Group untuk tidak mencemari semua halaman dengan pesan 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
+ ### Langkah 1: Instalasi Dependensi
112
+
113
+ Instal paket-paket yang diperlukan menggunakan 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**: Kerangka kerja internasionalisasi inti yang menangani pemuatan dan pengelolaan terjemahan.
128
+ - **react-i18next**: Binding React untuk i18next yang menyediakan hooks seperti `useTranslation` untuk komponen klien.
129
+ - **i18next-resources-to-backend**: Plugin yang memungkinkan pemuatan dinamis file terjemahan, sehingga Anda hanya memuat namespace yang Anda butuhkan.
130
+
131
+ ### Langkah 2: Konfigurasikan Proyek Anda
132
+
133
+ Buat file konfigurasi untuk mendefinisikan locale yang didukung, locale default, dan fungsi pembantu untuk lokalisasi URL. File ini berfungsi sebagai sumber kebenaran tunggal untuk pengaturan i18n Anda dan memastikan keamanan tipe di seluruh aplikasi Anda.
134
+
135
+ Mencentralisasi konfigurasi locale Anda mencegah inkonsistensi dan memudahkan penambahan atau penghapusan locale di masa depan. Fungsi pembantu memastikan pembuatan URL yang konsisten untuk SEO dan routing.
136
+
137
+ ```ts fileName="i18n.config.ts"
138
+ // Mendefinisikan locale yang didukung sebagai array const untuk keamanan tipe
139
+ // Pernyataan 'as const' membuat TypeScript menginferensi tipe literal daripada string[]
140
+ export const locales = ["en", "fr"] as const;
141
+
142
+ // Mengekstrak tipe Locale dari array locales
143
+ // Ini membuat tipe union: "en" | "fr"
144
+ export type Locale = (typeof locales)[number];
145
+
146
+ // Tetapkan locale default yang digunakan ketika tidak ada locale yang ditentukan
147
+ export const defaultLocale: Locale = "en";
148
+
149
+ // Bahasa dengan arah teks kanan-ke-kiri yang memerlukan penanganan khusus
150
+ export const rtlLocales = ["ar", "he", "fa", "ur"] as const;
151
+
152
+ // Periksa apakah sebuah locale memerlukan arah teks RTL (kanan-ke-kiri)
153
+ // Digunakan untuk bahasa seperti Arab, Ibrani, Persia, dan Urdu
154
+ export const isRtl = (locale: string) =>
155
+ (rtlLocales as readonly string[]).includes(locale);
156
+
157
+ // Hasilkan path yang dilokalkan untuk locale dan path tertentu
158
+ // Path untuk locale default tidak memiliki prefix (misal, "/about" bukan "/en/about")
159
+ // Locale lain diberi prefix (misal, "/fr/about")
160
+ export function localizedPath(locale: string, path: string) {
161
+ return locale === defaultLocale ? path : `/${locale}${path}`;
162
+ }
163
+
164
+ // URL dasar untuk URL absolut (digunakan dalam sitemap, metadata, dll.)
165
+ const ORIGIN = "https://example.com";
166
+
167
+ // Menghasilkan URL absolut dengan prefix locale
168
+ // Digunakan untuk metadata SEO, sitemap, dan URL kanonis
169
+ export function absoluteUrl(locale: string, path: string) {
170
+ return `${ORIGIN}${localizedPath(locale, path)}`;
171
+ }
172
+
173
+ // Digunakan untuk mengatur cookie locale di browser
174
+ export function getCookie(locale: Locale) {
175
+ return [
176
+ `NEXT_LOCALE=${locale}`,
177
+ "Path=/",
178
+ `Max-Age=${60 * 60 * 24 * 365}`, // 1 tahun
179
+ "SameSite=Lax",
180
+ ].join("; ");
181
+ }
182
+ ```
183
+
184
+ ### Langkah 3: Sentralisasi Namespace Terjemahan
185
+
186
+ Buat satu sumber kebenaran untuk setiap namespace yang diekspos oleh aplikasi Anda. Menggunakan kembali daftar ini menjaga sinkronisasi kode server, klien, dan tooling serta membuka tipe kuat untuk helper terjemahan.
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
+ ### Langkah 4: Ketik Kuat Kunci Terjemahan dengan TypeScript
195
+
196
+ Perluas `i18next` untuk menunjuk ke file bahasa kanonik Anda (biasanya bahasa Inggris). TypeScript kemudian menafsirkan kunci yang valid per namespace, sehingga panggilan ke `t()` diperiksa secara menyeluruh.
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
+ > Tip: Simpan deklarasi ini di bawah `src/types` (buat foldernya jika belum ada). Next.js sudah memasukkan `src` dalam `tsconfig.json`, sehingga augmentasi ini akan terdeteksi secara otomatis. Jika tidak, tambahkan yang berikut ke file `tsconfig.json` Anda:
213
+
214
+ ```json5 fileName="tsconfig.json"
215
+ {
216
+ "include": ["src/types/**/*.ts"],
217
+ }
218
+ ```
219
+
220
+ Dengan ini, Anda dapat mengandalkan autocomplete dan pemeriksaan saat kompilasi:
221
+
222
+ ```tsx
223
+ import { useTranslation, type TFunction } from "react-i18next";
224
+
225
+ const { t } = useTranslation("about");
226
+
227
+ // OK, bertipe: t("counter.increment")
228
+ // ERROR, error kompilasi: t("doesNotExist")
229
+ export type AboutTranslator = TFunction<"about">;
230
+ ```
231
+
232
+ ### Langkah 5: Siapkan Inisialisasi i18n di Sisi Server
233
+
234
+ Buat fungsi inisialisasi sisi server yang memuat terjemahan untuk komponen server. Fungsi ini membuat instance i18next terpisah untuk rendering sisi server, memastikan bahwa terjemahan dimuat sebelum rendering.
235
+
236
+ Komponen server membutuhkan instance i18next mereka sendiri karena mereka berjalan dalam konteks yang berbeda dari komponen klien. Memuat terjemahan terlebih dahulu di server mencegah tampilan konten yang belum diterjemahkan dan meningkatkan SEO dengan memastikan mesin pencari melihat konten yang sudah diterjemahkan.
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
+ // Konfigurasikan pemuatan sumber daya dinamis untuk i18next
246
+ // Fungsi ini secara dinamis mengimpor file JSON terjemahan berdasarkan locale dan namespace
247
+ // Contoh: locale="fr", namespace="about" -> mengimpor "@/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
+ * Inisialisasi instance i18next untuk rendering sisi server
259
+ *
260
+ * @returns Instance i18next yang sudah diinisialisasi siap digunakan di sisi server
261
+ */
262
+ export async function initI18next(
263
+ locale: string,
264
+ ns: readonly Namespace[] = DEFAULT_NAMESPACES
265
+ ) {
266
+ // Buat instance i18next baru (terpisah dari instance sisi klien)
267
+ const i18n = createInstance();
268
+
269
+ // Inisialisasi dengan integrasi React dan pemuat backend
270
+ await i18n
271
+ .use(initReactI18next) // Aktifkan dukungan React hooks
272
+ .use(backend) // Aktifkan pemuatan sumber daya dinamis
273
+ .init({
274
+ lng: locale,
275
+ fallbackLng: defaultLocale,
276
+ ns, // Muat hanya namespace yang ditentukan untuk kinerja lebih baik
277
+ defaultNS: "common", // Namespace default jika tidak ada yang ditentukan
278
+ interpolation: { escapeValue: false }, // Jangan escape HTML (React menangani proteksi XSS)
279
+ react: { useSuspense: false }, // Nonaktifkan Suspense untuk kompatibilitas SSR
280
+ returnNull: false, // Kembalikan string kosong alih-alih null untuk kunci yang hilang
281
+ initImmediate: false, // Tunda inisialisasi sampai sumber daya dimuat (SSR lebih cepat)
282
+ });
283
+ return i18n;
284
+ }
285
+ ```
286
+
287
+ ### Langkah 6: Buat Provider i18n di Sisi Klien
288
+
289
+ Buat provider komponen klien yang membungkus aplikasi Anda dengan konteks i18next. Provider ini menerima terjemahan yang sudah dimuat sebelumnya dari server untuk mencegah flash konten yang belum diterjemahkan (FOUC) dan menghindari pengambilan data ganda.
290
+
291
+ Komponen klien membutuhkan instance i18next mereka sendiri yang berjalan di browser. Dengan menerima sumber daya yang sudah dimuat sebelumnya dari server, kita memastikan hidrasi yang mulus dan mencegah konten berkedip. Provider ini juga mengelola perubahan locale dan pemuatan namespace secara dinamis.
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
+ // Konfigurasikan pemuatan sumber daya dinamis untuk sisi klien
305
+ // Pola yang sama seperti sisi server, tetapi instance ini berjalan di browser
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
+ // Sumber daya yang sudah dimuat dari server (mencegah FOUC - Flash of Untranslated Content)
315
+ // Format: { namespace: translationBundle }
316
+ resources?: Record<Namespace, ResourceLanguage>;
317
+ children: React.ReactNode;
318
+ };
319
+
320
+ /**
321
+ * Penyedia i18n sisi klien yang membungkus aplikasi dengan konteks i18next
322
+ * Menerima sumber daya yang sudah dimuat sebelumnya dari server untuk menghindari pengambilan ulang terjemahan
323
+ */
324
+ export default function I18nProvider({
325
+ locale,
326
+ namespaces = [allNamespaces[0]] as const,
327
+ resources,
328
+ children,
329
+ }: Props) {
330
+ // Membuat instance i18n sekali menggunakan inisialisasi malas useState
331
+ // Ini memastikan instance dibuat hanya sekali, tidak pada setiap render
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
+ // Jika resources disediakan (dari server), gunakan untuk menghindari pengambilan data di sisi klien
343
+ // Ini mencegah FOUC dan meningkatkan performa muat awal
344
+ resources: resources ? { [locale]: resources } : undefined,
345
+ defaultNS: "common",
346
+ interpolation: { escapeValue: false },
347
+ react: { useSuspense: false },
348
+ returnNull: false, // Mencegah nilai undefined dikembalikan
349
+ });
350
+
351
+ return i18nInstance;
352
+ });
353
+
354
+ // Perbarui bahasa saat properti locale berubah
355
+ useEffect(() => {
356
+ i18n.changeLanguage(locale);
357
+ }, [locale, i18n]);
358
+
359
+ // Pastikan semua namespace yang diperlukan dimuat di sisi klien
360
+ // Menggunakan join("|") sebagai dependency untuk membandingkan array dengan benar
361
+ useEffect(() => {
362
+ i18n.loadNamespaces(namespaces);
363
+ }, [namespaces.join("|"), i18n]);
364
+
365
+ // Menyediakan instance i18n ke semua komponen anak melalui konteks React
366
+ return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;
367
+ }
368
+ ```
369
+
370
+ ### Langkah 7: Definisikan Rute Locale Dinamis
371
+
372
+ Atur routing dinamis untuk locale dengan membuat direktori `[locale]` di folder app Anda. Ini memungkinkan Next.js untuk menangani routing berbasis locale di mana setiap locale menjadi segmen URL (misalnya, `/en/about`, `/fr/about`).
373
+
374
+ Menggunakan rute dinamis memungkinkan Next.js menghasilkan halaman statis untuk semua locale saat build time, meningkatkan performa dan SEO. Komponen layout mengatur atribut HTML `lang` dan `dir` berdasarkan locale, yang sangat penting untuk aksesibilitas dan pemahaman mesin pencari.
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
+ // Nonaktifkan parameter dinamis - semua locale harus diketahui saat build
381
+ // Ini memastikan generasi statis untuk semua rute locale
382
+ export const dynamicParams = false;
383
+
384
+ /**
385
+ * Menghasilkan parameter statis untuk semua locale saat build
386
+ * Next.js akan melakukan pre-render halaman untuk setiap locale yang dikembalikan di sini
387
+ * Contoh: [{ locale: "en" }, { locale: "fr" }]
388
+ */
389
+ export function generateStaticParams() {
390
+ return locales.map((locale) => ({ locale }));
391
+ }
392
+
393
+ /**
394
+ * Komponen layout root yang menangani atribut HTML spesifik locale
395
+ * Mengatur atribut lang dan arah teks (ltr/rtl) berdasarkan locale
396
+ */
397
+ export default function LocaleLayout({
398
+ children,
399
+ params,
400
+ }: {
401
+ children: ReactNode;
402
+ params: { locale: string };
403
+ }) {
404
+ // Validasi locale dari parameter URL
405
+ // Jika locale yang diberikan tidak valid, gunakan locale default
406
+ const locale: Locale = (locales as readonly string[]).includes(params.locale)
407
+ ? (params.locale as any)
408
+ : defaultLocale;
409
+
410
+ // Tentukan arah teks berdasarkan locale
411
+ // Bahasa RTL seperti Arab membutuhkan dir="rtl" untuk rendering teks yang benar
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
+ ### Langkah 8: Buat File Terjemahan Anda
423
+
424
+ Buat file JSON untuk setiap locale dan namespace. Struktur ini memungkinkan Anda mengatur terjemahan secara logis dan memuat hanya yang Anda butuhkan untuk setiap halaman.
425
+
426
+ Mengorganisir terjemahan berdasarkan namespace (misalnya, `common.json`, `about.json`) memungkinkan pemisahan kode dan mengurangi ukuran bundle. Anda hanya memuat terjemahan yang dibutuhkan untuk setiap halaman, sehingga meningkatkan performa.
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/id/home.json"
454
+ {
455
+ "title": "Beranda",
456
+ "description": "Deskripsi halaman beranda",
457
+ "welcome": "Selamat datang",
458
+ "greeting": "Halo, dunia!",
459
+ "aboutPage": "Halaman Tentang",
460
+ "documentation": "Dokumentasi"
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/id/about.json"
477
+ {
478
+ "title": "Tentang",
479
+ "description": "Deskripsi halaman tentang",
480
+ "counter": {
481
+ "label": "Penghitung",
482
+ "increment": "Tambah",
483
+ "description": "Klik tombol untuk menambah penghitung"
484
+ }
485
+ }
486
+ ```
487
+
488
+ ### Langkah 9: Memanfaatkan Terjemahan di Halaman Anda
489
+
490
+ Buat komponen halaman yang menginisialisasi i18next di server dan meneruskan terjemahan ke komponen server dan klien. Ini memastikan bahwa terjemahan dimuat sebelum rendering dan mencegah tampilan konten yang berkedip.
491
+
492
+ Inisialisasi sisi server memuat terjemahan sebelum halaman dirender, meningkatkan SEO dan mencegah FOUC (Flash of Unstyled Content). Dengan meneruskan sumber daya yang sudah dimuat ke penyedia klien, kita menghindari pengambilan data ganda dan memastikan hidrasi yang mulus.
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
+ * Komponen server halaman yang menangani inisialisasi i18n
505
+ * Memuat terjemahan terlebih dahulu di server dan meneruskannya ke komponen klien
506
+ */
507
+ export default async function AboutPage({
508
+ params: { locale },
509
+ }: {
510
+ params: { locale: Locale };
511
+ }) {
512
+ // Tentukan namespace terjemahan yang dibutuhkan halaman ini
513
+ // Gunakan kembali daftar terpusat untuk keamanan tipe dan autocomplete
514
+ const pageNamespaces = allNamespaces;
515
+
516
+ // Inisialisasi i18next di server dengan namespace yang diperlukan
517
+ // Ini memuat file JSON terjemahan di sisi server
518
+ const i18n = await initI18next(locale, pageNamespaces);
519
+
520
+ // Dapatkan fungsi terjemahan tetap untuk namespace "about"
521
+ // getFixedT mengunci namespace, sehingga t("title") bukan t("about:title")
522
+ const tAbout = i18n.getFixedT(locale, "about");
523
+
524
+ // Ekstrak bundel terjemahan dari instance i18n
525
+ // Data ini diteruskan ke I18nProvider untuk menghidrat i18n sisi klien
526
+ // Mencegah FOUC (Flash of Untranslated Content) dan menghindari pengambilan ganda
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
+ ### Langkah 10: Gunakan Terjemahan di Komponen Klien
549
+
550
+ Komponen klien dapat menggunakan hook `useTranslation` untuk mengakses terjemahan. Hook ini memberikan akses ke fungsi terjemahan dan instance i18n, memungkinkan Anda menerjemahkan konten dan mengakses informasi locale.
551
+
552
+ Komponen klien memerlukan React hooks untuk mengakses terjemahan. Hook `useTranslation` terintegrasi dengan mulus dengan i18next dan memberikan pembaruan reaktif saat locale berubah.
553
+
554
+ > Pastikan halaman/provider hanya menyertakan namespace yang Anda butuhkan (misalnya, `about`).
555
+ > Jika Anda menggunakan React < 19, gunakan memoization untuk formatter berat seperti `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
+ * Contoh komponen client yang menggunakan React hooks untuk terjemahan
565
+ * Dapat menggunakan hooks seperti useState, useEffect, dan useTranslation
566
+ */
567
+ const ClientComponent = () => {
568
+ // Hook useTranslation memberikan akses ke fungsi terjemahan dan instance i18n
569
+ // Tentukan namespace untuk hanya memuat terjemahan pada namespace "about"
570
+ const { t, i18n } = useTranslation("about");
571
+ const [count, setCount] = useState(0);
572
+
573
+ // Membuat formatter angka yang sesuai dengan locale
574
+ // i18n.language memberikan locale saat ini (misal, "en", "fr")
575
+ // Intl.NumberFormat memformat angka sesuai konvensi locale
576
+ const numberFormat = new Intl.NumberFormat(i18n.language);
577
+
578
+ return (
579
+ <div className="flex flex-col items-center gap-4">
580
+ {/* Format angka menggunakan format spesifik lokal */}
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
+ ### Langkah 11: Menggunakan Terjemahan di Komponen Server
600
+
601
+ Komponen server tidak dapat menggunakan React hooks, sehingga mereka menerima terjemahan melalui props dari komponen induk mereka. Pendekatan ini menjaga komponen server tetap sinkron dan memungkinkan mereka untuk disisipkan di dalam komponen klien.
602
+
603
+ Komponen server yang mungkin disisipkan di bawah batasan klien harus bersifat sinkron. Dengan meneruskan string terjemahan dan informasi locale sebagai props, kita menghindari operasi async dan memastikan rendering yang tepat.
604
+
605
+ ```tsx fileName="src/components/ServerComponent.tsx"
606
+ import type { TFunction } from "i18next";
607
+
608
+ type ServerComponentProps = {
609
+ // Fungsi terjemahan yang diteruskan dari komponen server induk
610
+ // Komponen server tidak dapat menggunakan hooks, jadi terjemahan datang melalui props
611
+ t: TFunction<"about">;
612
+ locale: string;
613
+ count: number;
614
+ };
615
+
616
+ /**
617
+ * Contoh komponen server - menerima terjemahan sebagai props
618
+ * Dapat disisipkan di dalam komponen klien (komponen server async)
619
+ * Tidak dapat menggunakan React hooks, jadi semua data harus berasal dari props atau operasi async
620
+ */
621
+ const ServerComponent = ({ t, locale, count }: ServerComponentProps) => {
622
+ // Format angka di sisi server menggunakan locale
623
+ // Ini dijalankan di server selama SSR, meningkatkan waktu muat halaman awal
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
+ {/* Gunakan fungsi terjemahan yang diteruskan sebagai 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
+ ### (Opsional) Langkah 12: Ubah bahasa konten Anda
648
+
649
+ Untuk mengubah bahasa konten Anda di Next.js, cara yang direkomendasikan adalah menggunakan URL dengan prefix locale dan link Next.js. Contoh di bawah ini membaca locale saat ini dari rute, menghapusnya dari pathname, dan menampilkan satu link untuk setiap locale yang tersedia.
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="Pemilih bahasa">
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 ? "halaman" : undefined}
706
+ onClick={() => {
707
+ document.cookie = getCookie(locale);
708
+ }}
709
+ >
710
+ {getLocaleLabel(locale)}
711
+ </Link>
712
+ );
713
+ })}
714
+ </nav>
715
+ );
716
+ }
717
+ ```
718
+
719
+ ### (Opsional) Langkah 13: Bangun komponen Link yang dilokalkan
720
+
721
+ Menggunakan kembali URL yang dilokalkan di seluruh aplikasi Anda menjaga navigasi tetap konsisten dan ramah SEO. Bungkus `next/link` dalam helper kecil yang menambahkan prefix locale aktif pada rute internal sambil membiarkan URL eksternal tidak berubah.
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
+ > Tip: Karena `LocalizedLink` adalah pengganti langsung, migrasikan secara bertahap dengan menukar impor dan membiarkan komponen menangani URL spesifik locale.
769
+
770
+ ### (Opsional) Langkah 14: Akses locale aktif di dalam Server Actions
771
+
772
+ Server Actions sering membutuhkan locale saat ini untuk email, pencatatan, atau integrasi pihak ketiga. Gabungkan cookie locale yang diatur oleh proxy Anda dengan header `Accept-Language` sebagai cadangan.
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
+ // Contoh server action yang menggunakan locale saat ini
798
+ export async function stuffFromServer(formData: FormData) {
799
+ const locale = await getCurrentLocale();
800
+
801
+ // Gunakan locale untuk efek samping yang terlokalisasi (email, CRM, dll.)
802
+ console.log(`Stuff from server with locale ${locale}`);
803
+ }
804
+ ```
805
+
806
+ > Karena helper ini bergantung pada cookies dan headers Next.js, ia bekerja di Route Handlers, Server Actions, dan konteks server-only lainnya.
807
+
808
+ ### (Opsional) Langkah 15: Internasionalisasi Metadata Anda
809
+
810
+ Menerjemahkan konten itu penting, tetapi tujuan utama internasionalisasi adalah membuat situs web Anda lebih terlihat oleh dunia. I18n adalah tuas luar biasa untuk meningkatkan visibilitas situs web Anda melalui SEO yang tepat.
811
+
812
+ Metadata yang diinternasionalisasi dengan benar membantu mesin pencari memahami bahasa apa saja yang tersedia di halaman Anda. Ini termasuk pengaturan tag meta hreflang, menerjemahkan judul dan deskripsi, serta memastikan URL kanonik diatur dengan benar untuk setiap locale.
813
+
814
+ Berikut adalah daftar praktik baik terkait SEO multibahasa:
815
+
816
+ - Atur tag meta hreflang di tag `<head>` untuk membantu mesin pencari memahami bahasa apa saja yang tersedia di halaman
817
+ - Daftarkan semua terjemahan halaman di sitemap.xml menggunakan skema XML `http://www.w3.org/1999/xhtml`
818
+ - Jangan lupa untuk mengecualikan halaman dengan prefix dari robots.txt (misalnya, `/dashboard`, `/fr/dashboard`, `/es/dashboard`)
819
+ - Gunakan komponen Link kustom untuk mengarahkan ke halaman dengan lokalitas paling sesuai (misalnya, dalam bahasa Prancis `<a href="/fr/about">À propos</a>`)
820
+
821
+ Pengembang sering lupa untuk mereferensikan halaman mereka dengan benar di berbagai locale. Mari kita perbaiki itu:
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
+ * Menghasilkan metadata SEO untuk setiap versi locale dari halaman
834
+ * Fungsi ini dijalankan untuk setiap locale pada saat build time
835
+ */
836
+ export async function generateMetadata({
837
+ params,
838
+ }: {
839
+ params: { locale: string };
840
+ }): Promise<Metadata> {
841
+ const { locale } = params;
842
+
843
+ // Mengimpor file terjemahan secara dinamis untuk locale ini
844
+ // Digunakan untuk mendapatkan judul dan deskripsi yang diterjemahkan untuk metadata
845
+ const messages = (await import(`@/locales/${locale}/about.json`)).default;
846
+
847
+ // Membuat pemetaan hreflang untuk semua locale
848
+ // Membantu mesin pencari memahami alternatif bahasa
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 kanonik untuk versi locale ini
859
+ canonical: absoluteUrl(locale, "/about"),
860
+ // Alternatif bahasa untuk SEO (tag hreflang)
861
+ // "x-default" menentukan versi locale default
862
+ languages: {
863
+ ...languages,
864
+ "x-default": absoluteUrl(defaultLocale, "/about"),
865
+ },
866
+ },
867
+ };
868
+ }
869
+
870
+ export default async function AboutPage() {
871
+ return <h1>Tentang</h1>;
872
+ }
873
+ ```
874
+
875
+ ### (Opsional) Langkah 16: Internasionalisasi Sitemap Anda
876
+
877
+ Buat sitemap yang mencakup semua versi locale dari halaman Anda. Ini membantu mesin pencari menemukan dan mengindeks semua versi bahasa dari konten Anda.
878
+
879
+ Sitemap yang diinternasionalisasi dengan benar memastikan mesin pencari dapat menemukan dan mengindeks semua versi bahasa dari halaman Anda. Ini meningkatkan visibilitas dalam hasil pencarian internasional.
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
+ * Mendapatkan peta semua locale dan path yang dilokalkan
892
+ *
893
+ * Contoh output:
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
+ // Menghasilkan sitemap dengan semua varian locale untuk SEO yang lebih baik
908
+ // Field alternates memberi tahu mesin pencari tentang versi bahasa
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
+ ### (Opsional) Langkah 17: Internasionalisasi robots.txt Anda
930
+
931
+ Buat file robots.txt yang menangani semua versi locale dari rute yang dilindungi dengan benar. Ini memastikan bahwa mesin pencari tidak mengindeks halaman admin atau dashboard dalam bahasa apa pun.
932
+
933
+ Mengonfigurasi robots.txt dengan benar untuk semua locale mencegah mesin pencari mengindeks halaman sensitif dalam bahasa apa pun. Ini sangat penting untuk keamanan dan privasi.
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
+ // Menghasilkan path untuk semua locale (misalnya, /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
+ ### (Opsional) Langkah 18: Siapkan Middleware untuk Routing Locale
961
+
962
+ Buat proxy untuk secara otomatis mendeteksi locale yang dipilih pengguna dan mengarahkan mereka ke URL dengan prefix locale yang sesuai. Ini meningkatkan pengalaman pengguna dengan menampilkan konten dalam bahasa pilihan mereka.
963
+
964
+ Middleware memastikan bahwa pengguna secara otomatis diarahkan ke bahasa pilihan mereka saat mengunjungi situs Anda. Middleware juga menyimpan preferensi pengguna dalam cookie untuk kunjungan berikutnya.
965
+
966
+ ```ts fileName="src/proxy.ts"
967
+ import { NextResponse, type NextRequest } from "next/server";
968
+ import { defaultLocale, locales } from "@/i18n.config";
969
+
970
+ // Regex untuk mencocokkan file dengan ekstensi (misalnya .js, .css, .png)
971
+ // Digunakan untuk mengecualikan aset statis dari routing locale
972
+ const PUBLIC_FILE = /\.[^/]+$/;
973
+
974
+ /**
975
+ * Mengambil locale dari header Accept-Language
976
+ * Menangani format seperti "fr-CA", "en-US", dll.
977
+ * Kembali ke locale default jika bahasa browser tidak didukung
978
+ */
979
+ const pickLocale = (accept: string | null) => {
980
+ // Dapatkan preferensi bahasa pertama (misalnya, "fr-CA" dari "fr-CA,en-US;q=0.9")
981
+ const raw = accept?.split(",")[0] ?? defaultLocale;
982
+ // Ambil kode bahasa dasar (misalnya, "fr" dari "fr-CA")
983
+ const base = raw.toLowerCase().split("-")[0];
984
+ // Periksa apakah kita mendukung locale ini, jika tidak gunakan default
985
+ return (locales as readonly string[]).includes(base) ? base : defaultLocale;
986
+ };
987
+
988
+ /**
989
+ * Proxy Next.js untuk deteksi dan routing locale
990
+ * Berjalan pada setiap permintaan sebelum halaman dirender
991
+ * Secara otomatis mengarahkan ulang ke URL dengan prefix locale jika diperlukan
992
+ */
993
+ export function proxy(request: NextRequest) {
994
+ const { pathname } = request.nextUrl;
995
+
996
+ // Lewati proxy untuk internal Next.js, rute API, dan file statis
997
+ // Ini tidak boleh memiliki prefix 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
+ // Periksa apakah URL sudah memiliki prefix locale
1008
+ // Contoh: "/fr/about" atau "/en" akan mengembalikan true
1009
+ const hasLocale = (locales as readonly string[]).some(
1010
+ (locale) => pathname === `/${locale}` || pathname.startsWith(`/${locale}/`)
1011
+ );
1012
+
1013
+ // Jika tidak ada prefix locale, deteksi locale dan redirect
1014
+ if (!hasLocale) {
1015
+ // Coba dapatkan locale dari cookie terlebih dahulu (preferensi pengguna)
1016
+ const cookieLocale = request.cookies.get("NEXT_LOCALE")?.value;
1017
+
1018
+ // Gunakan locale dari cookie jika valid, jika tidak deteksi dari header browser
1019
+ const locale =
1020
+ cookieLocale && (locales as readonly string[]).includes(cookieLocale)
1021
+ ? cookieLocale
1022
+ : pickLocale(request.headers.get("accept-language"));
1023
+
1024
+ // Kloning URL untuk memodifikasi pathname
1025
+ const url = request.nextUrl.clone();
1026
+ // Tambahkan prefix locale ke pathname
1027
+ // Tangani root path secara khusus untuk menghindari double slash
1028
+ url.pathname = `/${locale}${pathname === "/" ? "" : pathname}`;
1029
+
1030
+ // Buat respons pengalihan dan set cookie locale
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
+ // Cocokkan semua path kecuali:
1040
+ // - Rute API (/api/*)
1041
+ // - Internal Next.js (/_next/*)
1042
+ // - File statis (/static/*)
1043
+ // - File dengan ekstensi (.*\\..*)
1044
+ "/((?!api|_next|static|.*\\..*).*)",
1045
+ ],
1046
+ };
1047
+ ```
1048
+
1049
+ ### (Opsional) Langkah 19: Otomatiskan Terjemahan Anda Menggunakan Intlayer
1050
+
1051
+ Intlayer adalah perpustakaan **gratis** dan **open-source** yang dirancang untuk membantu proses lokalisasi dalam aplikasi Anda. Sementara i18next menangani pemuatan dan pengelolaan terjemahan, Intlayer membantu mengotomatisasi alur kerja terjemahan.
1052
+
1053
+ Mengelola terjemahan secara manual bisa memakan waktu dan rentan terhadap kesalahan. Intlayer mengotomatisasi pengujian, pembuatan, dan pengelolaan terjemahan, menghemat waktu Anda dan memastikan konsistensi di seluruh aplikasi Anda.
1054
+
1055
+ Intlayer memungkinkan Anda untuk:
1056
+
1057
+ - **Mendeklarasikan konten Anda di mana pun Anda mau dalam codebase Anda**
1058
+ Intlayer memungkinkan Anda mendeklarasikan konten di mana pun Anda mau dalam codebase menggunakan file `.content.{ts|js|json}`. Ini akan memungkinkan organisasi konten yang lebih baik, memastikan keterbacaan dan pemeliharaan codebase yang lebih baik.
1059
+
1060
+ - **Menguji terjemahan yang hilang**
1061
+ Intlayer menyediakan fungsi pengujian yang dapat diintegrasikan dalam pipeline CI/CD Anda, atau dalam unit test Anda. Pelajari lebih lanjut tentang [mengujicoba terjemahan Anda](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/testing.md).
1062
+
1063
+ - **Otomatiskan terjemahan Anda**,
1064
+ Intlayer menyediakan CLI dan ekstensi VSCode untuk mengotomatisasi terjemahan Anda. Ini dapat diintegrasikan dalam pipeline CI/CD Anda. Pelajari lebih lanjut tentang [otomatisasi terjemahan Anda](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/intlayer_cli.md).
1065
+ Anda dapat menggunakan **kunci API Anda sendiri, dan penyedia AI pilihan Anda**. Ini juga menyediakan terjemahan yang sadar konteks, lihat [isi konten](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/autoFill.md).
1066
+
1067
+ - **Hubungkan konten eksternal**
1068
+ - **Otomatiskan terjemahan Anda**,
1069
+ Intlayer menyediakan CLI dan ekstensi VSCode untuk mengotomatisasi terjemahan Anda. Ini dapat diintegrasikan dalam pipeline CI/CD Anda. Pelajari lebih lanjut tentang [otomatisasi terjemahan Anda](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/intlayer_cli.md).
1070
+ Anda dapat menggunakan **API key Anda sendiri, dan penyedia AI pilihan Anda**. Ini juga menyediakan terjemahan yang sadar konteks, lihat [mengisi konten](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/autoFill.md).
1071
+
1072
+ - **Hubungkan konten eksternal**
1073
+ Intlayer memungkinkan Anda menghubungkan konten Anda ke sistem manajemen konten eksternal (CMS). Untuk mengambilnya dengan cara yang dioptimalkan dan memasukkannya ke dalam sumber daya JSON Anda. Pelajari lebih lanjut tentang [mengambil konten eksternal](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/function_fetching.md).
1074
+
1075
+ - **Editor visual**
1076
+ Intlayer menawarkan editor visual gratis untuk mengedit konten Anda menggunakan editor visual. Pelajari lebih lanjut tentang [pengeditan visual terjemahan Anda](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/intlayer_visual_editor.md).
1077
+
1078
+ Dan masih banyak lagi. Untuk menemukan semua fitur yang disediakan oleh Intlayer, silakan merujuk ke [Dokumentasi Manfaat Intlayer](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/interest_of_intlayer.md).