@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,447 @@
1
+ ---
2
+ createdAt: 2026-09-13
3
+ updatedAt: 2026-09-13
4
+ title: "i18next vs Intlayer: 2026 벤치마크 및 비교"
5
+ description: "Next.js 및 TanStack Start 환경에서 react-i18next와 next-i18next를 Intlayer와 비교 측정한 결과. 번들 크기, 콘텐츠 누출, 로케일 전환 반응성 및 개발자 경험 분석."
6
+ keywords:
7
+ - i18next
8
+ - react-i18next
9
+ - next-i18next
10
+ - Intlayer
11
+ - 국제화
12
+ - i18n
13
+ - 벤치마크
14
+ - 번들 크기
15
+ - 블로그
16
+ - Next.js
17
+ - TanStack Start
18
+ - JavaScript
19
+ - React
20
+ slugs:
21
+ - blog
22
+ - i18next-vs-intlayer
23
+ author: aymericzip
24
+ ---
25
+
26
+ # i18next VS Intlayer | React & Next.js 국제화 (i18n) 벤チ마크 비교
27
+
28
+ `i18next`는 JavaScript 생태계에서 가장 널리 사용되는 i18n 프레임워크입니다. `react-i18next`와 `next-i18next`를 통해 수많은 React 및 Next.js 애플리케이션의 다국어를 지원하고 있습니다. Intlayer는 컴파일러 기반의 컴포넌트 스코프 콘텐츠 아키텍처를 제공하는 대안입니다.
29
+
30
+ 이 글에서는 단순한 기능 나열 대신 실제 측정 지표를 바탕으로 두 솔루션을 비교합니다. 모든 수치는 동일한 애플리케이션을 각 라이브러리로 빌드하고 브라우저가 실제로 다운로드하는 리소스를 기록하는 오픈 소스 벤치마크 제품군 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom)에서 추출되었습니다.
31
+
32
+ <TOC/>
33
+
34
+ > **요약**: `i18next`는 벤치마크에서 가장 무거운 런타임입니다. 기본 설정의 Next.js에서 **페이지당 +77 KB gzip**, 네임스페이스와 지연 로딩을 완전히 최적화한 후에도 **+22 KB**가 추가됩니다. 반면 Intlayer의 증가량은 **+0.3 KB**에 불과합니다. 완전히 스코프가 분리된 설정을 제외한 모든 `i18next` 구성은 **방문하지 않은 페이지의 문자열을 약 90% 누출**시키지만, Intlayer는 기본적으로 **0%**입니다. 지연 로드 백엔드를 통한 로케일 전환 시간은 `react-i18next`가 **123-185 ms**인 반면 Intlayer는 **3-4 ms**였습니다. `i18next` API를 그대로 유지하는 호환 어댑터 `@intlayer/next-i18next`는 원본의 **218.5 KB**에서 **150.7 KB**로 페이지 크기를 줄였습니다.
35
+
36
+ ## 요약 비교
37
+
38
+ - **i18next / react-i18next / next-i18next** - 성숙하고 플러그인이 풍부하며 프레임워크에 구애받지 않습니다. 네임스페이스, 언어 감지기, 백엔드, 플러그인을 통한 ICU 지원, 서식 있는 텍스트를 위한 `<Trans>` 컴포넌트를 제공합니다. 콘텐츠는 `locales/{lng}/{ns}.json`에 중앙 집중화되어 관리됩니다. 강력하지만 모든 최적화(네임스페이스 분할, 페이지별 로딩, 타입 안전성)를 개발자가 직접 구성하고 관리해야 합니다.
39
+ - **Intlayer** - 컴포넌트 중심의 콘텐츠 모델입니다. `.content.ts` 사전 파일이 지원하는 컴포넌트 바로 옆에 위치하며, 빌드 타임 컴파일러가 컴포넌트 및 로케일별로 트리 쉐이킹과 지연 로딩을 수행합니다. 작성한 콘텐츠로부터 엄격한 TypeScript 타입이 자동 생성되고, 번역 누락 시 빌드가 실패합니다. 미들웨어, SEO 헬퍼, 비주얼 에디터 / CMS 및 AI 기반 번역 기능을 기본 탑재하고 있습니다.
40
+
41
+ | 라이브러리 | GitHub 스타 | 총 커밋 수 | 최근 커밋 | 최초 출시 | NPM 버전 | NPM 다운로드 수 |
42
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
43
+ | `aymericzip/intlayer` | [![GitHub Repo stars](https://img.shields.io/github/stars/aymericzip/intlayer?style=for-the-badge&label=%E2%AD%90%20stars)](https://github.com/aymericzip/intlayer/stargazers) | [![GitHub commit activity](https://img.shields.io/github/commit-activity/t/aymericzip/intlayer?style=for-the-badge&label=commits)](https://github.com/aymericzip/intlayer/commits) | [![Last Commit](https://img.shields.io/github/last-commit/aymericzip/intlayer?style=for-the-badge)](https://github.com/aymericzip/intlayer/commits) | 2024년 4월 | [![npm](https://img.shields.io/npm/v/intlayer?style=for-the-badge)](https://www.npmjs.com/package/intlayer) | [![npm downloads](https://img.shields.io/npm/dm/intlayer?style=for-the-badge)](https://www.npmjs.com/package/intlayer) |
44
+ | `i18next/i18next` | [![GitHub Repo stars](https://img.shields.io/github/stars/i18next/i18next?style=for-the-badge&label=%E2%AD%90%20stars)](https://github.com/i18next/i18next/stargazers) | [![GitHub commit activity](https://img.shields.io/github/commit-activity/t/i18next/i18next?style=for-the-badge&label=commits)](https://github.com/i18next/i18next/commits) | [![Last Commit](https://img.shields.io/github/last-commit/i18next/i18next?style=for-the-badge)](https://github.com/i18next/i18next/commits) | 2012년 1월 | [![npm](https://img.shields.io/npm/v/i18next?style=for-the-badge)](https://www.npmjs.com/package/i18next) | [![npm downloads](https://img.shields.io/npm/dm/i18next?style=for-the-badge)](https://www.npmjs.com/package/i18next) |
45
+ | `i18next/react-i18next` | [![GitHub Repo stars](https://img.shields.io/github/stars/i18next/react-i18next?style=for-the-badge&label=%E2%AD%90%20stars)](https://github.com/i18next/react-i18next/stargazers) | [![GitHub commit activity](https://img.shields.io/github/commit-activity/t/i18next/react-i18next?style=for-the-badge&label=commits)](https://github.com/i18next/react-i18next/commits) | [![Last Commit](https://img.shields.io/github/last-commit/i18next/react-i18next?style=for-the-badge)](https://github.com/i18next/react-i18next/commits) | 2015년 12월 | [![npm](https://img.shields.io/npm/v/react-i18next?style=for-the-badge)](https://www.npmjs.com/package/react-i18next) | [![npm downloads](https://img.shields.io/npm/dm/react-i18next?style=for-the-badge)](https://www.npmjs.com/package/react-i18next) |
46
+ | `i18next/next-i18next` | [![GitHub Repo stars](https://img.shields.io/github/stars/i18next/next-i18next?style=for-the-badge&label=%E2%AD%90%20stars)](https://github.com/i18next/next-i18next/stargazers) | [![GitHub commit activity](https://img.shields.io/github/commit-activity/t/i18next/next-i18next?style=for-the-badge&label=commits)](https://github.com/i18next/next-i18next/commits) | [![Last Commit](https://img.shields.io/github/last-commit/i18next/next-i18next?style=for-the-badge)](https://github.com/i18next/next-i18next/commits) | 2018년 11월 | [![npm](https://img.shields.io/npm/v/next-i18next?style=for-the-badge)](https://www.npmjs.com/package/next-i18next) | [![npm downloads](https://img.shields.io/npm/dm/next-i18next?style=for-the-badge)](https://www.npmjs.com/package/next-i18next) |
47
+
48
+ > 배지는 자동으로 업데이트됩니다. 스냅샷 수치는 시간에 따라 달라질 수 있습니다.
49
+
50
+ ## 주요 기능 비교
51
+
52
+ | 기능 | Intlayer (`react-intlayer` / `next-intlayer`) | i18next (`react-i18next` / `next-i18next`) |
53
+ | ---------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------- |
54
+ | **컴포넌트 인근 번역 정의** | ✅ 가능, 컴포넌트와 동일 디렉터리에 `.content.ts` 배치 | ❌ 불가, `locales/{lng}/{ns}.json` 중앙 집중 관리 |
55
+ | **TypeScript 통합** | ✅ 콘텐츠 기반 엄격한 타입 자동 생성 | ⚠️ 기본 지원; 엄격한 키 사용 시 `CustomTypeOptions` 확장 필요 |
56
+ | **누락된 번역 감지** | ✅ TypeScript 에러 + 빌드 시 오류/경고 발생 | ⚠️ 런타임 폴백 (`saveMissing`, 키 반환) |
57
+ | **서식 있는 콘텐츠 (JSX / Markdown)** | ✅ 네이티브 지원 | ⚠️ 인덱스 태그 기반 `<Trans>` 사용 |
58
+ | **ICU 형식 지원** | ⚠️ 개발 중 | ⚠️ 플러그인 필요 (`i18next-icu`) |
59
+ | **복수형(Pluralization) 처리** | ✅ 열거형 기반 패턴 | ✅ `_one` / `_other` 접미사 (Intl.PluralRules) |
60
+ | **서식 지정 (날짜, 숫자, 통화)** | ✅ `useNumber`, `useDate` 등 (내부적으로 Intl 활용) | ⚠️ 보간 포매터 또는 수동 `Intl.*` 호출 |
61
+ | **지역화된 라우팅 및 미들웨어** | ✅ 내장 프록시/미들웨어, `getMultilingualUrls` | ⚠️ 기본 미포함; 커스텀 미들웨어 또는 외부 라이브러리 필요 |
62
+ | **SEO 헬퍼 (hreflang, sitemap, robots)** | ✅ 내장 헬퍼 제공 | ❌ 수동 구현 |
63
+ | **동기식 서버 컴포넌트** | ✅ `next-intlayer/server`의 `useIntlayer`를 모든 서버 컴포넌트에서 직접 사용 가능 | ⚠️ 페이지 레벨에서 `getFixedT` 호출 후 Props로 `t` 전달 |
64
+ | **트리 쉐이킹 (사용된 콘텐츠만 배포)** | ✅ 컴포넌트 및 로케일 단위로 컴파일러가 자동 처리 | ⚠️ 수동: 네임스페이스 분할 + 페이지별 `ns` 목록 + 백엔드 구성 |
65
+ | **지연 로딩 (Lazy Loading)** | ✅ `importMode: 'dynamic'` (설정 파일 한 줄 추가) | ✅ 백엔드 플러그인 활용 (`i18next-resources-to-backend` 등) |
66
+ | **미사용 콘텐츠 제거 (Purge)** | ✅ 참조되지 않는 사전은 빌드 시 자동 제거 | ❌ 기본 기능 없음 |
67
+ | **누락 번역 테스트 (CLI / CI)** | ✅ `npx intlayer content test` | ⚠️ `i18next-parser` 등 외부 도구 필요 |
68
+ | **AI 기반 번역 지원** | ✅ 내장 제공, 사용자 고유 API 키 사용 | ❌ 없음 (Locize 등 별도 유료 서비스 필요) |
69
+ | **비주얼 에디터 / CMS** | ✅ 무료 비주얼 에디터 + 선택형 CMS 제공 | ❌ 없음 (Locize 등 외부 플랫폼 필요) |
70
+ | **MCP 서버 & Agent Skills** | ✅ 지원 | ❌ 미지원 |
71
+ | **생태계 및 커뮤니티** | ⚠️ 비교적 최신이나 빠르게 성장 중 | ✅ 가장 크고 성숙함 |
72
+
73
+ ## 벤치마크
74
+
75
+ ### 측정 기준 및 환경
76
+
77
+ [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) 테스트 스위트는 각 라이브러리를 사용하여 **완전히 동일한 애플리케이션**을 빌드합니다: **10개 페이지**(홈, 소개, 블로그, 채용, 문의, FAQ, 가격, 제품, 설정, 팀), **10개 로케일**(`en`, `fr`, `es`, `de`, `it`, `pt`, `zh`, `ja`, `ko`, `ru`), 동일한 컴포넌트 및 동일한 콘텐츠. 측정은 `en`과 `fr` 페이지를 대상으로 진행되었습니다.
78
+
79
+ 각 라이브러리는 최소 설정부터 최적화 설정까지 최대 네 가지 **로딩 전략**으로 구현되었습니다:
80
+
81
+ | 전략 | 설명 | 사용 사례 |
82
+ | ------------------ | --------------------------------------------------------------------------------- | -------------------------------------- |
83
+ | **static** | 모든 로케일과 페이지 번들을 하나로 묶음 (`init()`에 `resources` 직접 인라인 삽입) | 빠른 프로토타입, AI 생성 코드 |
84
+ | **dynamic** | 백엔드를 통해 활성 로케일만 로드하지만, 모든 네임스페이스를 한 번에 가져옴 | 대부분의 일반 프로젝트 |
85
+ | **scoped-static** | 라우트별로 하나의 네임스페이스를 분할하되, 초기 번들에 사전 포함 | 드문 구성 |
86
+ | **scoped-dynamic** | 라우트별 네임스페이스 분할 + 백엔드 지연 로딩. 현재 페이지 및 현재 로케일만 로드 | 엄격한 성능 예산이 필요한 애플리케이션 |
87
+
88
+ Intlayer는 별도의 "scoped" 변형이 없습니다. 컴파일러가 콘텐츠를 **컴포넌트 단위**로 자동 분리하므로 `static`과 `dynamic` 행이 이미 최적화된 상태입니다.
89
+
90
+ 각 빌드에 대해 측정된 메트릭:
91
+
92
+ - **Lib size**: i18n 라이브러리만 import하는 빈 컴포넌트의 gzip 크기. 런타임의 기본 오버헤드.
93
+ - **Page JS**: 페이지당 다운로드되는 JavaScript gzip 크기 (전체 페이지 및 로케일의 평균).
94
+ - **Locale leak %**: 다운로드된 JS 내 번역 문자열 중 사용자가 **보고 있지 않은** 언어의 비율.
95
+ - **Page leak %**: 다운로드된 JS 내 번역 문자열 중 사용자가 **머물고 있지 않은** 페이지의 비율.
96
+ - **Component avg**: 개별적으로 격리 컴파일된 각 컴포넌트의 평균 gzip 크기.
97
+ - **E2E reactivity**: 새 언어를 선택한 시점부터 DOM의 `html[lang]`이 업데이트될 때까지의 실제 소요 시간 (Playwright 5회 측정).
98
+ - **Hydration**: React 하이드레이션 단계 소요 시간.
99
+
100
+ > 아래 수치는 `next-i18next` 16.3.0, `react-i18next` 17.0.13, `intlayer` 9.5.1을 사용한 **2026-09-12** 측정 결과입니다. 테스트 애플리케이션은 의도적으로 작게 설계되었으므로(로케일당 수십 개 문자열), 누출 백분율은 **패턴**을 나타냅니다. 콘텐츠가 늘어날수록 누출량은 증가하지만 런타임 비용은 고정됩니다.
101
+
102
+ ### Next.js 결과 (`next-i18next`)
103
+
104
+ | 라이브러리 | 전략 | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E 반응성 | Hydration |
105
+ | ------------------------------- | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | ----------: | --------: |
106
+ | **base** (i18n 없음) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
107
+ | `next-i18next` | static | 19.7 KB | 218.5 KB | 0.0% | 89.8% | 78.5 KB | 16.4 ms | 15.6 ms |
108
+ | `next-i18next` | dynamic | 19.7 KB | 169.5 KB | 50.0% | 89.8% | 26.1 KB | 15.4 ms | 27.7 ms |
109
+ | `next-i18next` | scoped-static | 19.7 KB | 220.1 KB | 0.0% | 89.8% | 78.9 KB | 16.4 ms | 14.7 ms |
110
+ | `next-i18next` | scoped-dynamic | 19.7 KB | 163.4 KB | 0.0% | 0.0% | 27.1 KB | 15.9 ms | 15.1 ms |
111
+ | **`next-intlayer`** | static | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **8.5 KB** | **15.5 ms** | 16.9 ms |
112
+ | **`next-intlayer`** | dynamic | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **6.9 KB** | **15.3 ms** | 15.9 ms |
113
+ | `@intlayer/next-i18next` (호환) | static | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 10.7 ms | 11.3 ms |
114
+ | `@intlayer/next-i18next` (호환) | dynamic | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 11.9 ms | 10.6 ms |
115
+
116
+ **결과 분석**
117
+
118
+ - **런타임 오버헤드**: `i18next` 코어와 `react-i18next`의 결합은 측정된 런타임 중 가장 무거운 **19.7 KB gzip**을 기록했습니다 (Intlayer는 5.5 KB).
119
+ - **기본 구성의 비효율**: `init()`에 `resources`를 직접 넣는 방식은 기본 앱 대비 +77.5 KB 증가한 **218.5 KB/페이지**를 다운로드합니다. 모든 페이지에 모든 네임스페이스가 포함되기 때문입니다.
120
+ - **최적화에 필요한 많은 비용**: 백엔드 방식(`dynamic`)을 도입하면 49 KB를 절감하지만 여전히 **타 페이지 문자열이 90% 누출**되며, 이 구성에서는 절반이 다른 로케일의 문자열입니다. 라우트별 네임스페이스 분할(`scoped-dynamic`)을 적용해야 비로소 0% 누출과 **163.4 KB**에 도달하지만, 설정이 전혀 필요 없는 Intlayer(141.3 KB)보다 여전히 **+22.4 KB/페이지** 더 큽니다.
121
+ - **컴포넌트 크기**: `useTranslation()`을 호출하는 컴포넌트는 설정에 따라 26~79 KB에 달하지만, `useIntlayer()`를 사용하는 동일 컴포넌트는 6.9 KB에 불과합니다.
122
+ - **하이드레이션 지연**: `dynamic` 구성에서 하이드레이션 시간이 27.7 ms로 급증합니다. React가 하이드레이션을 수행하기 전에 클라이언트에서 i18next 인스턴스가 초기화되고 백엔드를 처리해야 하기 때문입니다.
123
+
124
+ ### TanStack Start 결과 (`react-i18next`)
125
+
126
+ Next.js 특유의 구조적 차이를 배제하고 TanStack Start 환경에서 순수 `react-i18next`로 측정한 결과입니다.
127
+
128
+ | 라이브러리 | 전략 | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E 반응성 | Hydration |
129
+ | -------------------- | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | ---------: | --------: |
130
+ | **base** (i18n 없음) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
131
+ | `react-i18next` | static | 18.4 KB | 180.3 KB | 50.0% | 89.8% | 24.3 KB | 12.9 ms | 85.1 ms |
132
+ | `react-i18next` | dynamic | 18.4 KB | 136.4 KB | 23.1% | 89.8% | 24.8 KB | 123.1 ms | 32.9 ms |
133
+ | `react-i18next` | scoped-static | 18.4 KB | 184.2 KB | 50.7% | 89.8% | 25.3 KB | 185.1 ms | 25.2 ms |
134
+ | `react-i18next` | scoped-dynamic | 18.4 KB | 127.2 KB | 0.0% | 0.0% | 26.7 KB | 17.6 ms | 11.3 ms |
135
+ | **`intlayer`** | static | **5.0 KB** | **125.8 KB** | 50.0% | **0.0%** | **8.1 KB** | **3.2 ms** | 11.5 ms |
136
+ | **`intlayer`** | dynamic | **5.0 KB** | **118.6 KB** | **0.0%** | **0.0%** | **6.3 KB** | **3.6 ms** | 14.1 ms |
137
+
138
+ **결과 분석**
139
+
140
+ - 기본 `react-i18next` 앱은 기준 앱 대비 **+69 KB/페이지**를 다운로드하며, 하이드레이션에 **85 ms**(기준 앱의 4배)가 소요됩니다. 첫 렌더링 전에 전체 리소스 트리가 클라이언트에서 파싱 및 등록되기 때문입니다.
141
+ - **로케일 전환 시 지연 문제**: 리소스를 필요할 때 로드하는 백엔드를 사용할 경우 언어 변경 시 네트워크 왕복이 발생하여 `html[lang]` 갱신까지 지연이 발생합니다: `dynamic`에서 **123 ms**, `scoped-static`에서 **185 ms**. 반면 Intlayer는 두 모드 모두에서 **3-4 ms** 내에 DOM을 업데이트합니다.
142
+ - 고도로 최적화된 `scoped-dynamic` 설정도 127.2 KB로 여전히 Intlayer의 `dynamic`보다 **+8.6 KB** 더 무거우며, 이를 위해 라우트-네임스페이스 맵, 백엔드 및 Suspense 설정이 필요했습니다.
143
+ - Intlayer의 `static`은 해당 페이지의 컴포넌트가 직접 임포트한 사전만 포함하므로 이미 **페이지 누출 0%**를 달성합니다. `importMode: 'dynamic'`을 활성화하면 로케일 누출도 완전히 제거됩니다.
144
+ - **컴포넌트 크기**: `react-i18next` 컴포넌트가 24-27 KB인 반면 Intlayer는 6-8 KB입니다.
145
+
146
+ ## 차이의 원인: 글로벌 인스턴스 vs 컴파일된 사전
147
+
148
+ `i18next`는 2012년에 런타임 중심 모델로 설계되었습니다: 글로벌 인스턴스가 리소스 저장소를 관리하고 플러그인이 이를 확장하며, 렌더링 시 `t()`가 키를 조회합니다. 이는 매우 유연하지만(어떤 프레임워크나 포맷도 지원) 구조적인 오버헤드를 유발합니다:
149
+
150
+ ```bash
151
+ .
152
+ ├── i18n.ts # createInstance().use(...).use(...).init({...})
153
+ └── src
154
+ ├── locales
155
+ │ ├── en
156
+ │ │ ├── common.json
157
+ │ │ ├── home.json
158
+ │ │ └── about.json
159
+ │ └── fr
160
+ │ ├── common.json
161
+ │ ├── home.json
162
+ │ └── about.json
163
+ ├── components
164
+ │ └── Counter.tsx # useTranslation("about") + t("counter.label")
165
+ └── app
166
+ └── [locale]
167
+ └── about
168
+ └── page.tsx # ["common", "about"] 필요 여부를 직접 알아야 함
169
+ ```
170
+
171
+ 인스턴스는 컴포넌트가 어떤 키를 요청할지 미리 알 수 없으므로 지시된 모든 네임스페이스를 유지합니다. 따라서 최적화를 위해 **개발자**가 카탈로그를 분할하고, 페이지별 네임스페이스를 정의하고, 컴포넌트 이동 시마다 이를 관리해야 합니다. [벤치마크 노트](https://github.com/intlayer-org/benchmark-bloom/blob/main/report/NOTE.md)에서 언급하듯 "타입 안전성을 유지하면서 각 페이지에 필요한 네임스페이스를 완벽히 파악하는 것은 매우 번거로운 일"입니다.
172
+
173
+ Intlayer는 글로벌 인스턴스를 사용하지 않습니다. 콘텐츠가 컴포넌트 옆에 선언되며 컴파일러가 빌드 타임에 종속성 트리를 분석합니다:
174
+
175
+ ```bash
176
+ .
177
+ ├── intlayer.config.ts
178
+ └── src
179
+ ├── components
180
+ │ └── Counter
181
+ │ ├── index.tsx # useIntlayer("counter")
182
+ │ └── index.content.ts
183
+ └── app
184
+ └── [locale]
185
+ └── about
186
+ ├── page.tsx
187
+ └── page.content.ts
188
+ ```
189
+
190
+ `@intlayer/swc` / `@intlayer/babel`은 어떤 컴포넌트가 어떤 사전을 임포트하는지 확인하여 활성 언어에 필요한 것만 번들링하고 사용되지 않는 항목은 제거합니다. "scoped-dynamic" 패턴이 수동 관리 없이 빌드 결과물로 자동 도출됩니다.
191
+
192
+ > `dynamic` 행의 성능을 적용하려면 `intlayer.config.ts`에서 `dictionary.importMode: 'dynamic'`을 설정하십시오. 자세한 내용은 [번들 최적화 문서](https://intlayer.org/ko/doc/concept/bundle-optimization)를 참고하세요.
193
+
194
+ ## 개발자 경험 (DX)
195
+
196
+ ### 초기 설정 비교
197
+
198
+ **next-i18next (App Router)**
199
+
200
+ ```ts fileName="src/app/i18n/server.ts"
201
+ import { createInstance } from "i18next";
202
+ import { initReactI18next } from "react-i18next/initReactI18next";
203
+ import resourcesToBackend from "i18next-resources-to-backend";
204
+ import { defaultLocale } from "@/i18n.config";
205
+
206
+ const backend = resourcesToBackend(
207
+ (locale: string, namespace: string) =>
208
+ import(`../../locales/${locale}/${namespace}.json`)
209
+ );
210
+
211
+ export const initI18next = async (
212
+ locale: string,
213
+ namespaces: string[] = ["common"]
214
+ ) => {
215
+ const i18n = createInstance();
216
+ await i18n
217
+ .use(initReactI18next)
218
+ .use(backend)
219
+ .init({
220
+ lng: locale,
221
+ fallbackLng: defaultLocale,
222
+ ns: namespaces,
223
+ defaultNS: "common",
224
+ interpolation: { escapeValue: false },
225
+ react: { useSuspense: false },
226
+ });
227
+ return i18n;
228
+ };
229
+ ```
230
+
231
+ 여기에 추가로 클라이언트용 `I18nProvider`, `generateStaticParams`, 그리고 각 페이지의 `namespaces` 목록 관리가 필요합니다.
232
+
233
+ **Intlayer**
234
+
235
+ ```ts fileName="intlayer.config.ts"
236
+ import { type IntlayerConfig, Locales } from "intlayer";
237
+
238
+ const config: IntlayerConfig = {
239
+ internationalization: {
240
+ locales: [Locales.ENGLISH, Locales.FRENCH],
241
+ defaultLocale: Locales.ENGLISH,
242
+ },
243
+ };
244
+
245
+ export default config;
246
+ ```
247
+
248
+ ```tsx fileName="src/app/[locale]/layout.tsx"
249
+ import { getHTMLTextDir } from "intlayer";
250
+ import { IntlayerClientProvider, type NextLayoutIntlayer } from "next-intlayer";
251
+
252
+ const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
253
+ const { locale } = await params;
254
+
255
+ return (
256
+ <html lang={locale} dir={getHTMLTextDir(locale)}>
257
+ <body>
258
+ <IntlayerClientProvider locale={locale}>
259
+ {children}
260
+ </IntlayerClientProvider>
261
+ </body>
262
+ </html>
263
+ );
264
+ };
265
+
266
+ export default LocaleLayout;
267
+ ```
268
+
269
+ ### 클라이언트 컴포넌트
270
+
271
+ **react-i18next**
272
+
273
+ ```json fileName="src/locales/en/about.json"
274
+ {
275
+ "counter": {
276
+ "label": "Counter",
277
+ "increment": "Increment"
278
+ }
279
+ }
280
+ ```
281
+
282
+ ```tsx fileName="src/components/Counter.tsx"
283
+ "use client";
284
+
285
+ import { useState } from "react";
286
+ import { useTranslation } from "react-i18next";
287
+
288
+ export const Counter = () => {
289
+ const { t, i18n } = useTranslation("about");
290
+ const [count, setCount] = useState(0);
291
+ const numberFormat = new Intl.NumberFormat(i18n.language);
292
+
293
+ return (
294
+ <div>
295
+ <p>{numberFormat.format(count)}</p>
296
+ <button
297
+ aria-label={t("counter.label")}
298
+ onClick={() => setCount((c) => c + 1)}
299
+ >
300
+ {t("counter.increment")}
301
+ </button>
302
+ </div>
303
+ );
304
+ };
305
+ ```
306
+
307
+ > 이 컴포넌트를 렌더링하는 페이지는 `about` 네임스페이스를 로드해야 하며, `CustomTypeOptions`를 확장하지 않으면 `t("counter.label")`에 엄격한 타입이 적용되지 않습니다.
308
+
309
+ **Intlayer**
310
+
311
+ ```ts fileName="src/components/Counter/index.content.ts"
312
+ import { t, type Dictionary } from "intlayer";
313
+
314
+ const counterContent = {
315
+ key: "counter",
316
+ content: {
317
+ label: t({ en: "Counter", fr: "Compteur" }),
318
+ increment: t({ en: "Increment", fr: "Incrémenter" }),
319
+ },
320
+ } satisfies Dictionary;
321
+
322
+ export default counterContent;
323
+ ```
324
+
325
+ ```tsx fileName="src/components/Counter/index.tsx"
326
+ "use client";
327
+
328
+ import { useState } from "react";
329
+ import { useIntlayer } from "next-intlayer";
330
+ import { useNumber } from "next-intlayer/format";
331
+
332
+ export const Counter = () => {
333
+ const { label, increment } = useIntlayer("counter");
334
+ const number = useNumber();
335
+ const [count, setCount] = useState(0);
336
+
337
+ return (
338
+ <div>
339
+ <p>{number(count)}</p>
340
+ <button aria-label={label} onClick={() => setCount((c) => c + 1)}>
341
+ {increment}
342
+ </button>
343
+ </div>
344
+ );
345
+ };
346
+ ```
347
+
348
+ `label`과 `increment`는 엄격히 타입이 지정됩니다. 오타는 TypeScript 에러가 되고, 프랑스어 번역 누락은 빌드 에러로 처리됩니다.
349
+
350
+ ### 동기식 서버 컴포넌트
351
+
352
+ **next-i18next**
353
+
354
+ ```tsx fileName="src/components/ServerCounter.tsx"
355
+ type ServerCounterProps = {
356
+ t: (key: string) => string;
357
+ locale: string;
358
+ count: number;
359
+ };
360
+
361
+ export const ServerCounter = ({ t, locale, count }: ServerCounterProps) => (
362
+ <div>
363
+ <p>{new Intl.NumberFormat(locale).format(count)}</p>
364
+ <button aria-label={t("counter.label")}>{t("counter.increment")}</button>
365
+ </div>
366
+ );
367
+ ```
368
+
369
+ 페이지에서 `i18n.getFixedT(locale, "about")`를 호출한 후 하위 컴포넌트로 `t`와 `locale`을 넘겨주어야 합니다.
370
+
371
+ **Intlayer**
372
+
373
+ ```tsx fileName="src/components/ServerCounter.tsx"
374
+ import { useIntlayer } from "next-intlayer/server";
375
+ import { useNumber } from "next-intlayer/server/format";
376
+
377
+ export const ServerCounter = ({ count }: { count: number }) => {
378
+ const { label, increment } = useIntlayer("counter");
379
+ const number = useNumber();
380
+
381
+ return (
382
+ <div>
383
+ <p>{number(count)}</p>
384
+ <button aria-label={label}>{increment}</button>
385
+ </div>
386
+ );
387
+ };
388
+ ```
389
+
390
+ ## i18next API를 유지하면서 Intlayer의 성능 얻기
391
+
392
+ 기존 컴포넌트를 전부 다시 작성하지 않고도 벤치마크 성능을 누릴 수 있습니다. `@intlayer/i18next`, `@intlayer/react-i18next`, `@intlayer/next-i18next`는 드롭인 호환 어댑터입니다: `useTranslation`, `t()`, `<Trans>`, `{{interpolation}}`, 복수형 접미사, 컨텍스트 접미사 및 `returnObjects`가 그대로 작동하며, 백그라운드에서는 Intlayer 컴파일러가 사전을 공급합니다.
393
+
394
+ ```ts fileName="next.config.ts"
395
+ import type { NextConfig } from "next";
396
+ import { createNextI18nPlugin } from "@intlayer/next-i18next/plugin";
397
+
398
+ const withIntlayer = createNextI18nPlugin();
399
+
400
+ const nextConfig: NextConfig = {};
401
+
402
+ export default withIntlayer(nextConfig);
403
+ ```
404
+
405
+ ```ts fileName="vite.config.ts"
406
+ import { defineConfig } from "vite";
407
+ import { reactI18nextVitePlugin } from "@intlayer/react-i18next/plugin";
408
+
409
+ export default defineConfig({
410
+ plugins: [reactI18nextVitePlugin()],
411
+ });
412
+ ```
413
+
414
+ 벤치마크에서 동일한 Next.js 앱의 호환 빌드는 애플리케이션 코드를 수정하지 않고도 페이지당 **218.5 KB에서 150.7 KB**로, 컴포넌트당 **78.5 KB에서 9.7 KB**로, 페이지 누출은 **~90%에서 0%**로, 하이드레이션은 15.6 ms에서 11.3 ms로 단축되었습니다. 기존의 `locales/{lng}/{ns}.json` 파일은 JSON 동기화 플러그인을 통해 신뢰할 수 있는 단일 원천(source of truth)으로 계속 사용할 수 있습니다.
415
+
416
+ 마이그레이션 가이드를 참고하세요: [i18next](https://intlayer.org/ko/doc/migration/i18next), [react-i18next](https://intlayer.org/ko/doc/migration/react-i18next), [next-i18next](https://intlayer.org/ko/doc/migration/next-i18next).
417
+
418
+ ## 어떤 도구를 선택해야 할까요?
419
+
420
+ - **i18next를 선택할 경우**: 광범위한 플러그인 생태계(감지기, 백엔드, ICU, Locize 등)가 필수적이거나, React 외부 환경(Node 서비스, Vanilla JS, 기타 프레임워크)에서도 동일하게 사용해야 하거나, 팀원들이 이미 익숙하거나, 번역 플랫폼이 `locales/{lng}/{ns}.json`을 요구할 때. 단, 성능이 중요하다면 네임스페이스 분할과 라우트 매핑 관리에 시간을 투자해야 합니다.
421
+ - **Intlayer를 선택할 경우**: **컴포넌트 중심의 콘텐츠 관리**, **엄격한 TypeScript 타입 지원**, **빌드 시 누락 번역 감지**, **무설정 트리 쉐이킹 및 지연 로딩**, 즉각적인 로케일 전환, 동기식 서버 컴포넌트, 통합 편집 도구(비주얼 에디터, CMS, AI 번역, MCP 서버)를 원할 때. 모듈식 코드베이스 및 디자인 시스템에 특히 적합합니다.
422
+ - **`@intlayer/*-i18next` 어댑터를 선택할 경우**: 이미 i18next를 사용 중이며 코드 리팩토링 없이 번들 크기와 반응성을 대폭 개선하고 싶을 때.
423
+
424
+ ## 관련 비교 자료
425
+
426
+ - [next-intl vs Intlayer](https://intlayer.org/ko/blog/next-intl-vs-intlayer) (동일 벤치마크)
427
+ - [Lingui vs Intlayer](https://intlayer.org/ko/blog/lingui-vs-intlayer) (동일 벤치마크)
428
+ - [vue-i18n vs Intlayer 벤치마크](https://intlayer.org/ko/blog/vue-i18n-vs-intlayer-benchmark) (동일 벤치마크)
429
+ - [next-i18next vs next-intl vs Intlayer](https://intlayer.org/ko/blog/next-i18next-vs-next-intl-vs-intlayer)
430
+ - [react-i18next vs react-intl vs Intlayer](https://intlayer.org/ko/blog/react-i18next-vs-react-intl-vs-intlayer)
431
+ - [i18next는 구식인가요?](https://intlayer.org/ko/blog/is-i18next-outdated)
432
+
433
+ ## GitHub 스타
434
+
435
+ GitHub 스타는 프로젝트의 인기, 커뮤니티의 신뢰도 및 장기적인 지속 가능성을 보여주는 중요한 지표입니다. 기술적 완성도를 직접적으로 나타내는 것은 아니지만, 많은 개발자가 해당 프로젝트의 가치를 인정하고 활발히 채택하고 있음을 반영합니다.
436
+
437
+ [![스타 기록 차트](https://api.star-history.com/chart?repos=i18next%2Fi18next%2Ci18next%2Freact-i18next%2Ci18next%2Fnext-i18next%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://star-history.com/#i18next/i18next&i18next/react-i18next&i18next/next-i18next&aymericzip/intlayer)
438
+
439
+ ## 결론
440
+
441
+ `i18next`는 뛰어난 범용성과 강력한 플러그인 생태계로 지난 10년 이상 업계 표준의 위치를 지켜왔습니다. 그러나 벤치마크는 런타임 중심 아키텍처가 야기하는 비용을 명확히 보여줍니다. 일반적인 설정은 **페이지당 +70~77 KB gzip**을 소모하고, **타 페이지 문자열을 ~90% 누출**시키며, 지연 로딩 시 언어 전환에 **100 ms 이상**이 걸립니다. 수동 최적화로 누출을 0%로 줄일 수는 있지만 많은 관리 비용이 수반되며, 그럼에도 Intlayer보다 **9~22 KB** 무겁습니다.
442
+
443
+ Intlayer는 이러한 모든 작업을 컴파일러로 이전했습니다. 컴포넌트별 사전 분할, 로케일별 지연 로딩, 미사용 콘텐츠 제거가 빌드 과정에서 자동으로 이루어집니다. 동일한 앱에서: **페이지당 +0.3 KB**, **누출 0%**, **3~10배 작은 컴포넌트**, **3~4 ms 로케일 전환**을 경험할 수 있습니다.
444
+
445
+ 모든 원시 데이터, 테스트 앱 및 스크립트는 [Benchmark Bloom 저장소](https://github.com/intlayer-org/benchmark-bloom)에서 직접 확인하고 검증하실 수 있습니다.
446
+
447
+ 자세한 내용은 ['왜 Intlayer인가요?' 문서](https://intlayer.org/ko/doc/why)를 참조하십시오.
@@ -70,7 +70,7 @@ GitHub 스타 수는 과거의 누적 인기를 반영할 뿐, 현재의 아키
70
70
  | `i18next` core | 2,626 | **259** | 마이너 패치 |
71
71
  | Intlayer | 7,156 | **4,343** | 컴파일러, IDE 툴링, AI 번역 엔진 개발 등 |
72
72
 
73
- [![Star History Chart](https://api.star-history.com/chart?repos=i18next%2Fi18next%2Ci18next%2Freact-i18next%2Ci18next%2Fnext-i18next%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://www.star-history.com/#i18next/i18next&i18next/react-i18next&i18next/next-i18next&aymericzip/intlayer)
73
+ [![Star History Chart](https://api.star-history.com/chart?repos=i18next%2Fi18next%2Ci18next%2Freact-i18next%2Ci18next%2Fnext-i18next%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://star-history.com/#i18next/i18next&i18next/react-i18next&i18next/next-i18next&aymericzip/intlayer)
74
74
 
75
75
  성숙한 라이브러리는 안정성을 제공합니다. 하지만 i18n 도구의 패러다임은 완전히 바뀌었습니다. 빌드 타임에 불필요한 콘텐츠를 제거하고, CI에서 LLM으로 자동 번역하며, Language Server (LSP)와 AI 에이전트를 IDE에 통합합니다. 런타임에 전적으로 의존하는 아키텍처는 이러한 현대적 기술을 수용하기 어렵습니다.
76
76
 
@@ -66,7 +66,7 @@ Crowdin의 공식 파트너이기 때문에, CLI 자체에 무료 로컬 AI 번
66
66
  - `amannn/next-intl`: **187 커밋** (Next.js 호환성 유지 및 소규모 수정).
67
67
  - `aymericzip/intlayer`: **4,343 커밋** (컴파일러 최적화, IDE 확장, MCP 서버, AI 번역 엔진 개발 등).
68
68
 
69
- [![Star History Chart](https://api.star-history.com/chart?repos=amannn%2Fnext-intl%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://www.star-history.com/#amannn/next-intl&aymericzip/intlayer)
69
+ [![Star History Chart](https://api.star-history.com/chart?repos=amannn%2Fnext-intl%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://star-history.com/#amannn/next-intl&aymericzip/intlayer)
70
70
 
71
71
  성숙한 라이브러리는 안정감을 줍니다. 하지만 i18n 환경은 달라졌습니다. 빌드 시 미사용 텍스트를 걸러내고, CI에서 LLM이 번역을 수행하며, 에디터는 Language Server (LSP) 및 AI 어시스턴트와 밀접하게 연동됩니다. 런타임 처리에 갇힌 아키텍처는 이러한 진보를 온전히 누리기 어렵습니다.
72
72
 
@@ -64,7 +64,7 @@ Vite + Vue 기반의 가벼운 기본 애플리케이션(31.5 KB)에 `vue-i18n`
64
64
  - `intlify/vue-i18n`: **259 커밋** (Vue 3 및 Nuxt 유지보수 위주).
65
65
  - `aymericzip/intlayer`: **4,343 커밋** (컴파일러 고도화, LSP 도구, AI 에이전트 연동 작업 등 지속 개발).
66
66
 
67
- [![Star History Chart](https://api.star-history.com/chart?repos=intlify%2Fvue-i18n%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://www.star-history.com/#intlify/vue-i18n&aymericzip/intlayer)
67
+ [![Star History Chart](https://api.star-history.com/chart?repos=intlify%2Fvue-i18n%2Caymericzip%2Fintlayer&type=date&legend=top-left)](https://star-history.com/#intlify/vue-i18n&aymericzip/intlayer)
68
68
 
69
69
  오래된 라이브러리는 안정성이 뛰어납니다. 하지만 오늘날의 프론트엔드는 빌드 타임 AST 변환, 데드 코드 제거, AI 자동화에 기반하고 있습니다. 런타임에 종속된 구조로는 이러한 혁신을 온전히 따라잡기 어렵습니다.
70
70