@intlayer/docs 9.5.2 → 9.5.3

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 (384) hide show
  1. package/README.md +1 -1
  2. package/blog/ar/i18next_vs_intlayer-i18next.md +327 -0
  3. package/blog/ar/i18next_vs_intlayer.md +445 -0
  4. package/blog/ar/is_i18next_outdated.md +1 -1
  5. package/blog/ar/is_next-intl_outdated.md +1 -1
  6. package/blog/ar/is_vue-i18n_outdated.md +1 -1
  7. package/blog/ar/lingui_vs_intlayer-lingui.md +304 -0
  8. package/blog/ar/lingui_vs_intlayer.md +381 -0
  9. package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  10. package/blog/ar/next-intl_vs_intlayer-next-intl.md +309 -0
  11. package/blog/ar/next-intl_vs_intlayer.md +397 -0
  12. package/blog/ar/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  13. package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +286 -0
  14. package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +0 -0
  15. package/blog/de/i18next_vs_intlayer-i18next.md +327 -0
  16. package/blog/de/i18next_vs_intlayer.md +445 -0
  17. package/blog/de/is_i18next_outdated.md +1 -1
  18. package/blog/de/is_next-intl_outdated.md +1 -1
  19. package/blog/de/is_vue-i18n_outdated.md +1 -1
  20. package/blog/de/lingui_vs_intlayer-lingui.md +304 -0
  21. package/blog/de/lingui_vs_intlayer.md +381 -0
  22. package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  23. package/blog/de/next-intl_vs_intlayer-next-intl.md +309 -0
  24. package/blog/de/next-intl_vs_intlayer.md +415 -0
  25. package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  26. package/blog/de/vue-i18n_vs_intlayer_benchmark.md +355 -0
  27. package/blog/en/i18next_vs_intlayer-i18next.md +327 -0
  28. package/blog/en/i18next_vs_intlayer.md +445 -0
  29. package/blog/en/is_i18next_outdated.md +1 -1
  30. package/blog/en/is_next-intl_outdated.md +1 -1
  31. package/blog/en/is_vue-i18n_outdated.md +1 -1
  32. package/blog/en/lingui_vs_intlayer-lingui.md +304 -0
  33. package/blog/en/lingui_vs_intlayer.md +381 -0
  34. package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  35. package/blog/en/next-intl_vs_intlayer-next-intl.md +309 -0
  36. package/blog/en/next-intl_vs_intlayer.md +415 -0
  37. package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  38. package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  39. package/blog/en/vue-i18n_vs_intlayer.md +1 -1
  40. package/blog/en/vue-i18n_vs_intlayer_benchmark.md +361 -0
  41. package/blog/en-GB/i18next_vs_intlayer-i18next.md +327 -0
  42. package/blog/en-GB/i18next_vs_intlayer.md +445 -0
  43. package/blog/en-GB/is_i18next_outdated.md +1 -1
  44. package/blog/en-GB/is_next-intl_outdated.md +1 -1
  45. package/blog/en-GB/is_vue-i18n_outdated.md +1 -1
  46. package/blog/en-GB/lingui_vs_intlayer-lingui.md +304 -0
  47. package/blog/en-GB/lingui_vs_intlayer.md +381 -0
  48. package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  49. package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +309 -0
  50. package/blog/en-GB/next-intl_vs_intlayer.md +415 -0
  51. package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  52. package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  53. package/blog/en-GB/vue-i18n_vs_intlayer.md +1 -1
  54. package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +245 -0
  55. package/blog/es/i18next_vs_intlayer-i18next.md +327 -0
  56. package/blog/es/i18next_vs_intlayer.md +445 -0
  57. package/blog/es/is_i18next_outdated.md +1 -1
  58. package/blog/es/is_next-intl_outdated.md +1 -1
  59. package/blog/es/is_vue-i18n_outdated.md +1 -1
  60. package/blog/es/lingui_vs_intlayer-lingui.md +304 -0
  61. package/blog/es/lingui_vs_intlayer.md +381 -0
  62. package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  63. package/blog/es/next-intl_vs_intlayer-next-intl.md +309 -0
  64. package/blog/es/next-intl_vs_intlayer.md +417 -0
  65. package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  66. package/blog/es/vue-i18n_vs_intlayer_benchmark.md +363 -0
  67. package/blog/fr/i18next_vs_intlayer-i18next.md +327 -0
  68. package/blog/fr/i18next_vs_intlayer.md +445 -0
  69. package/blog/fr/is_i18next_outdated.md +1 -1
  70. package/blog/fr/is_next-intl_outdated.md +1 -1
  71. package/blog/fr/is_vue-i18n_outdated.md +1 -1
  72. package/blog/fr/lingui_vs_intlayer-lingui.md +304 -0
  73. package/blog/fr/lingui_vs_intlayer.md +381 -0
  74. package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  75. package/blog/fr/next-intl_vs_intlayer-next-intl.md +309 -0
  76. package/blog/fr/next-intl_vs_intlayer.md +417 -0
  77. package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +287 -0
  78. package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +39 -0
  79. package/blog/hi/i18next_vs_intlayer-i18next.md +327 -0
  80. package/blog/hi/i18next_vs_intlayer.md +445 -0
  81. package/blog/hi/is_i18next_outdated.md +1 -1
  82. package/blog/hi/is_next-intl_outdated.md +1 -1
  83. package/blog/hi/is_vue-i18n_outdated.md +1 -1
  84. package/blog/hi/lingui_vs_intlayer-lingui.md +304 -0
  85. package/blog/hi/lingui_vs_intlayer.md +381 -0
  86. package/blog/hi/next-intl_vs_intlayer-next-intl.md +309 -0
  87. package/blog/hi/next-intl_vs_intlayer.md +397 -0
  88. package/blog/hi/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  89. package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  90. package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +0 -0
  91. package/blog/id/i18next_vs_intlayer-i18next.md +327 -0
  92. package/blog/id/i18next_vs_intlayer.md +445 -0
  93. package/blog/id/is_i18next_outdated.md +1 -1
  94. package/blog/id/is_next-intl_outdated.md +1 -1
  95. package/blog/id/is_vue-i18n_outdated.md +1 -1
  96. package/blog/id/lingui_vs_intlayer-lingui.md +304 -0
  97. package/blog/id/lingui_vs_intlayer.md +381 -0
  98. package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  99. package/blog/id/next-intl_vs_intlayer-next-intl.md +310 -0
  100. package/blog/id/next-intl_vs_intlayer.md +397 -0
  101. package/blog/id/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  102. package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +36 -0
  103. package/blog/id/vue-i18n_vs_intlayer.md +1 -1
  104. package/blog/id/vue-i18n_vs_intlayer_benchmark.md +41 -0
  105. package/blog/it/i18next_vs_intlayer-i18next.md +327 -0
  106. package/blog/it/i18next_vs_intlayer.md +445 -0
  107. package/blog/it/is_i18next_outdated.md +1 -1
  108. package/blog/it/is_next-intl_outdated.md +1 -1
  109. package/blog/it/is_vue-i18n_outdated.md +1 -1
  110. package/blog/it/lingui_vs_intlayer-lingui.md +304 -0
  111. package/blog/it/lingui_vs_intlayer.md +381 -0
  112. package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  113. package/blog/it/next-intl_vs_intlayer-next-intl.md +309 -0
  114. package/blog/it/next-intl_vs_intlayer.md +418 -0
  115. package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  116. package/blog/it/vue-i18n_vs_intlayer_benchmark.md +34 -0
  117. package/blog/ja/i18next_vs_intlayer-i18next.md +327 -0
  118. package/blog/ja/i18next_vs_intlayer.md +447 -0
  119. package/blog/ja/is_i18next_outdated.md +1 -1
  120. package/blog/ja/is_next-intl_outdated.md +1 -1
  121. package/blog/ja/is_vue-i18n_outdated.md +1 -1
  122. package/blog/ja/lingui_vs_intlayer-lingui.md +304 -0
  123. package/blog/ja/lingui_vs_intlayer.md +381 -0
  124. package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  125. package/blog/ja/next-intl_vs_intlayer-next-intl.md +310 -0
  126. package/blog/ja/next-intl_vs_intlayer.md +422 -0
  127. package/blog/ja/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  128. package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  129. package/blog/ja/vue-i18n_vs_intlayer.md +1 -1
  130. package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +0 -0
  131. package/blog/ko/i18next_vs_intlayer-i18next.md +327 -0
  132. package/blog/ko/i18next_vs_intlayer.md +447 -0
  133. package/blog/ko/is_i18next_outdated.md +1 -1
  134. package/blog/ko/is_next-intl_outdated.md +1 -1
  135. package/blog/ko/is_vue-i18n_outdated.md +1 -1
  136. package/blog/ko/lingui_vs_intlayer-lingui.md +304 -0
  137. package/blog/ko/lingui_vs_intlayer.md +381 -0
  138. package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  139. package/blog/ko/next-intl_vs_intlayer-next-intl.md +309 -0
  140. package/blog/ko/next-intl_vs_intlayer.md +397 -0
  141. package/blog/ko/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  142. package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  143. package/blog/ko/vue-i18n_vs_intlayer.md +1 -1
  144. package/blog/ko/vue-i18n_vs_intlayer_benchmark.md +366 -0
  145. package/blog/pl/i18next_vs_intlayer-i18next.md +327 -0
  146. package/blog/pl/i18next_vs_intlayer.md +445 -0
  147. package/blog/pl/is_i18next_outdated.md +1 -1
  148. package/blog/pl/is_next-intl_outdated.md +1 -1
  149. package/blog/pl/is_vue-i18n_outdated.md +1 -1
  150. package/blog/pl/lingui_vs_intlayer-lingui.md +304 -0
  151. package/blog/pl/lingui_vs_intlayer.md +381 -0
  152. package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  153. package/blog/pl/next-intl_vs_intlayer-next-intl.md +309 -0
  154. package/blog/pl/next-intl_vs_intlayer.md +397 -0
  155. package/blog/pl/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  156. package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +289 -0
  157. package/blog/pl/vue-i18n_vs_intlayer.md +1 -1
  158. package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +0 -0
  159. package/blog/pt/i18next_vs_intlayer-i18next.md +327 -0
  160. package/blog/pt/i18next_vs_intlayer.md +445 -0
  161. package/blog/pt/is_i18next_outdated.md +1 -1
  162. package/blog/pt/is_next-intl_outdated.md +1 -1
  163. package/blog/pt/is_vue-i18n_outdated.md +1 -1
  164. package/blog/pt/lingui_vs_intlayer-lingui.md +304 -0
  165. package/blog/pt/lingui_vs_intlayer.md +381 -0
  166. package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  167. package/blog/pt/next-intl_vs_intlayer-next-intl.md +309 -0
  168. package/blog/pt/next-intl_vs_intlayer.md +411 -0
  169. package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  170. package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +0 -0
  171. package/blog/ru/i18next_vs_intlayer-i18next.md +327 -0
  172. package/blog/ru/i18next_vs_intlayer.md +445 -0
  173. package/blog/ru/is_i18next_outdated.md +1 -1
  174. package/blog/ru/is_next-intl_outdated.md +1 -1
  175. package/blog/ru/is_vue-i18n_outdated.md +1 -1
  176. package/blog/ru/lingui_vs_intlayer-lingui.md +304 -0
  177. package/blog/ru/lingui_vs_intlayer.md +381 -0
  178. package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  179. package/blog/ru/next-intl_vs_intlayer-next-intl.md +309 -0
  180. package/blog/ru/next-intl_vs_intlayer.md +417 -0
  181. package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  182. package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +54 -0
  183. package/blog/tr/i18next_vs_intlayer-i18next.md +327 -0
  184. package/blog/tr/i18next_vs_intlayer.md +445 -0
  185. package/blog/tr/is_i18next_outdated.md +1 -1
  186. package/blog/tr/is_next-intl_outdated.md +1 -1
  187. package/blog/tr/is_vue-i18n_outdated.md +1 -1
  188. package/blog/tr/lingui_vs_intlayer-lingui.md +304 -0
  189. package/blog/tr/lingui_vs_intlayer.md +381 -0
  190. package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  191. package/blog/tr/next-intl_vs_intlayer-next-intl.md +309 -0
  192. package/blog/tr/next-intl_vs_intlayer.md +397 -0
  193. package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  194. package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  195. package/blog/tr/vue-i18n_vs_intlayer.md +1 -1
  196. package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +0 -0
  197. package/blog/uk/i18next_vs_intlayer-i18next.md +327 -0
  198. package/blog/uk/i18next_vs_intlayer.md +445 -0
  199. package/blog/uk/is_i18next_outdated.md +1 -1
  200. package/blog/uk/is_next-intl_outdated.md +1 -1
  201. package/blog/uk/is_vue-i18n_outdated.md +1 -1
  202. package/blog/uk/lingui_vs_intlayer-lingui.md +304 -0
  203. package/blog/uk/lingui_vs_intlayer.md +381 -0
  204. package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  205. package/blog/uk/next-intl_vs_intlayer-next-intl.md +309 -0
  206. package/blog/uk/next-intl_vs_intlayer.md +397 -0
  207. package/blog/uk/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  208. package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +270 -0
  209. package/blog/uk/vue-i18n_vs_intlayer.md +1 -1
  210. package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +0 -0
  211. package/blog/vi/i18next_vs_intlayer-i18next.md +327 -0
  212. package/blog/vi/i18next_vs_intlayer.md +445 -0
  213. package/blog/vi/is_i18next_outdated.md +1 -1
  214. package/blog/vi/is_next-intl_outdated.md +1 -1
  215. package/blog/vi/is_vue-i18n_outdated.md +1 -1
  216. package/blog/vi/lingui_vs_intlayer-lingui.md +304 -0
  217. package/blog/vi/lingui_vs_intlayer.md +381 -0
  218. package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  219. package/blog/vi/next-intl_vs_intlayer-next-intl.md +309 -0
  220. package/blog/vi/next-intl_vs_intlayer.md +397 -0
  221. package/blog/vi/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  222. package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  223. package/blog/vi/vue-i18n_vs_intlayer.md +1 -1
  224. package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +0 -0
  225. package/blog/zh/i18next_vs_intlayer-i18next.md +327 -0
  226. package/blog/zh/i18next_vs_intlayer.md +445 -0
  227. package/blog/zh/is_i18next_outdated.md +1 -1
  228. package/blog/zh/is_next-intl_outdated.md +1 -1
  229. package/blog/zh/is_vue-i18n_outdated.md +1 -1
  230. package/blog/zh/lingui_vs_intlayer-lingui.md +304 -0
  231. package/blog/zh/lingui_vs_intlayer.md +381 -0
  232. package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
  233. package/blog/zh/next-intl_vs_intlayer-next-intl.md +309 -0
  234. package/blog/zh/next-intl_vs_intlayer.md +422 -0
  235. package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
  236. package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
  237. package/blog/zh/vue-i18n_vs_intlayer.md +1 -1
  238. package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +30 -0
  239. package/dist/cjs/generated/blog.entry.cjs +160 -0
  240. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  241. package/dist/cjs/generated/frequentQuestions.entry.cjs +20 -0
  242. package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
  243. package/dist/esm/generated/blog.entry.mjs +160 -0
  244. package/dist/esm/generated/blog.entry.mjs.map +1 -1
  245. package/dist/esm/generated/frequentQuestions.entry.mjs +20 -0
  246. package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
  247. package/dist/types/generated/blog.entry.d.ts +8 -0
  248. package/dist/types/generated/blog.entry.d.ts.map +1 -1
  249. package/dist/types/generated/frequentQuestions.entry.d.ts +1 -0
  250. package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
  251. package/docs/ar/benchmark/nextjs.md +1 -1
  252. package/docs/ar/benchmark/solid.md +1 -1
  253. package/docs/ar/benchmark/svelte.md +1 -1
  254. package/docs/ar/benchmark/tanstack.md +1 -1
  255. package/docs/ar/benchmark/vue.md +1 -1
  256. package/docs/ar/interest_of_intlayer.md +1 -1
  257. package/docs/bn/interest_of_intlayer.md +1 -1
  258. package/docs/cs/interest_of_intlayer.md +1 -1
  259. package/docs/de/benchmark/nextjs.md +1 -1
  260. package/docs/de/benchmark/solid.md +1 -1
  261. package/docs/de/benchmark/svelte.md +1 -1
  262. package/docs/de/benchmark/tanstack.md +1 -1
  263. package/docs/de/benchmark/vue.md +1 -1
  264. package/docs/de/interest_of_intlayer.md +1 -1
  265. package/docs/en/benchmark/nextjs.md +1 -1
  266. package/docs/en/benchmark/solid.md +1 -1
  267. package/docs/en/benchmark/svelte.md +1 -1
  268. package/docs/en/benchmark/tanstack.md +1 -1
  269. package/docs/en/benchmark/vue.md +1 -1
  270. package/docs/en/interest_of_intlayer.md +1 -1
  271. package/docs/en-GB/benchmark/nextjs.md +1 -1
  272. package/docs/en-GB/benchmark/solid.md +1 -1
  273. package/docs/en-GB/benchmark/svelte.md +1 -1
  274. package/docs/en-GB/benchmark/tanstack.md +1 -1
  275. package/docs/en-GB/benchmark/vue.md +1 -1
  276. package/docs/en-GB/interest_of_intlayer.md +1 -1
  277. package/docs/es/benchmark/nextjs.md +1 -1
  278. package/docs/es/benchmark/solid.md +1 -1
  279. package/docs/es/benchmark/svelte.md +1 -1
  280. package/docs/es/benchmark/tanstack.md +1 -1
  281. package/docs/es/benchmark/vue.md +1 -1
  282. package/docs/es/interest_of_intlayer.md +1 -1
  283. package/docs/fr/benchmark/nextjs.md +1 -1
  284. package/docs/fr/benchmark/solid.md +1 -1
  285. package/docs/fr/benchmark/svelte.md +1 -1
  286. package/docs/fr/benchmark/tanstack.md +1 -1
  287. package/docs/fr/benchmark/vue.md +1 -1
  288. package/docs/fr/interest_of_intlayer.md +1 -1
  289. package/docs/hi/benchmark/nextjs.md +1 -1
  290. package/docs/hi/benchmark/solid.md +1 -1
  291. package/docs/hi/benchmark/svelte.md +1 -1
  292. package/docs/hi/benchmark/tanstack.md +1 -1
  293. package/docs/hi/benchmark/vue.md +1 -1
  294. package/docs/hi/interest_of_intlayer.md +1 -1
  295. package/docs/id/benchmark/nextjs.md +1 -1
  296. package/docs/id/benchmark/solid.md +1 -1
  297. package/docs/id/benchmark/svelte.md +1 -1
  298. package/docs/id/benchmark/tanstack.md +1 -1
  299. package/docs/id/benchmark/vue.md +1 -1
  300. package/docs/id/interest_of_intlayer.md +1 -1
  301. package/docs/it/benchmark/nextjs.md +1 -1
  302. package/docs/it/benchmark/solid.md +1 -1
  303. package/docs/it/benchmark/svelte.md +1 -1
  304. package/docs/it/benchmark/tanstack.md +1 -1
  305. package/docs/it/benchmark/vue.md +1 -1
  306. package/docs/it/interest_of_intlayer.md +1 -1
  307. package/docs/ja/benchmark/nextjs.md +1 -1
  308. package/docs/ja/benchmark/solid.md +1 -1
  309. package/docs/ja/benchmark/svelte.md +1 -1
  310. package/docs/ja/benchmark/tanstack.md +1 -1
  311. package/docs/ja/benchmark/vue.md +1 -1
  312. package/docs/ja/interest_of_intlayer.md +1 -1
  313. package/docs/ko/benchmark/nextjs.md +1 -1
  314. package/docs/ko/benchmark/solid.md +1 -1
  315. package/docs/ko/benchmark/svelte.md +1 -1
  316. package/docs/ko/benchmark/tanstack.md +1 -1
  317. package/docs/ko/benchmark/vue.md +1 -1
  318. package/docs/ko/interest_of_intlayer.md +1 -1
  319. package/docs/nl/interest_of_intlayer.md +1 -1
  320. package/docs/pl/benchmark/nextjs.md +1 -1
  321. package/docs/pl/benchmark/solid.md +1 -1
  322. package/docs/pl/benchmark/svelte.md +1 -1
  323. package/docs/pl/benchmark/tanstack.md +1 -1
  324. package/docs/pl/benchmark/vue.md +1 -1
  325. package/docs/pl/interest_of_intlayer.md +1 -1
  326. package/docs/pt/benchmark/nextjs.md +1 -1
  327. package/docs/pt/benchmark/solid.md +1 -1
  328. package/docs/pt/benchmark/svelte.md +1 -1
  329. package/docs/pt/benchmark/tanstack.md +1 -1
  330. package/docs/pt/benchmark/vue.md +1 -1
  331. package/docs/pt/interest_of_intlayer.md +1 -1
  332. package/docs/ru/benchmark/nextjs.md +1 -1
  333. package/docs/ru/benchmark/solid.md +1 -1
  334. package/docs/ru/benchmark/svelte.md +1 -1
  335. package/docs/ru/benchmark/tanstack.md +1 -1
  336. package/docs/ru/benchmark/vue.md +1 -1
  337. package/docs/ru/interest_of_intlayer.md +1 -1
  338. package/docs/tr/benchmark/nextjs.md +1 -1
  339. package/docs/tr/benchmark/solid.md +1 -1
  340. package/docs/tr/benchmark/svelte.md +1 -1
  341. package/docs/tr/benchmark/tanstack.md +1 -1
  342. package/docs/tr/benchmark/vue.md +1 -1
  343. package/docs/tr/interest_of_intlayer.md +1 -1
  344. package/docs/uk/benchmark/nextjs.md +1 -1
  345. package/docs/uk/benchmark/solid.md +1 -1
  346. package/docs/uk/benchmark/svelte.md +1 -1
  347. package/docs/uk/benchmark/tanstack.md +1 -1
  348. package/docs/uk/benchmark/vue.md +1 -1
  349. package/docs/uk/interest_of_intlayer.md +1 -1
  350. package/docs/ur/interest_of_intlayer.md +1 -1
  351. package/docs/vi/benchmark/nextjs.md +1 -1
  352. package/docs/vi/benchmark/solid.md +1 -1
  353. package/docs/vi/benchmark/svelte.md +1 -1
  354. package/docs/vi/benchmark/tanstack.md +1 -1
  355. package/docs/vi/benchmark/vue.md +1 -1
  356. package/docs/vi/interest_of_intlayer.md +1 -1
  357. package/docs/zh/benchmark/nextjs.md +1 -1
  358. package/docs/zh/benchmark/solid.md +1 -1
  359. package/docs/zh/benchmark/svelte.md +1 -1
  360. package/docs/zh/benchmark/tanstack.md +1 -1
  361. package/docs/zh/benchmark/vue.md +1 -1
  362. package/docs/zh/interest_of_intlayer.md +1 -1
  363. package/docs/zh-TW/interest_of_intlayer.md +1 -1
  364. package/frequent_questions/ar/claude_code_token_consumption.md +152 -0
  365. package/frequent_questions/de/claude_code_token_consumption.md +152 -0
  366. package/frequent_questions/en/claude_code_token_consumption.md +152 -0
  367. package/frequent_questions/en-GB/claude_code_token_consumption.md +152 -0
  368. package/frequent_questions/es/claude_code_token_consumption.md +152 -0
  369. package/frequent_questions/fr/claude_code_token_consumption.md +152 -0
  370. package/frequent_questions/hi/claude_code_token_consumption.md +152 -0
  371. package/frequent_questions/id/claude_code_token_consumption.md +152 -0
  372. package/frequent_questions/it/claude_code_token_consumption.md +152 -0
  373. package/frequent_questions/ja/claude_code_token_consumption.md +152 -0
  374. package/frequent_questions/ko/claude_code_token_consumption.md +152 -0
  375. package/frequent_questions/pl/claude_code_token_consumption.md +152 -0
  376. package/frequent_questions/pt/claude_code_token_consumption.md +152 -0
  377. package/frequent_questions/ru/claude_code_token_consumption.md +152 -0
  378. package/frequent_questions/tr/claude_code_token_consumption.md +152 -0
  379. package/frequent_questions/uk/claude_code_token_consumption.md +152 -0
  380. package/frequent_questions/vi/claude_code_token_consumption.md +152 -0
  381. package/frequent_questions/zh/claude_code_token_consumption.md +152 -0
  382. package/package.json +6 -6
  383. package/src/generated/blog.entry.ts +160 -0
  384. package/src/generated/frequentQuestions.entry.ts +20 -0
@@ -0,0 +1,309 @@
1
+ ---
2
+ createdAt: 2026-09-13
3
+ updatedAt: 2026-09-13
4
+ title: "next-intl vs @intlayer/next-intl: 동일한 API, 다른 번들"
5
+ description: Next.js 앱의 next-intl imports가 @intlayer/next-intl compat adapter에 의해 제공될 때 어떤 변화가 생기는지 알아봅니다. 동일한 코드에서 측정된 번들 크기, leakage, 컴포넌트 크기 및 hydration, 그리고 adapter가 유지하는 것, 무시하는 것 및 대체할 수 없는 것.
6
+ keywords:
7
+ - next-intl
8
+ - use-intl
9
+ - "@intlayer/next-intl"
10
+ - Intlayer
11
+ - Compat adapter
12
+ - Migration
13
+ - Internationalization
14
+ - i18n
15
+ - Benchmark
16
+ - Bundle size
17
+ - Blog
18
+ - Next.js
19
+ - TanStack Start
20
+ - React
21
+ slugs:
22
+ - blog
23
+ - next-intl-vs-intlayer-next-intl
24
+ author: aymericzip
25
+ ---
26
+
27
+ # next-intl VS @intlayer/next-intl | 동일한 API, 다른 번들
28
+
29
+ `@intlayer/next-intl`는 호환성 어댑터입니다. `next-intl` API (`useTranslations`, `getTranslations`, `useLocale`, `t.rich()`, ICU plurals, `NextIntlClientProvider`...)를 노출하고 Intlayer에서 컴파일한 딕셔너리로부터 제공합니다. 애플리케이션 코드는 변경되지 않습니다. 번들만 달라집니다.
30
+
31
+ 이 글은 동일한 Next.js 애플리케이션에서 `next-intl`로 한 번 빌드하고 어댑터로 한 번 빌드한 것을 비교합니다. 수치는 브라우저가 실제로 다운로드하는 내용을 기록하는 오픈소스 도구인 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom)에서 나옵니다. 라이브러리로서의 `next-intl` vs Intlayer 비교를 원한다면 [next-intl vs Intlayer](https://intlayer.org/blog/next-intl-vs-intlayer)를 읽어보세요. 이 글은 컴포넌트를 그대로 유지할 때 어댑터가 어떤 변화를 가져오는지에 관한 것입니다.
32
+
33
+ <TOC/>
34
+
35
+ > **요약**: 동일한 Next.js 앱에서 `next-intl`을 `@intlayer/next-intl`로 바꾼 경우, 페이지당 JavaScript는 **153.6 KB에서 147.5 KB** gzip으로, 평균 컴포넌트는 **21.8 KB에서 8.1 KB**로, 외부 페이지 문자열 누수는 **약 90%에서 0%**로, hydration은 **14.7ms에서 12.8ms**로 감소했으며, 수정된 컴포넌트가 없습니다. TanStack Start에서 `use-intl` 동등물(`@intlayer/use-intl`)은 컴포넌트를 **76-87 KB에서 9-11 KB**로 줄였고 로케일 전환은 **7-21ms에서 4-9ms**로 단축했습니다. 어댑터는 `next-intl`의 **14.7 KB** 및 네이티브 `next-intlayer`의 **5.5 KB**와 비교하여 **8.0 KB**의 런타임 비용이 발생합니다. 네비게이션과 미들웨어는 Intlayer의 라우팅 구성에서 다시 구현됩니다. 로컬라이즈된 `pathnames`은 전달되지 않는 유일한 기능입니다.
36
+
37
+ ## `@intlayer/next-intl`이란
38
+
39
+ `next-intl`는 런타임입니다: `getRequestConfig`는 요청당 `messages/{locale}.json`을 로드하고, `NextIntlClientProvider`는 이를 클라이언트로 전송하며, `useTranslations("about")`는 렌더링 시 해당 객체에서 키를 읽습니다. 모든 최적화(네임스페이스, 페이지당 `pick(messages, [...])`, 지연 로딩)는 직접 작성해야 합니다.
40
+
41
+ `@intlayer/next-intl`는 해당 체인의 첫 번째와 마지막 부분을 유지하고 중간 부분을 대체합니다. 컴포넌트는 여전히 `useTranslations("about")`을 호출합니다. 그들이 받는 것은 빌드 시에 컴파일되고 해당 컴포넌트로 범위가 지정된 Intlayer 딕셔너리에서 활성 로케일에서만 제공됩니다.
42
+
43
+ 세 가지 메커니즘이 이를 작동하게 합니다:
44
+
45
+ 1. **Import aliasing.** `createNextIntlPlugin()`(from `@intlayer/next-intl/plugin`)은 `withIntlayer`을 래핑하고 Webpack / Turbopack aliases를 추가하여 `next-intl`, `next-intl/server`, `next-intl/navigation` 및 `next-intl/middleware`가 `@intlayer/next-intl`로 resolve되도록 합니다. 당신의 codebase에서 import는 이름이 변경되지 않습니다.
46
+ 2. **JSON as source of truth.** `syncJSON` plugin은 기존 `messages/{locale}.json`을 읽고, 최상위 수준의 키를 네임스페이스당 하나의 dictionary로 분할하며, CLI나 CMS가 업데이트할 때 동일한 파일에 번역을 다시 작성합니다. 번역가의 workflow는 변경되지 않습니다.
47
+ 3. **Call-site binding.** Intlayer optimize pass (Babel 또는 SWC)는 `useTranslations("about")`을 `about` dictionary를 직접 받는 call로 다시 작성합니다. 컴포넌트는 더 이상 global message tree에 접근하지 않고, 자신의 content에만 접근합니다.
48
+
49
+ ```tsx fileName="app/[locale]/about/page.tsx"
50
+ // 당신의 코드, 변경 없음
51
+ import { useTranslations } from "next-intl";
52
+
53
+ const AboutPage = () => {
54
+ const t = useTranslations("about");
55
+ return <h1>{t("title")}</h1>;
56
+ };
57
+ ```
58
+
59
+ ```tsx fileName="컴파일러가 내보내는 것 (단순화됨)"
60
+ import _dicHash_about from "../.intlayer/dictionaries/about.mjs";
61
+ import { useDictionary as useTranslations } from "@intlayer/next-intl";
62
+
63
+ const AboutPage = () => {
64
+ const t = useTranslations(_dicHash_about);
65
+ return <h1>{t("title")}</h1>;
66
+ };
67
+ ```
68
+
69
+ 그 리라이트가 아래의 component-size 및 page-leakage 열을 이동시키는 이유입니다: 페이지는 자신이 렌더링하는 컴포넌트의 사전만 가져오며, 제공되는 로케일에서만 가져옵니다.
70
+
71
+ ## 어댑터가 유지, 무시 및 대체하지 않는 것
72
+
73
+ | `next-intl` API | `@intlayer/next-intl` 사용 |
74
+ | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
75
+ | `useTranslations("ns")` / `getTranslations("ns")` | ✅ 유지됨. 빌드 시간에 `ns` 사전에 바인딩됨. 키는 당신의 콘텐츠에 대해 타입되어 있습니다. |
76
+ | `getTranslations({ locale, namespace })` | ✅ 유지됨 |
77
+ | `t("key", { name })`, `t.rich()`, `t.markup()`, `t.raw()` | ✅ 유지됨. ICU plurals, `select`, `selectordinal`, `#`, `{ts, date, long}`는 Intlayer의 ICU resolver를 통해 실행됨 |
78
+ | `useLocale()` / `getLocale()` / `setRequestLocale()` / `setLocale` | ✅ 유지됨 |
79
+ | `useFormatter()` | ✅ 유지됨. `dateTime`, `number`, `relativeTime`, `list`, `dateTimeRange`는 네이티브 `Intl`로 연결됨 |
80
+ | `NextIntlClientProvider` | ✅ 유지됨. `messages`, `timeZone` 및 `now` props는 **수락되지만 무시됨** (개발자 경고가 표시됨) |
81
+ | `getMessages()` | ✅ 호환성을 위해 유지됨; 더 이상 필요하지 않음 |
82
+ | `getRequestConfig()` in `src/i18n.ts` | ⚠️ 필요하지 않음. 사전은 빌드 시간에 컴파일됨; 요청별 메시지 로딩이 없음 |
83
+ | `defineRouting()` | ✅ 유지됨. 생략된 필드(`locales`, `defaultLocale`, `localePrefix`)는 `intlayer.config.ts`에서 읽음 |
84
+ | `createNavigation()`, `Link`, `redirect`, `usePathname`, `useRouter` | ✅ 유지됨. Intlayer의 라우팅 설정에서 다시 구현됨; `routing` 인자는 허용되지만 무시됨 |
85
+ | `pathnames` (지역화된 경로명) | ❌ 타입 지정을 위해 허용되지만, **보간되지 않음**. 평문 경로명을 유지하거나 해당 매핑을 Intlayer의 `rewrite`로 이동 |
86
+ | `createMiddleware()` | ✅ 유지됨. Intlayer의 프록시를 반환; `useLocale()` 및 스위처가 작동하도록 `NEXT_LOCALE` 쿠키를 설정 |
87
+ | `NEXT_LOCALE` 쿠키 | ✅ 기본적으로 읽음 (`routing.storage`를 직접 설정하지 않는 한) |
88
+ | Bare `useTranslations()` with no namespace | ⚠️ Works, but the call site is not bound: it resolves through the runtime registry. Pass a namespace to get the bundle gains |
89
+
90
+ ## 벤치마크
91
+
92
+ ### 측정 항목
93
+
94
+ [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) suite는 각 설정으로 **동일한 애플리케이션**을 빌드합니다: **10개의 페이지** (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), **10개의 locale** (`en`, `fr`, `es`, `de`, `it`, `pt`, `zh`, `ja`, `ko`, `ru`), 동일한 컴포넌트 및 동일한 콘텐츠. 페이지는 `en` 및 `fr`에서 측정됩니다.
95
+
96
+ `next-intl`은 네 가지 로딩 전략으로 구축되었습니다. 가장 단순한 설정(`messages/{locale}.json` 전체 로드)부터 최적화된 설정(경로당 하나의 namespace + 페이지당 `pick()`)까지입니다. 어댑터는 **naive 설정과 동일한 컴포넌트**로 구축되었으며, `next.config.ts`와 `intlayer.config.ts`만 변경되었습니다. "scoped" variant는 없습니다: 컴파일러가 컴포넌트당 콘텐츠를 스코프하므로, `static`과 `dynamic` 행이 이미 스코프되어 있습니다.
97
+
98
+ 각 빌드마다, 스위트는 다음을 기록합니다:
99
+
100
+ - **Lib size**: i18n 라이브러리만 import하는 빈 컴포넌트의 gzip 크기입니다. 런타임의 고정 비용입니다.
101
+ - **Page JS**: 페이지당 다운로드되는 gzip JavaScript이며, 모든 페이지와 로케일에 대해 평균을 냅니다.
102
+ - **Locale leak %**: 사용자가 **보고 있지 않은** locale에 속하는 다운로드된 JS의 번역된 문자열의 비율.
103
+ - **Page leak %**: 사용자가 **방문하지 않은** 페이지에 속하는 다운로드된 JS의 번역된 문자열의 비율.
104
+ - **Component avg**: isolation에서 컴파일된 각 component의 평균 gzip 크기. 단일 component가 i18n runtime 및 catalog에 미치는 영향을 보여줍니다.
105
+ - **E2E reactivity**: 새로운 locale을 선택한 후 DOM의 `html[lang]` 업데이트까지의 실제 경과 시간 (Playwright, 5회 반복).
106
+ - **Hydration**: React hydration 단계 지속 시간.
107
+
108
+ > 아래의 숫자는 **2026-09-12**에 실행된 결과이며, `next-intl` / `use-intl` 4.14.2 및 `@intlayer/*` 9.5.1을 사용합니다. 테스트 애플리케이션은 의도적으로 작습니다 (locale당 몇십 개의 문자열), 따라서 누수 비율은 **패턴**을 설명합니다: runtime 비용이 고정되어 있는 동안 콘텐츠가 증가하면 증가합니다.
109
+
110
+ ### Next.js 결과
111
+
112
+ | Setup | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
113
+ | ------------------------- | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | ----------: |
114
+ | **base** (i18n 없음) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
115
+ | `next-intl` | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
116
+ | `next-intl` | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
117
+ | `next-intl` | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
118
+ | `next-intl` | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
119
+ | **`@intlayer/next-intl`** | static | **8.0 KB** | **147.5 KB** | **0.0%** | **0.0%** | **8.1 KB** | **14.5 ms** | **12.8 ms** |
120
+ | **`@intlayer/next-intl`** | dynamic | **8.0 KB** | **148.7 KB** | **0.0%** | **0.0%** | **8.1 KB** | **11.7 ms** | **12.8 ms** |
121
+ | `next-intlayer` (native) | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
122
+ | `next-intlayer` (native) | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
123
+
124
+ **읽는 방법**
125
+
126
+ - **동일한 컴포넌트, 페이지당 6 KB 절약.** 어댑터로 빌드한 naive 앱은 **147.5 KB**에 도달하여, 완전히 최적화된 설정(153.6 KB)을 포함한 모든 `next-intl` 구성보다 작습니다. 런타임 자체가 차이입니다: 8.0 KB 대 14.7 KB, 모든 페이지에서 지불됩니다.
127
+ - **누수가 컴포넌트를 건드리지 않고 0%로 간다.** 순진한 `next-intl` 설정은 모든 페이지에서 ~90%의 외국어 페이지 문자열을 배송한다. `next-intl`으로 0%에 도달하려면 `scoped-*` 설정을 의미한다: 라우트당 하나의 네임스페이스, 각 페이지에서 `pick(messages, [...])`. 어댑터는 각 `useTranslations("ns")`를 자신의 딕셔너리에 바인딩하는 optimize 패스 때문에 순진한 코드에서 0%에 도달한다.
128
+ - **컴포넌트가 2.7배 축소된다.** 격리된 상태로 컴파일된 컴포넌트는 `next-intl`로 평균 **21.8 KB** (제공자와 메시지 트리에 도달함)이고 어댑터로 **8.1 KB**이다. `next-intl`의 `scoped-static` 설정에서는 모든 라우트의 네임스페이스 파일이 그것을 선택하는 페이지에서 도달할 수 있기 때문에 그 숫자가 _80 KB로 올라간다_.
129
+ - **Hydration이 2ms 더 빠릅니다** (12.8 vs 14.7 ms): React가 hydrate되기 전에 RSC payload에서 deserialize할 message object가 없습니다.
130
+ - **adapter는 native runtime이 아닙니다.** `next-intlayer`는 **141.3 KB**에 위치하며, base app보다 +0.3 KB이고, 5.5 KB runtime을 가집니다. adapter는 Intlayer의 core 위에 `next-intl` API surface (`useFormatter`, `t.rich`, the ICU resolver)를 제공하므로, 8.0 KB이고 page당 +6 KB입니다. 이것은 bridge이지, destination이 아닙니다.
131
+
132
+ ### TanStack Start (`use-intl`)에서의 결과
133
+
134
+ `use-intl`은 `next-intl`의 framework-agnostic core입니다. 이의 adapter인 `@intlayer/use-intl`은 Vite plugin (`@intlayer/use-intl/plugin`)과 함께 동일한 design을 따릅니다.
135
+
136
+ | Setup | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
137
+ | ------------------------ | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | ----------: |
138
+ | **base** (no i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
139
+ | `use-intl` | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms | 15.3 ms |
140
+ | `use-intl` | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms | 15.4 ms |
141
+ | `use-intl` | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms | 24.8 ms |
142
+ | `use-intl` | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms | 25.9 ms |
143
+ | **`@intlayer/use-intl`** | static | **7.3 KB** | 135.8 KB | 49.7% | **0.0%** | **10.9 KB** | **4.2 ms** | **10.5 ms** |
144
+ | **`@intlayer/use-intl`** | dynamic | **7.3 KB** | **129.7 KB** | **0.0%** | **0.0%** | **9.3 KB** | **8.7 ms** | 16.1 ms |
145
+ | `intlayer` (native) | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms | 11.5 ms |
146
+ | `intlayer` (native) | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms | 14.1 ms |
147
+
148
+ **읽는 방법**
149
+
150
+ - **페이지당 바이트는 최적화된 `use-intl`과 비슷합니다.** `dynamic` 모드의 `@intlayer/use-intl` (129.7 KB)은 `use-intl`의 `scoped-dynamic` (128.7 KB)과 1 KB 이내 차이가 나며, `use-intl`의 일반 `dynamic` (119.4 KB)보다 10 KB _많습니다_. 그 일반 `dynamic` 행은 여전히 외부 페이지 문자열의 90%가 누출됩니다; 바이트 수가 낮은 이유는 테스트 앱의 콘텐츠가 작기 때문입니다. 어댑터의 0%는 콘텐츠가 증가해도 평탄하게 유지되는 것입니다.
151
+ - **컴포넌트가 7-9배 더 작습니다.** `use-intl` 컴포넌트는 모든 전략에서 평균 **76-87 KB**이며, 이는 `useTranslations`가 제공자의 전체 메시지 객체에 바인딩되기 때문입니다. 어댑터는 평균 **9-11 KB**입니다.
152
+ - **로케일 전환이 더 빠릅니다.** 최적화된 `use-intl` 설정은 `html[lang]`을 업데이트하는 데 **13-21 ms**가 소요되고, 어댑터는 **4-9 ms**가 소요됩니다. 더 적은 컴포넌트가 다시 렌더링되고, 메시지 트리에서 아무것도 다시 선택되지 않습니다.
153
+ - **`static`은 모든 로케일을 유지합니다.** 어댑터의 `static` 행은 49.7%의 로케일 누수를 표시하며, 이는 `static` 모드의 네이티브 Intlayer와 동일합니다. 모든 로케일이 번들로 제공되지만 페이지의 사전만 번들로 제공됩니다. 한 줄의 설정 (`importMode: 'dynamic'`)으로 이를 제거할 수 있습니다.
154
+
155
+ ## 숫자가 변하는 이유
156
+
157
+ 컴포넌트에서 아무것도 변경되지 않았으므로, 이득은 전적으로 `useTranslations`가 바인딩된 대상에서 비롯됩니다.
158
+
159
+ **`next-intl`을 사용할 때**, 바인딩은 provider입니다. `NextIntlClientProvider`는 locale에 대한 전체 `messages` 객체를 받으며, 모든 `useTranslations("about")`은 이것을 읽습니다. bundler는 하나의 컴포넌트가 하나의 hook을 import하고 하나의 context를 읽는 것을 보지만, 오직 `about` 브랜치만 사용되는지 알 수 없습니다. 아래의 routes는 모두 동일한 message 객체를 공유하므로, page-leak 열은 파일을 직접 분할할 때까지 ~90%를 표시합니다.
160
+
161
+ ```bash
162
+ .
163
+ ├── messages
164
+ │ ├── en.json # 모든 namespace, 모든 page
165
+ │ └── fr.json
166
+ └── src
167
+ ├── i18n.ts # getRequestConfig({ messages: await import(...) })
168
+ ├── middleware.ts # createMiddleware(routing)
169
+ └── app/[locale]
170
+ ├── layout.tsx # <NextIntlClientProvider messages={messages}>
171
+ └── about/page.tsx # useTranslations("about")
172
+ ```
173
+
174
+ **`@intlayer/next-intl`를 사용하는 경우**, 바인딩은 dictionary입니다. `syncJSON`은 `messages/en.json`을 top-level key당 하나의 dictionary로 변환합니다. 컴파일러는 `useTranslations("about")`을 호출하는 컴포넌트를 식별하고 활성 locale에서 `about`을 직접 제공하며, bundler가 추적하고 분할할 수 있는 import로 전달합니다.
175
+
176
+ ```bash
177
+ .
178
+ ├── intlayer.config.ts # syncJSON({ source: ({ locale }) => `./messages/${locale}.json` })
179
+ ├── messages
180
+ │ ├── en.json # 변경 없음, 여전히 source of truth
181
+ │ └── fr.json
182
+ ├── .intlayer/ # 생성됨: namespace당, locale당 하나의 dictionary
183
+ └── src
184
+ ├── middleware.ts # createMiddleware() 이제 Intlayer의 proxy를 반환합니다
185
+ └── app/[locale]
186
+ ├── layout.tsx # <NextIntlClientProvider> (messages prop 없음)
187
+ └── about/page.tsx # useTranslations("about") ← 변경되지 않음
188
+ ```
189
+
190
+ `src/i18n.ts`와 `messages` prop이 사라집니다. 나머지는 모두 동일합니다.
191
+
192
+ ## 3단계로 마이그레이션
193
+
194
+ <Steps>
195
+ <Step number={1} title="설치">
196
+
197
+ ```bash packageManager="npm"
198
+ npx intlayer init --interactive
199
+ ```
200
+
201
+ ```bash packageManager="pnpm"
202
+ pnpm dlx intlayer init --interactive
203
+ ```
204
+
205
+ ```bash packageManager="yarn"
206
+ yarn dlx intlayer init --interactive
207
+ ```
208
+
209
+ ```bash packageManager="bun"
210
+ bunx intlayer init --interactive
211
+ ```
212
+
213
+ 이 명령은 `next-intl`을 감지하고 `intlayer`, `next-intlayer`, `@intlayer/next-intl` 및 `@intlayer/sync-json-plugin`을 설치합니다. `next-intl`을 계속 설치된 상태로 유지하세요: 이는 어댑터의 peer dependency이며 타입을 제공합니다.
214
+
215
+ </Step>
216
+ <Step number={2} title="Intlayer를 메시지 위치로 지정">
217
+
218
+ ```ts fileName="intlayer.config.ts"
219
+ import { Locales, type IntlayerConfig } from "intlayer";
220
+ import { syncJSON } from "@intlayer/sync-json-plugin";
221
+
222
+ const config: IntlayerConfig = {
223
+ internationalization: {
224
+ locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
225
+ defaultLocale: Locales.ENGLISH,
226
+ },
227
+ dictionary: {
228
+ // "static"은 모든 locale을 번들로 묶고; "dynamic"은 활성화된 것만 요청 시 로드합니다
229
+ importMode: "dynamic",
230
+ },
231
+ plugins: [
232
+ syncJSON({
233
+ // ICU placeholders: {name}, {count, plural, one {# item} other {# items}}
234
+ format: "icu",
235
+ source: ({ locale }) => `./messages/${locale}.json`,
236
+ location: "messages",
237
+ }),
238
+ ],
239
+ };
240
+
241
+ export default config;
242
+ ```
243
+
244
+ `messages/{locale}.json`은 현재 위치에 유지됩니다. 각 최상위 키는 dictionary가 되며, `useTranslations("about")`은 `about` dictionary에 매핑됩니다.
245
+
246
+ </Step>
247
+ <Step number={3} title="next.config.ts 래핑">
248
+
249
+ ```ts fileName="next.config.ts"
250
+ import type { NextConfig } from "next";
251
+ import { createNextIntlPlugin } from "@intlayer/next-intl/plugin";
252
+
253
+ const withIntlayer = createNextIntlPlugin();
254
+
255
+ const nextConfig: NextConfig = {};
256
+
257
+ export default withIntlayer(nextConfig);
258
+ ```
259
+
260
+ `createNextIntlPlugin()`은 `withIntlayer`(콘텐츠 감시, 사전 컴파일, 최적화 패스)와 Webpack 및 Turbopack을 위한 `next-intl` → `@intlayer/next-intl` 별칭을 구성합니다. 빌드하면 위 테이블의 숫자들이 당신의 것이 됩니다.
261
+
262
+ </Step>
263
+ </Steps>
264
+
265
+ ### 나중에 삭제할 수 있는 항목
266
+
267
+ | 파일 / 패턴 | 이유 |
268
+ | -------------------------------------------- | ---------------------------------------------------------------------------------------- |
269
+ | `src/i18n.ts`의 `getRequestConfig` | 요청별 메시지 로딩 없음. 파일은 `createNavigation` 헬퍼도 내보내는 경우에만 유지하세요 |
270
+ | `messages={...}` on `NextIntlClientProvider` | The adapter reads compiled output; the prop is ignored and logs a warning in development |
271
+ | `await getMessages()` in layouts | Same reason |
272
+ | Per-page `pick(messages, [...])` | The compiler does the picking, per component |
273
+
274
+ ### 바이트 이상으로 얻을 수 있는 것
275
+
276
+ - **타입 안전 키.** `useTranslations("about")`는 컴파일된 `about` 딕셔너리에 대해 타입이 지정됩니다. `t("does.not.exist")`는 런타임 폴백이 아닌 TypeScript 에러입니다.
277
+ - **`npx intlayer test`**는 locale이 key를 누락하면 CI를 실패시킵니다. **`npx intlayer fill`**은 선택한 provider(OpenAI, Anthropic, Mistral, Gemini...)를 사용하여 누락된 것들을 번역하고, 자신의 key를 사용하여 결과를 `messages/{locale}.json`에 다시 씁니다.
278
+ - **Visual Editor와 CMS**는 동일한 dictionaries에서 작동하므로, 개발자가 아닌 사람도 UI를 통해 `messages/fr.json`을 편집할 수 있으며 파일이 업데이트됩니다.
279
+ - **`.content.ts`로의 점진적 이동.** 모든 component는 `useTranslations("about")`에서 co-located content 파일과 함께 `useIntlayer("about")`로 전환할 수 있으며, 한 번에 하나씩 가능합니다. JSON과 `.content.ts` dictionaries는 공존하며 병합됩니다.
280
+
281
+ ## 시작하기 전에 알아야 할 제한사항
282
+
283
+ - **라우팅 설정이 `intlayer.config.ts`로 이동합니다.** `createNavigation(routing)`과 `createMiddleware(routing)`은 시그니처를 유지하지만 인수는 무시합니다: locale, 기본 locale, prefix 전략은 Intlayer의 `routing` 설정에서 가져옵니다. `next-intl`의 로컬라이제이션된 `pathnames`(`/about` → `/a-propos`)을 사용하는 경우, 어댑터는 이를 보간하지 않습니다; Intlayer의 `routing.rewrite`가 해당 경우를 다루지만 별도의 변경입니다.
284
+ - **Namespace 없는 `useTranslations()`은 바인드되지 않습니다.** 최적화 패스는 어떤 dictionary를 import할지 알기 위해 정적 namespace가 필요합니다. 베어 호출은 여전히 작동하지만, 모든 dictionary를 참조하는 runtime registry를 통해 작동하며, 이는 정확히 제거하려고 했던 누수입니다. namespace를 전달하세요.
285
+ - **어댑터는 무료가 아닙니다.** 8.0 KB의 런타임 대 `next-intlayer`의 5.5 KB, 그리고 네이티브 빌드에 비해 페이지당 +6-7 KB입니다. 이는 `next-intl` API 표면의 비용입니다. 모든 컴포넌트가 `useIntlayer`로 이동된 지점에 도달하면 어댑터를 제거하세요.
286
+ - **공급자의 `messages`, `timeZone`, `now`는 무시됩니다.** 포매터는 네이티브 `Intl`로 지원되며 로케일만이 출력에 영향을 미칩니다. 강제 타임존 또는 하이드레이션 안정적인 날짜를 위한 고정된 `now`에 의존하는 경우 호출 사이트에서 처리하세요.
287
+
288
+ ## 어느 것을 언제 사용할까요?
289
+
290
+ - **`next-intl`에 머물러야 합니다** 앱이 작고, 번들이 걱정사항이 아니며, 팀이 네임스페이스와 페이지당 `pick()`을 관리하는 데 능숙한 경우입니다.
291
+ - **`@intlayer/next-intl`를 사용하세요.** 현재 `next-intl`을 사용 중이며 번들 크기, 누수 및 하이드레이션 개선, 타입 안전 키, CLI/CMS 도구를 원하지만 전체 재작성은 피하고 싶다면 이를 사용하세요. 이것은 기존의 모든 `next-intl` codebase를 위한 권장되는 진입점입니다.
292
+ - **네이티브 (`next-intlayer`)로 이동하세요.** 새로운 프로젝트에서, 또는 adapter가 역할을 다한 후에 이동하세요. 이는 세 가지 중 가장 가벼운 옵션입니다 (5.5 KB, 페이지당 +0.3 KB) 그리고 동기식 서버 컴포넌트, 컴포넌트별 `.content.ts` 파일 및 전체 기능 세트를 활용할 수 있습니다.
293
+
294
+ ## 관련 비교
295
+
296
+ - [next-intl vs Intlayer](https://intlayer.org/blog/next-intl-vs-intlayer) (라이브러리, 동일한 벤치마크)
297
+ - [i18next vs @intlayer/i18next](https://intlayer.org/blog/i18next-vs-intlayer-i18next) (동일한 adapter 시리즈)
298
+ - [Lingui vs @intlayer/lingui](https://intlayer.org/blog/lingui-vs-intlayer-lingui) (동일 어댑터 시리즈)
299
+ - [vue-i18n vs @intlayer/vue-i18n](https://intlayer.org/blog/vue-i18n-vs-intlayer-vue-i18n) (동일 어댑터 시리즈)
300
+ - [마이그레이션 가이드: next-intl to Intlayer](https://intlayer.org/doc/migration/next-intl)
301
+ - [호환성 어댑터 레퍼런스: next-intl](https://intlayer.org/doc/compatibility/next-intl)
302
+
303
+ ## 결론
304
+
305
+ `@intlayer/next-intl`은 한 가지를 수행합니다: `useTranslations`이 바인딩되는 대상을 모든 메시지를 보유한 provider에서 해당 컴포넌트를 위해 컴파일된 dictionary로 변경합니다. **페이지당 6 KB**의 크기로 **2.7배 더 작은 컴포넌트**, **0% 누수**, 그리고 누구든 컴포넌트 파일을 열기 전에 **2ms의 hydration**을 제공하는 동일한 Next.js 앱에서 말입니다. Navigation과 middleware는 Intlayer의 routing config 위에 API를 유지하며, native `next-intlayer` runtime은 여전히 더 가볍습니다.
306
+
307
+ 모든 raw data, test app 및 script는 [Benchmark Bloom repository](https://github.com/intlayer-org/benchmark-bloom)에 있습니다. 직접 실행해보세요.
308
+
309
+ 자세한 내용은 ['Why Intlayer?' doc](https://intlayer.org/doc/why)을 참조하세요.