@intlayer/docs 9.5.6 → 9.5.7
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.
- package/blog/ar/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ar/i18next_vs_intlayer.md +130 -16
- package/blog/ar/lingui_vs_intlayer.md +122 -15
- package/blog/ar/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ar/next-intl_vs_intlayer.md +136 -20
- package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +119 -17
- package/blog/ar/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/de/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/de/i18next_vs_intlayer.md +128 -14
- package/blog/de/lingui_vs_intlayer.md +122 -15
- package/blog/de/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/de/next-intl_vs_intlayer.md +125 -15
- package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/de/vue-i18n_vs_intlayer.md +193 -31
- package/blog/en/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en/i18next_vs_intlayer.md +128 -14
- package/blog/en/lingui_vs_intlayer.md +124 -15
- package/blog/en/next-intl_vs_intlayer-next-intl.md +123 -14
- package/blog/en/next-intl_vs_intlayer.md +125 -13
- package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +115 -15
- package/blog/en/vue-i18n_vs_intlayer.md +188 -27
- package/blog/en-GB/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en-GB/i18next_vs_intlayer.md +128 -14
- package/blog/en-GB/lingui_vs_intlayer.md +122 -15
- package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/en-GB/next-intl_vs_intlayer.md +125 -15
- package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/en-GB/vue-i18n_vs_intlayer.md +187 -25
- package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +116 -0
- package/blog/es/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/es/i18next_vs_intlayer.md +128 -14
- package/blog/es/lingui_vs_intlayer.md +122 -15
- package/blog/es/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/es/next-intl_vs_intlayer.md +125 -15
- package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/es/vue-i18n_vs_intlayer.md +193 -31
- package/blog/fr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/fr/i18next_vs_intlayer.md +128 -14
- package/blog/fr/lingui_vs_intlayer.md +122 -15
- package/blog/fr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/fr/next-intl_vs_intlayer.md +127 -15
- package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +118 -17
- package/blog/fr/vue-i18n_vs_intlayer.md +192 -31
- package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +329 -7
- package/blog/hi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/hi/i18next_vs_intlayer.md +130 -16
- package/blog/hi/lingui_vs_intlayer.md +122 -15
- package/blog/hi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/hi/next-intl_vs_intlayer.md +135 -19
- package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/hi/vue-i18n_vs_intlayer.md +193 -31
- package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/id/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/id/i18next_vs_intlayer.md +128 -14
- package/blog/id/lingui_vs_intlayer.md +122 -15
- package/blog/id/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/id/next-intl_vs_intlayer.md +135 -19
- package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +354 -2
- package/blog/id/vue-i18n_vs_intlayer.md +188 -26
- package/blog/id/vue-i18n_vs_intlayer_benchmark.md +327 -7
- package/blog/it/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/it/i18next_vs_intlayer.md +128 -14
- package/blog/it/lingui_vs_intlayer.md +122 -15
- package/blog/it/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/it/next-intl_vs_intlayer.md +125 -15
- package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/it/vue-i18n_vs_intlayer.md +191 -31
- package/blog/it/vue-i18n_vs_intlayer_benchmark.md +332 -5
- package/blog/ja/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ja/i18next_vs_intlayer.md +129 -17
- package/blog/ja/lingui_vs_intlayer.md +122 -15
- package/blog/ja/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ja/next-intl_vs_intlayer.md +124 -14
- package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ja/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ko/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ko/i18next_vs_intlayer.md +129 -17
- package/blog/ko/lingui_vs_intlayer.md +122 -15
- package/blog/ko/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ko/next-intl_vs_intlayer.md +134 -18
- package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ko/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pl/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pl/i18next_vs_intlayer.md +128 -14
- package/blog/pl/lingui_vs_intlayer.md +122 -15
- package/blog/pl/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pl/next-intl_vs_intlayer.md +134 -18
- package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pl/vue-i18n_vs_intlayer.md +188 -26
- package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/pt/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pt/i18next_vs_intlayer.md +128 -14
- package/blog/pt/lingui_vs_intlayer.md +122 -15
- package/blog/pt/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pt/next-intl_vs_intlayer.md +131 -15
- package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pt/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ru/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ru/i18next_vs_intlayer.md +130 -16
- package/blog/ru/lingui_vs_intlayer.md +122 -15
- package/blog/ru/next-intl_vs_intlayer-next-intl.md +125 -16
- package/blog/ru/next-intl_vs_intlayer.md +123 -13
- package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +127 -27
- package/blog/ru/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +326 -19
- package/blog/tr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/tr/i18next_vs_intlayer.md +128 -14
- package/blog/tr/lingui_vs_intlayer.md +122 -15
- package/blog/tr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/tr/next-intl_vs_intlayer.md +136 -20
- package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/tr/vue-i18n_vs_intlayer.md +188 -26
- package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/uk/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/uk/i18next_vs_intlayer.md +130 -16
- package/blog/uk/lingui_vs_intlayer.md +122 -15
- package/blog/uk/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/uk/next-intl_vs_intlayer.md +135 -19
- package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +135 -17
- package/blog/uk/vue-i18n_vs_intlayer.md +188 -27
- package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/vi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/vi/i18next_vs_intlayer.md +128 -14
- package/blog/vi/lingui_vs_intlayer.md +122 -15
- package/blog/vi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/vi/next-intl_vs_intlayer.md +135 -19
- package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/vi/vue-i18n_vs_intlayer.md +188 -26
- package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/zh/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/zh/i18next_vs_intlayer.md +128 -14
- package/blog/zh/lingui_vs_intlayer.md +122 -15
- package/blog/zh/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/zh/next-intl_vs_intlayer.md +125 -15
- package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/zh/vue-i18n_vs_intlayer.md +192 -31
- package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +340 -9
- package/dist/cjs/generated/docs.entry.cjs +40 -40
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/index.cjs +2 -2
- package/dist/esm/generated/docs.entry.mjs +40 -40
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/types/generated/docs.entry.d.ts +2 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +13 -13
- package/docs/ar/benchmark/solid.md +5 -5
- package/docs/ar/benchmark/svelte.md +4 -4
- package/docs/ar/benchmark/tanstack.md +14 -13
- package/docs/ar/benchmark/vue.md +5 -5
- package/docs/ar/chrome_extension.md +130 -0
- package/docs/ar/cli/index.md +6 -1
- package/docs/ar/cli/infra.md +162 -0
- package/docs/ar/cli/init.md +24 -1
- package/docs/ar/dictionary/html.md +173 -5
- package/docs/ar/dictionary/markdown.md +263 -1
- package/docs/ar/intlayer_with_analog.md +23 -1
- package/docs/ar/intlayer_with_angular_19.md +24 -1
- package/docs/ar/intlayer_with_angular_21.md +24 -1
- package/docs/ar/intlayer_with_astro.md +24 -1
- package/docs/ar/intlayer_with_astro_lit.md +25 -1
- package/docs/ar/intlayer_with_astro_preact.md +26 -1
- package/docs/ar/intlayer_with_astro_react.md +26 -1
- package/docs/ar/intlayer_with_astro_solid.md +26 -1
- package/docs/ar/intlayer_with_astro_svelte.md +25 -1
- package/docs/ar/intlayer_with_astro_vue.md +25 -1
- package/docs/ar/intlayer_with_remix_3.md +22 -1
- package/docs/ar/self_hosting.md +406 -231
- package/docs/de/benchmark/nextjs.md +13 -13
- package/docs/de/benchmark/solid.md +5 -5
- package/docs/de/benchmark/svelte.md +4 -4
- package/docs/de/benchmark/tanstack.md +14 -13
- package/docs/de/benchmark/vue.md +5 -5
- package/docs/de/chrome_extension.md +130 -0
- package/docs/de/cli/index.md +6 -1
- package/docs/de/cli/infra.md +162 -0
- package/docs/de/cli/init.md +24 -1
- package/docs/de/dictionary/html.md +173 -5
- package/docs/de/dictionary/markdown.md +263 -1
- package/docs/de/intlayer_with_analog.md +23 -1
- package/docs/de/intlayer_with_angular_19.md +24 -1
- package/docs/de/intlayer_with_angular_21.md +24 -1
- package/docs/de/intlayer_with_astro.md +24 -1
- package/docs/de/intlayer_with_astro_lit.md +25 -1
- package/docs/de/intlayer_with_astro_preact.md +26 -1
- package/docs/de/intlayer_with_astro_react.md +26 -1
- package/docs/de/intlayer_with_astro_solid.md +26 -1
- package/docs/de/intlayer_with_astro_svelte.md +25 -1
- package/docs/de/intlayer_with_astro_vue.md +25 -1
- package/docs/de/intlayer_with_remix_3.md +22 -1
- package/docs/de/self_hosting.md +404 -227
- package/docs/en/benchmark/nextjs.md +13 -13
- package/docs/en/benchmark/solid.md +5 -5
- package/docs/en/benchmark/svelte.md +4 -4
- package/docs/en/benchmark/tanstack.md +14 -13
- package/docs/en/benchmark/vue.md +5 -5
- package/docs/en/chrome_extension.md +130 -0
- package/docs/en/cli/index.md +6 -1
- package/docs/en/cli/infra.md +175 -0
- package/docs/en/cli/init.md +25 -1
- package/docs/en/dictionary/html.md +173 -5
- package/docs/en/dictionary/markdown.md +263 -1
- package/docs/en/intlayer_with_analog.md +23 -1
- package/docs/en/intlayer_with_angular_19.md +24 -1
- package/docs/en/intlayer_with_angular_21.md +24 -1
- package/docs/en/intlayer_with_astro.md +24 -1
- package/docs/en/intlayer_with_astro_lit.md +25 -1
- package/docs/en/intlayer_with_astro_preact.md +26 -1
- package/docs/en/intlayer_with_astro_react.md +26 -1
- package/docs/en/intlayer_with_astro_solid.md +26 -1
- package/docs/en/intlayer_with_astro_svelte.md +25 -1
- package/docs/en/intlayer_with_astro_vue.md +25 -1
- package/docs/en/intlayer_with_remix_3.md +22 -1
- package/docs/en/self_hosting.md +418 -176
- package/docs/en-GB/benchmark/nextjs.md +13 -13
- package/docs/en-GB/benchmark/solid.md +5 -5
- package/docs/en-GB/benchmark/svelte.md +4 -4
- package/docs/en-GB/benchmark/tanstack.md +14 -13
- package/docs/en-GB/benchmark/vue.md +5 -5
- package/docs/en-GB/chrome_extension.md +130 -0
- package/docs/en-GB/cli/index.md +6 -1
- package/docs/en-GB/cli/infra.md +162 -0
- package/docs/en-GB/cli/init.md +24 -1
- package/docs/en-GB/dictionary/html.md +173 -5
- package/docs/en-GB/dictionary/markdown.md +263 -1
- package/docs/en-GB/intlayer_with_analog.md +23 -1
- package/docs/en-GB/intlayer_with_angular_19.md +24 -1
- package/docs/en-GB/intlayer_with_angular_21.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +24 -1
- package/docs/en-GB/intlayer_with_astro_lit.md +25 -1
- package/docs/en-GB/intlayer_with_astro_preact.md +26 -1
- package/docs/en-GB/intlayer_with_astro_react.md +26 -1
- package/docs/en-GB/intlayer_with_astro_solid.md +26 -1
- package/docs/en-GB/intlayer_with_astro_svelte.md +25 -1
- package/docs/en-GB/intlayer_with_astro_vue.md +25 -1
- package/docs/en-GB/intlayer_with_remix_3.md +22 -1
- package/docs/en-GB/self_hosting.md +381 -206
- package/docs/es/benchmark/nextjs.md +13 -13
- package/docs/es/benchmark/solid.md +5 -5
- package/docs/es/benchmark/svelte.md +4 -4
- package/docs/es/benchmark/tanstack.md +14 -13
- package/docs/es/benchmark/vue.md +5 -5
- package/docs/es/chrome_extension.md +130 -0
- package/docs/es/cli/index.md +6 -1
- package/docs/es/cli/infra.md +162 -0
- package/docs/es/cli/init.md +24 -1
- package/docs/es/dictionary/html.md +173 -5
- package/docs/es/dictionary/markdown.md +263 -1
- package/docs/es/intlayer_with_analog.md +23 -1
- package/docs/es/intlayer_with_angular_19.md +24 -1
- package/docs/es/intlayer_with_angular_21.md +24 -1
- package/docs/es/intlayer_with_astro.md +24 -1
- package/docs/es/intlayer_with_astro_lit.md +25 -1
- package/docs/es/intlayer_with_astro_preact.md +26 -1
- package/docs/es/intlayer_with_astro_react.md +26 -1
- package/docs/es/intlayer_with_astro_solid.md +26 -1
- package/docs/es/intlayer_with_astro_svelte.md +25 -1
- package/docs/es/intlayer_with_astro_vue.md +25 -1
- package/docs/es/intlayer_with_remix_3.md +22 -1
- package/docs/es/self_hosting.md +400 -223
- package/docs/fr/benchmark/nextjs.md +13 -13
- package/docs/fr/benchmark/solid.md +5 -5
- package/docs/fr/benchmark/svelte.md +4 -4
- package/docs/fr/benchmark/tanstack.md +14 -13
- package/docs/fr/benchmark/vue.md +5 -5
- package/docs/fr/chrome_extension.md +130 -0
- package/docs/fr/cli/index.md +6 -1
- package/docs/fr/cli/infra.md +162 -0
- package/docs/fr/cli/init.md +24 -1
- package/docs/fr/dictionary/html.md +173 -5
- package/docs/fr/dictionary/markdown.md +265 -4
- package/docs/fr/intlayer_with_analog.md +23 -1
- package/docs/fr/intlayer_with_angular_19.md +24 -1
- package/docs/fr/intlayer_with_angular_21.md +24 -1
- package/docs/fr/intlayer_with_astro.md +24 -1
- package/docs/fr/intlayer_with_astro_lit.md +25 -1
- package/docs/fr/intlayer_with_astro_preact.md +26 -1
- package/docs/fr/intlayer_with_astro_react.md +26 -1
- package/docs/fr/intlayer_with_astro_solid.md +26 -1
- package/docs/fr/intlayer_with_astro_svelte.md +25 -1
- package/docs/fr/intlayer_with_astro_vue.md +25 -1
- package/docs/fr/intlayer_with_remix_3.md +22 -1
- package/docs/fr/self_hosting.md +401 -224
- package/docs/hi/benchmark/nextjs.md +13 -13
- package/docs/hi/benchmark/solid.md +5 -5
- package/docs/hi/benchmark/svelte.md +4 -4
- package/docs/hi/benchmark/tanstack.md +14 -13
- package/docs/hi/benchmark/vue.md +5 -5
- package/docs/hi/chrome_extension.md +130 -0
- package/docs/hi/cli/index.md +6 -1
- package/docs/hi/cli/infra.md +162 -0
- package/docs/hi/cli/init.md +24 -1
- package/docs/hi/dictionary/html.md +173 -5
- package/docs/hi/dictionary/markdown.md +263 -1
- package/docs/hi/intlayer_with_analog.md +23 -1
- package/docs/hi/intlayer_with_angular_19.md +24 -1
- package/docs/hi/intlayer_with_angular_21.md +24 -1
- package/docs/hi/intlayer_with_astro.md +24 -1
- package/docs/hi/intlayer_with_astro_lit.md +25 -1
- package/docs/hi/intlayer_with_astro_preact.md +26 -1
- package/docs/hi/intlayer_with_astro_react.md +26 -1
- package/docs/hi/intlayer_with_astro_solid.md +26 -1
- package/docs/hi/intlayer_with_astro_svelte.md +25 -1
- package/docs/hi/intlayer_with_astro_vue.md +25 -1
- package/docs/hi/intlayer_with_remix_3.md +22 -1
- package/docs/hi/self_hosting.md +409 -235
- package/docs/id/benchmark/nextjs.md +13 -13
- package/docs/id/benchmark/solid.md +5 -5
- package/docs/id/benchmark/svelte.md +4 -4
- package/docs/id/benchmark/tanstack.md +14 -13
- package/docs/id/benchmark/vue.md +5 -5
- package/docs/id/chrome_extension.md +130 -0
- package/docs/id/cli/index.md +6 -1
- package/docs/id/cli/infra.md +162 -0
- package/docs/id/cli/init.md +24 -1
- package/docs/id/dictionary/html.md +173 -5
- package/docs/id/dictionary/markdown.md +263 -1
- package/docs/id/intlayer_with_analog.md +23 -1
- package/docs/id/intlayer_with_angular_19.md +24 -1
- package/docs/id/intlayer_with_angular_21.md +24 -1
- package/docs/id/intlayer_with_astro.md +24 -1
- package/docs/id/intlayer_with_astro_lit.md +25 -1
- package/docs/id/intlayer_with_astro_preact.md +26 -1
- package/docs/id/intlayer_with_astro_react.md +26 -1
- package/docs/id/intlayer_with_astro_solid.md +26 -1
- package/docs/id/intlayer_with_astro_svelte.md +25 -1
- package/docs/id/intlayer_with_astro_vue.md +25 -1
- package/docs/id/intlayer_with_remix_3.md +22 -1
- package/docs/id/self_hosting.md +416 -243
- package/docs/it/benchmark/nextjs.md +13 -13
- package/docs/it/benchmark/solid.md +5 -5
- package/docs/it/benchmark/svelte.md +4 -4
- package/docs/it/benchmark/tanstack.md +14 -13
- package/docs/it/benchmark/vue.md +5 -5
- package/docs/it/chrome_extension.md +130 -0
- package/docs/it/cli/index.md +6 -1
- package/docs/it/cli/infra.md +162 -0
- package/docs/it/cli/init.md +24 -1
- package/docs/it/dictionary/html.md +173 -5
- package/docs/it/dictionary/markdown.md +263 -1
- package/docs/it/intlayer_with_analog.md +23 -1
- package/docs/it/intlayer_with_angular_19.md +24 -1
- package/docs/it/intlayer_with_angular_21.md +24 -1
- package/docs/it/intlayer_with_astro.md +24 -1
- package/docs/it/intlayer_with_astro_lit.md +25 -1
- package/docs/it/intlayer_with_astro_preact.md +26 -1
- package/docs/it/intlayer_with_astro_react.md +26 -1
- package/docs/it/intlayer_with_astro_solid.md +26 -1
- package/docs/it/intlayer_with_astro_svelte.md +25 -1
- package/docs/it/intlayer_with_astro_vue.md +25 -1
- package/docs/it/intlayer_with_remix_3.md +22 -1
- package/docs/it/self_hosting.md +412 -237
- package/docs/ja/benchmark/nextjs.md +13 -13
- package/docs/ja/benchmark/solid.md +5 -5
- package/docs/ja/benchmark/svelte.md +4 -4
- package/docs/ja/benchmark/tanstack.md +13 -12
- package/docs/ja/benchmark/vue.md +5 -5
- package/docs/ja/chrome_extension.md +130 -0
- package/docs/ja/cli/index.md +6 -1
- package/docs/ja/cli/infra.md +162 -0
- package/docs/ja/cli/init.md +24 -1
- package/docs/ja/dictionary/html.md +173 -5
- package/docs/ja/dictionary/markdown.md +263 -1
- package/docs/ja/intlayer_with_analog.md +23 -1
- package/docs/ja/intlayer_with_angular_19.md +24 -1
- package/docs/ja/intlayer_with_angular_21.md +24 -1
- package/docs/ja/intlayer_with_astro.md +24 -1
- package/docs/ja/intlayer_with_astro_lit.md +25 -1
- package/docs/ja/intlayer_with_astro_preact.md +26 -1
- package/docs/ja/intlayer_with_astro_react.md +26 -1
- package/docs/ja/intlayer_with_astro_solid.md +26 -1
- package/docs/ja/intlayer_with_astro_svelte.md +25 -1
- package/docs/ja/intlayer_with_astro_vue.md +25 -1
- package/docs/ja/intlayer_with_remix_3.md +22 -1
- package/docs/ja/self_hosting.md +398 -223
- package/docs/ko/benchmark/nextjs.md +13 -13
- package/docs/ko/benchmark/solid.md +5 -5
- package/docs/ko/benchmark/svelte.md +4 -4
- package/docs/ko/benchmark/tanstack.md +14 -13
- package/docs/ko/benchmark/vue.md +5 -5
- package/docs/ko/chrome_extension.md +130 -0
- package/docs/ko/cli/index.md +6 -1
- package/docs/ko/cli/infra.md +162 -0
- package/docs/ko/cli/init.md +24 -1
- package/docs/ko/dictionary/html.md +173 -5
- package/docs/ko/dictionary/markdown.md +263 -1
- package/docs/ko/intlayer_with_analog.md +23 -1
- package/docs/ko/intlayer_with_angular_19.md +24 -1
- package/docs/ko/intlayer_with_angular_21.md +24 -1
- package/docs/ko/intlayer_with_astro.md +24 -1
- package/docs/ko/intlayer_with_astro_lit.md +25 -1
- package/docs/ko/intlayer_with_astro_preact.md +26 -1
- package/docs/ko/intlayer_with_astro_react.md +26 -1
- package/docs/ko/intlayer_with_astro_solid.md +26 -1
- package/docs/ko/intlayer_with_astro_svelte.md +25 -1
- package/docs/ko/intlayer_with_astro_vue.md +25 -1
- package/docs/ko/intlayer_with_remix_3.md +22 -1
- package/docs/ko/self_hosting.md +411 -238
- package/docs/pl/benchmark/nextjs.md +13 -13
- package/docs/pl/benchmark/solid.md +5 -5
- package/docs/pl/benchmark/svelte.md +4 -4
- package/docs/pl/benchmark/tanstack.md +14 -13
- package/docs/pl/benchmark/vue.md +5 -5
- package/docs/pl/chrome_extension.md +130 -0
- package/docs/pl/cli/index.md +6 -1
- package/docs/pl/cli/infra.md +162 -0
- package/docs/pl/cli/init.md +24 -1
- package/docs/pl/dictionary/html.md +173 -5
- package/docs/pl/dictionary/markdown.md +263 -1
- package/docs/pl/intlayer_with_analog.md +23 -1
- package/docs/pl/intlayer_with_angular_19.md +24 -1
- package/docs/pl/intlayer_with_angular_21.md +24 -1
- package/docs/pl/intlayer_with_astro.md +24 -1
- package/docs/pl/intlayer_with_astro_lit.md +25 -1
- package/docs/pl/intlayer_with_astro_preact.md +26 -1
- package/docs/pl/intlayer_with_astro_react.md +26 -1
- package/docs/pl/intlayer_with_astro_solid.md +26 -1
- package/docs/pl/intlayer_with_astro_svelte.md +25 -1
- package/docs/pl/intlayer_with_astro_vue.md +25 -1
- package/docs/pl/intlayer_with_remix_3.md +22 -1
- package/docs/pl/self_hosting.md +408 -233
- package/docs/pt/benchmark/nextjs.md +13 -13
- package/docs/pt/benchmark/solid.md +5 -5
- package/docs/pt/benchmark/svelte.md +4 -4
- package/docs/pt/benchmark/tanstack.md +14 -13
- package/docs/pt/benchmark/vue.md +5 -5
- package/docs/pt/chrome_extension.md +130 -0
- package/docs/pt/cli/index.md +6 -1
- package/docs/pt/cli/infra.md +162 -0
- package/docs/pt/cli/init.md +24 -1
- package/docs/pt/dictionary/html.md +173 -5
- package/docs/pt/dictionary/markdown.md +263 -1
- package/docs/pt/intlayer_with_analog.md +23 -1
- package/docs/pt/intlayer_with_angular_19.md +24 -1
- package/docs/pt/intlayer_with_angular_21.md +24 -1
- package/docs/pt/intlayer_with_astro.md +24 -1
- package/docs/pt/intlayer_with_astro_lit.md +25 -1
- package/docs/pt/intlayer_with_astro_preact.md +26 -1
- package/docs/pt/intlayer_with_astro_react.md +26 -1
- package/docs/pt/intlayer_with_astro_solid.md +26 -1
- package/docs/pt/intlayer_with_astro_svelte.md +25 -1
- package/docs/pt/intlayer_with_astro_vue.md +25 -1
- package/docs/pt/intlayer_with_remix_3.md +22 -1
- package/docs/pt/self_hosting.md +399 -224
- package/docs/ru/benchmark/nextjs.md +13 -13
- package/docs/ru/benchmark/solid.md +5 -5
- package/docs/ru/benchmark/svelte.md +4 -4
- package/docs/ru/benchmark/tanstack.md +14 -13
- package/docs/ru/benchmark/vue.md +5 -5
- package/docs/ru/chrome_extension.md +130 -0
- package/docs/ru/cli/index.md +6 -1
- package/docs/ru/cli/infra.md +162 -0
- package/docs/ru/cli/init.md +24 -1
- package/docs/ru/dictionary/html.md +173 -5
- package/docs/ru/dictionary/markdown.md +263 -1
- package/docs/ru/intlayer_with_analog.md +23 -1
- package/docs/ru/intlayer_with_angular_19.md +24 -1
- package/docs/ru/intlayer_with_angular_21.md +24 -1
- package/docs/ru/intlayer_with_astro.md +24 -1
- package/docs/ru/intlayer_with_astro_lit.md +25 -1
- package/docs/ru/intlayer_with_astro_preact.md +26 -1
- package/docs/ru/intlayer_with_astro_react.md +26 -1
- package/docs/ru/intlayer_with_astro_solid.md +26 -1
- package/docs/ru/intlayer_with_astro_svelte.md +25 -1
- package/docs/ru/intlayer_with_astro_vue.md +25 -1
- package/docs/ru/intlayer_with_remix_3.md +22 -1
- package/docs/ru/self_hosting.md +403 -228
- package/docs/tr/benchmark/nextjs.md +13 -13
- package/docs/tr/benchmark/solid.md +5 -5
- package/docs/tr/benchmark/svelte.md +4 -4
- package/docs/tr/benchmark/tanstack.md +14 -13
- package/docs/tr/benchmark/vue.md +5 -5
- package/docs/tr/chrome_extension.md +130 -0
- package/docs/tr/cli/index.md +6 -1
- package/docs/tr/cli/infra.md +162 -0
- package/docs/tr/cli/init.md +24 -1
- package/docs/tr/dictionary/html.md +173 -5
- package/docs/tr/dictionary/markdown.md +263 -1
- package/docs/tr/intlayer_with_analog.md +23 -1
- package/docs/tr/intlayer_with_angular_19.md +24 -1
- package/docs/tr/intlayer_with_angular_21.md +24 -1
- package/docs/tr/intlayer_with_astro.md +24 -1
- package/docs/tr/intlayer_with_astro_lit.md +25 -1
- package/docs/tr/intlayer_with_astro_preact.md +26 -1
- package/docs/tr/intlayer_with_astro_react.md +26 -1
- package/docs/tr/intlayer_with_astro_solid.md +26 -1
- package/docs/tr/intlayer_with_astro_svelte.md +25 -1
- package/docs/tr/intlayer_with_astro_vue.md +25 -1
- package/docs/tr/intlayer_with_remix_3.md +22 -1
- package/docs/tr/self_hosting.md +410 -234
- package/docs/uk/benchmark/nextjs.md +13 -13
- package/docs/uk/benchmark/solid.md +5 -5
- package/docs/uk/benchmark/svelte.md +4 -4
- package/docs/uk/benchmark/tanstack.md +14 -13
- package/docs/uk/benchmark/vue.md +5 -5
- package/docs/uk/chrome_extension.md +130 -0
- package/docs/uk/cli/index.md +6 -1
- package/docs/uk/cli/infra.md +162 -0
- package/docs/uk/cli/init.md +24 -1
- package/docs/uk/dictionary/html.md +173 -5
- package/docs/uk/dictionary/markdown.md +263 -1
- package/docs/uk/intlayer_with_analog.md +23 -1
- package/docs/uk/intlayer_with_angular_19.md +24 -1
- package/docs/uk/intlayer_with_angular_21.md +24 -1
- package/docs/uk/intlayer_with_astro.md +24 -1
- package/docs/uk/intlayer_with_astro_lit.md +25 -1
- package/docs/uk/intlayer_with_astro_preact.md +26 -1
- package/docs/uk/intlayer_with_astro_react.md +26 -1
- package/docs/uk/intlayer_with_astro_solid.md +26 -1
- package/docs/uk/intlayer_with_astro_svelte.md +25 -1
- package/docs/uk/intlayer_with_astro_vue.md +25 -1
- package/docs/uk/intlayer_with_remix_3.md +22 -1
- package/docs/uk/self_hosting.md +413 -238
- package/docs/vi/benchmark/nextjs.md +13 -13
- package/docs/vi/benchmark/solid.md +5 -5
- package/docs/vi/benchmark/svelte.md +4 -4
- package/docs/vi/benchmark/tanstack.md +14 -13
- package/docs/vi/benchmark/vue.md +5 -5
- package/docs/vi/chrome_extension.md +130 -0
- package/docs/vi/cli/index.md +6 -1
- package/docs/vi/cli/infra.md +162 -0
- package/docs/vi/cli/init.md +24 -1
- package/docs/vi/dictionary/html.md +173 -5
- package/docs/vi/dictionary/markdown.md +263 -1
- package/docs/vi/intlayer_with_analog.md +23 -1
- package/docs/vi/intlayer_with_angular_19.md +24 -1
- package/docs/vi/intlayer_with_angular_21.md +24 -1
- package/docs/vi/intlayer_with_astro.md +24 -1
- package/docs/vi/intlayer_with_astro_lit.md +25 -1
- package/docs/vi/intlayer_with_astro_preact.md +26 -1
- package/docs/vi/intlayer_with_astro_react.md +26 -1
- package/docs/vi/intlayer_with_astro_solid.md +26 -1
- package/docs/vi/intlayer_with_astro_svelte.md +25 -1
- package/docs/vi/intlayer_with_astro_vue.md +25 -1
- package/docs/vi/intlayer_with_remix_3.md +22 -1
- package/docs/vi/self_hosting.md +408 -234
- package/docs/zh/benchmark/nextjs.md +13 -13
- package/docs/zh/benchmark/solid.md +5 -5
- package/docs/zh/benchmark/svelte.md +4 -4
- package/docs/zh/benchmark/tanstack.md +14 -13
- package/docs/zh/benchmark/vue.md +5 -5
- package/docs/zh/chrome_extension.md +130 -0
- package/docs/zh/cli/index.md +6 -1
- package/docs/zh/cli/infra.md +162 -0
- package/docs/zh/cli/init.md +24 -1
- package/docs/zh/dictionary/html.md +172 -5
- package/docs/zh/dictionary/markdown.md +262 -1
- package/docs/zh/intlayer_with_analog.md +23 -1
- package/docs/zh/intlayer_with_angular_19.md +24 -1
- package/docs/zh/intlayer_with_angular_21.md +24 -1
- package/docs/zh/intlayer_with_astro.md +24 -1
- package/docs/zh/intlayer_with_astro_lit.md +25 -1
- package/docs/zh/intlayer_with_astro_preact.md +26 -1
- package/docs/zh/intlayer_with_astro_react.md +26 -1
- package/docs/zh/intlayer_with_astro_solid.md +26 -1
- package/docs/zh/intlayer_with_astro_svelte.md +25 -1
- package/docs/zh/intlayer_with_astro_vue.md +25 -1
- package/docs/zh/intlayer_with_remix_3.md +22 -1
- package/docs/zh/self_hosting.md +410 -237
- package/legal/ar/privacy_notice.md +9 -3
- package/legal/de/privacy_notice.md +9 -3
- package/legal/en/privacy_notice.md +10 -3
- package/legal/en-GB/privacy_notice.md +9 -3
- package/legal/es/privacy_notice.md +9 -3
- package/legal/fr/privacy_notice.md +9 -3
- package/legal/hi/privacy_notice.md +9 -3
- package/legal/id/privacy_notice.md +9 -3
- package/legal/it/privacy_notice.md +9 -3
- package/legal/ja/privacy_notice.md +9 -3
- package/legal/ko/privacy_notice.md +9 -3
- package/legal/pl/privacy_notice.md +9 -3
- package/legal/pt/privacy_notice.md +9 -3
- package/legal/ru/privacy_notice.md +9 -3
- package/legal/tr/privacy_notice.md +9 -3
- package/legal/uk/privacy_notice.md +9 -3
- package/legal/vi/privacy_notice.md +9 -3
- package/legal/zh/privacy_notice.md +9 -3
- package/package.json +1 -1
- package/src/generated/docs.entry.ts +40 -40
- package/docs/ar/roadmap.md +0 -321
- package/docs/de/roadmap.md +0 -322
- package/docs/en/intlayer_with_astro_vanilla.md +0 -713
- package/docs/en/roadmap.md +0 -325
- package/docs/en-GB/roadmap.md +0 -322
- package/docs/es/roadmap.md +0 -322
- package/docs/fr/roadmap.md +0 -322
- package/docs/hi/roadmap.md +0 -322
- package/docs/id/roadmap.md +0 -325
- package/docs/it/roadmap.md +0 -322
- package/docs/ja/roadmap.md +0 -322
- package/docs/ko/roadmap.md +0 -322
- package/docs/pl/roadmap.md +0 -325
- package/docs/pt/roadmap.md +0 -322
- package/docs/ru/roadmap.md +0 -322
- package/docs/tr/roadmap.md +0 -325
- package/docs/uk/roadmap.md +0 -325
- package/docs/vi/roadmap.md +0 -325
- package/docs/zh/roadmap.md +0 -322
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-09-13
|
|
3
|
-
updatedAt: 2026-09-
|
|
3
|
+
updatedAt: 2026-09-22
|
|
4
4
|
title: "i18next vs Intlayer: Đo kiểm và So sánh chi tiết năm 2026"
|
|
5
5
|
description: "Đo lường react-i18next và next-i18next so với Intlayer trên Next.js và TanStack Start. Kích thước bundle, rò rỉ nội dung, tốc độ phản hồi khi chuyển ngôn ngữ và trải nghiệm lập trình viên."
|
|
6
6
|
keywords:
|
|
@@ -25,6 +25,8 @@ author: aymericzip
|
|
|
25
25
|
|
|
26
26
|
# i18next VS Intlayer | Đo kiểm đa ngôn ngữ (i18n) cho React & Next.js
|
|
27
27
|
|
|
28
|
+

|
|
29
|
+
|
|
28
30
|
`i18next` là framework i18n phổ biến nhất trong hệ sinh thái JavaScript. Thông qua `react-i18next` và `next-i18next`, nó đang vận hành phần lớn các ứng dụng React và Next.js. Intlayer là một giải pháp thay thế hiện đại dựa trên trình biên dịch và cô lập phạm vi theo từng component.
|
|
29
31
|
|
|
30
32
|
Bài viết này so sánh hai giải pháp dựa trên số liệu đo lường thực tế thay vì danh sách tính năng đơn thuần. Các số liệu được trích xuất từ [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) - một bộ đo lường nguồn mở xây dựng cùng một ứng dụng mẫu trên từng thư viện và ghi nhận chính xác những gì trình duyệt tải về.
|
|
@@ -99,6 +101,10 @@ Các chỉ số đo lường:
|
|
|
99
101
|
|
|
100
102
|
### Kết quả trên Next.js (`next-i18next`)
|
|
101
103
|
|
|
104
|
+
Chọn các chỉ số và thư viện bạn quan tâm:
|
|
105
|
+
|
|
106
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
107
|
+
|
|
102
108
|
| Thư viện | Chiến lược | Dung lượng Lib (gz) | JS TB mỗi trang (gz) | Rò rỉ ngôn ngữ | Rò rỉ trang | Kích thước TB Comp (gz) | Phản hồi E2E | Thời gian Hydrate |
|
|
103
109
|
| -------------------------------------- | -------------- | ------------------: | -------------------: | -------------: | ----------: | ----------------------: | -----------: | ----------------: |
|
|
104
110
|
| **base** (không i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -119,6 +125,15 @@ Các chỉ số đo lường:
|
|
|
119
125
|
- **Kích thước từng component**: Một component gọi `useTranslation()` được đóng gói trong khoảng 26 đến 79 KB; trong khi component tương đương dùng `useIntlayer()` chỉ nặng 6.9 KB.
|
|
120
126
|
- **Độ trễ khi hydrate**: Thời gian hydrate tăng vọt lên 27.7 ms ở cấu hình `dynamic` do thực thể i18next cần khởi tạo và nạp backend tại client trước khi React có thể hoàn tất quá trình hydrate.
|
|
121
127
|
|
|
128
|
+
<ClickToOpenIframe
|
|
129
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.md"
|
|
130
|
+
width="100%"
|
|
131
|
+
height="600px"
|
|
132
|
+
style="border:none;"
|
|
133
|
+
/>
|
|
134
|
+
|
|
135
|
+
> Bảng đầy đủ, từng thư viện và từng chiến lược, trong [báo cáo benchmark Next.js](https://intlayer.org/vi/doc/benchmark/nextjs).
|
|
136
|
+
|
|
122
137
|
### Kết quả trên TanStack Start (`react-i18next`)
|
|
123
138
|
|
|
124
139
|
Cùng ứng dụng kiểm thử trên nền tảng TanStack Start sử dụng trực tiếp `react-i18next` nhằm loại bỏ các yếu tố can thiệp riêng của Next.js:
|
|
@@ -141,8 +156,19 @@ Cùng ứng dụng kiểm thử trên nền tảng TanStack Start sử dụng tr
|
|
|
141
156
|
- Chế độ `static` của Intlayer đã mặc định đạt **0% rò rỉ trang** vì nó chỉ đóng gói các từ điển được import bởi component của trang đó. Bật `importMode: 'dynamic'` sẽ triệt tiêu hoàn toàn rò rỉ ngôn ngữ.
|
|
142
157
|
- **Kích thước component**: 24-27 KB ở `react-i18next` so với 6-8 KB ở Intlayer. `useTranslation()` luôn gắn chặt từng component với instance i18next toàn cục.
|
|
143
158
|
|
|
159
|
+
<ClickToOpenIframe
|
|
160
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.md"
|
|
161
|
+
width="100%"
|
|
162
|
+
height="600px"
|
|
163
|
+
style="border:none;"
|
|
164
|
+
/>
|
|
165
|
+
|
|
166
|
+
> Bảng đầy đủ trong [báo cáo benchmark TanStack Start](https://intlayer.org/vi/doc/benchmark/tanstack).
|
|
167
|
+
|
|
144
168
|
## Nguyên nhân của sự chênh lệch: Global Instance vs Từ điển biên dịch
|
|
145
169
|
|
|
170
|
+

|
|
171
|
+
|
|
146
172
|
`i18next` được xây dựng từ năm 2012 theo hướng runtime: một instance toàn cục nắm giữ kho tài nguyên, các plugin mở rộng nó và hàm `t()` tìm khóa khi render. Thiết kế này đem lại tính linh hoạt cao nhưng tạo ra gánh nặng lớn về dung lượng:
|
|
147
173
|
|
|
148
174
|
```bash
|
|
@@ -166,7 +192,13 @@ Cùng ứng dụng kiểm thử trên nền tảng TanStack Start sử dụng tr
|
|
|
166
192
|
└── page.tsx # phải tự biết rằng trang này cần ["common", "about"]
|
|
167
193
|
```
|
|
168
194
|
|
|
169
|
-
Instance toàn cục không thể biết trước component sẽ gọi những khóa nào; vì vậy nó buộc phải lưu trữ toàn bộ các namespace được chỉ định nạp. Muốn tối ưu, **bạn** phải chia nhỏ danh mục, **bạn** phải liệt kê các namespace cần thiết cho từng trang, và **bạn** phải duy trì danh sách này khi component di chuyển.
|
|
195
|
+
Instance toàn cục không thể biết trước component sẽ gọi những khóa nào; vì vậy nó buộc phải lưu trữ toàn bộ các namespace được chỉ định nạp. Muốn tối ưu, **bạn** phải chia nhỏ danh mục, **bạn** phải liệt kê các namespace cần thiết cho từng trang, và **bạn** phải duy trì danh sách này khi component di chuyển.
|
|
196
|
+
|
|
197
|
+
Chi phí gia tăng đồng thời trên hai trục, trang và ngôn ngữ:
|
|
198
|
+
|
|
199
|
+

|
|
200
|
+
|
|
201
|
+
Đúng như [ghi chú benchmark](https://github.com/intlayer-org/benchmark-bloom/blob/main/report/NOTE.md) đã chỉ ra: "Vừa duy trì an toàn kiểu dữ liệu vừa quản lý đúng namespace cho từng trang thực sự là một cơn ác mộng".
|
|
170
202
|
|
|
171
203
|
Intlayer loại bỏ hoàn toàn instance toàn cục. Nội dung được khai báo ngay cạnh component và trình biên dịch sẽ giải quyết cây phụ thuộc vào lúc build:
|
|
172
204
|
|
|
@@ -193,7 +225,8 @@ Intlayer loại bỏ hoàn toàn instance toàn cục. Nội dung được khai
|
|
|
193
225
|
|
|
194
226
|
### Khởi tạo cấu hình
|
|
195
227
|
|
|
196
|
-
|
|
228
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
229
|
+
<Tab label="next-i18next" value="i18next">
|
|
197
230
|
|
|
198
231
|
```ts fileName="src/app/i18n/server.ts"
|
|
199
232
|
import { createInstance } from "i18next";
|
|
@@ -228,7 +261,8 @@ export const initI18next = async (
|
|
|
228
261
|
|
|
229
262
|
Bên cạnh đó, bạn phải viết thêm `I18nProvider` ở phía client, khai báo `generateStaticParams` và quản lý mảng `namespaces` trên từng trang.
|
|
230
263
|
|
|
231
|
-
|
|
264
|
+
</Tab>
|
|
265
|
+
<Tab label="Intlayer" value="intlayer">
|
|
232
266
|
|
|
233
267
|
```ts fileName="intlayer.config.ts"
|
|
234
268
|
import { type IntlayerConfig, Locales } from "intlayer";
|
|
@@ -264,9 +298,13 @@ const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
|
|
|
264
298
|
export default LocaleLayout;
|
|
265
299
|
```
|
|
266
300
|
|
|
301
|
+
</Tab>
|
|
302
|
+
</Tabs>
|
|
303
|
+
|
|
267
304
|
### Component phía Client
|
|
268
305
|
|
|
269
|
-
|
|
306
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
307
|
+
<Tab label="react-i18next" value="i18next">
|
|
270
308
|
|
|
271
309
|
```json fileName="src/locales/en/about.json"
|
|
272
310
|
{
|
|
@@ -304,7 +342,8 @@ export const Counter = () => {
|
|
|
304
342
|
|
|
305
343
|
> Trang hiển thị component này bắt buộc phải nạp namespace `about`, và `t("counter.label")` sẽ chỉ là chuỗi thông thường nếu chưa mở rộng `CustomTypeOptions`.
|
|
306
344
|
|
|
307
|
-
|
|
345
|
+
</Tab>
|
|
346
|
+
<Tab label="Intlayer" value="intlayer">
|
|
308
347
|
|
|
309
348
|
```ts fileName="src/components/Counter/index.content.ts"
|
|
310
349
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -345,9 +384,13 @@ export const Counter = () => {
|
|
|
345
384
|
|
|
346
385
|
`label` và `increment` đều được kiểm tra kiểu dữ liệu nghiêm ngặt; gõ sai tên sẽ báo lỗi TypeScript ngay lập tức, và nếu thiếu bản dịch tiếng Pháp thì quá trình build sẽ bị dừng lại.
|
|
347
386
|
|
|
387
|
+
</Tab>
|
|
388
|
+
</Tabs>
|
|
389
|
+
|
|
348
390
|
### Component phía Server đồng bộ
|
|
349
391
|
|
|
350
|
-
|
|
392
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
393
|
+
<Tab label="next-i18next" value="i18next">
|
|
351
394
|
|
|
352
395
|
```tsx fileName="src/components/ServerCounter.tsx"
|
|
353
396
|
type ServerCounterProps = {
|
|
@@ -366,7 +409,8 @@ export const ServerCounter = ({ t, locale, count }: ServerCounterProps) => (
|
|
|
366
409
|
|
|
367
410
|
Trang cha phải gọi `i18n.getFixedT(locale, "about")` rồi truyền `t` và `locale` xuống dưới dạng props.
|
|
368
411
|
|
|
369
|
-
|
|
412
|
+
</Tab>
|
|
413
|
+
<Tab label="Intlayer" value="intlayer">
|
|
370
414
|
|
|
371
415
|
```tsx fileName="src/components/ServerCounter.tsx"
|
|
372
416
|
import { useIntlayer } from "next-intlayer/server";
|
|
@@ -385,6 +429,9 @@ export const ServerCounter = ({ count }: { count: number }) => {
|
|
|
385
429
|
};
|
|
386
430
|
```
|
|
387
431
|
|
|
432
|
+
</Tab>
|
|
433
|
+
</Tabs>
|
|
434
|
+
|
|
388
435
|
## Giữ nguyên API của i18next, nhận ngay hiệu năng của Intlayer
|
|
389
436
|
|
|
390
437
|
Bạn không cần phải viết lại toàn bộ component để đạt được kết quả benchmark trên. `@intlayer/i18next`, `@intlayer/react-i18next` và `@intlayer/next-i18next` đóng vai trò là các adapter tương thích trực tiếp: các lệnh gọi `useTranslation`, `t()`, `<Trans>`, xử lý số nhiều và ngữ cảnh vẫn hoạt động bình thường, được vận hành bởi các từ điển do trình biên dịch Intlayer cung cấp.
|
|
@@ -415,18 +462,85 @@ Xem hướng dẫn chuyển đổi: [i18next](https://intlayer.org/vi/doc/migrat
|
|
|
415
462
|
|
|
416
463
|
## Khi nào nên chọn giải pháp nào?
|
|
417
464
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
465
|
+
<AccordionGroup>
|
|
466
|
+
<Accordion header="Chọn i18next">
|
|
467
|
+
|
|
468
|
+
Nếu bạn phụ thuộc chặt chẽ vào hệ sinh thái plugin (bộ nhận diện đặc thù, backend chuyên biệt, ICU, Locize), cần bản địa hóa ở cả ngoài React (Node services, vanilla JS, các framework khác), đội ngũ của bạn đã rất thành thạo, hoặc nền tảng dịch thuật bắt buộc định dạng `locales/{lng}/{ns}.json`. Hãy dành thời gian để quản lý namespace và bản đồ route nếu hiệu năng là ưu tiên hàng đầu.
|
|
469
|
+
|
|
470
|
+
</Accordion>
|
|
471
|
+
<Accordion header="Chọn Intlayer">
|
|
472
|
+
|
|
473
|
+
Bạn mong muốn **nội dung theo phạm vi component**, **TypeScript nghiêm ngặt**, **phát hiện thiếu khóa trong thời gian build**, **tree-shaking và lazy loading không tốn công sức**, chuyển đổi ngôn ngữ tức thì, server component đồng bộ và các công cụ biên tập tích hợp sẵn ([Visual Editor](https://intlayer.org/vi/doc/concept/editor), [CMS](https://intlayer.org/vi/doc/concept/cms), [dịch thuật AI](https://intlayer.org/vi/doc/concept/auto-fill), [MCP server](https://intlayer.org/vi/doc/mcp-server)). Đặc biệt phù hợp cho các codebase dạng module quy mô lớn và design system.
|
|
474
|
+
|
|
475
|
+
</Accordion>
|
|
476
|
+
<Accordion header="Chọn adapter @intlayer/*-i18next">
|
|
477
|
+
|
|
478
|
+
Bạn đã sử dụng i18next và muốn tối ưu dung lượng bundle cùng độ phản hồi mà không cần viết lại component. Các tệp `locales/{lng}/{ns}.json` hiện tại vẫn là nguồn chân lý duy nhất. Được đo lường song song trong [i18next vs @intlayer/i18next](https://intlayer.org/vi/blog/i18next-vs-intlayer-i18next).
|
|
479
|
+
|
|
480
|
+
</Accordion>
|
|
481
|
+
</AccordionGroup>
|
|
482
|
+
|
|
483
|
+
## FAQ (Câu hỏi thường gặp)
|
|
484
|
+
|
|
485
|
+
<FAQ>
|
|
486
|
+
|
|
487
|
+
<Question title="Tại sao i18next lại nặng hơn nhiều so với các thư viện khác?">
|
|
488
|
+
|
|
489
|
+
Nó được thiết kế như một runtime độc lập với framework: một global instance, một pipeline plugin, một kho lưu trữ tài nguyên, một bộ phân giải khóa. Sự linh hoạt đó được biên dịch vào từng bundle. Một component rỗng chỉ import thư viện đã tốn **19.7 KB gzip** với `next-i18next` so với **5.5 KB** của `next-intlayer`, và chi phí đó phải trả trên mọi trang bất kể nội dung của bạn nặng bao nhiêu.
|
|
490
|
+
|
|
491
|
+
</Question>
|
|
492
|
+
|
|
493
|
+
<Question title="Lazy loading với backend có giải quyết được vấn đề không?">
|
|
494
|
+
|
|
495
|
+
Nó giảm dung lượng byte, nhưng không giải quyết được độ trễ. Chuyển sang `i18next-resources-to-backend` tiết kiệm ~49 KB mỗi trang nhưng lại thêm một round-trip mạng khi chuyển đổi ngôn ngữ: **123 ms** trong cấu hình `dynamic` và **185 ms** trong `scoped-static`, so với **3-4 ms** của Intlayer. Thời gian hydration cũng tăng lên 27.7 ms vì instance phải phân giải backend trước khi React có thể hydrate.
|
|
496
|
+
|
|
497
|
+
</Question>
|
|
498
|
+
|
|
499
|
+
<Question title="Tôi có thể đạt 0% rò rỉ nội dung với i18next không?">
|
|
500
|
+
|
|
501
|
+
Có, với `scoped-dynamic`: một namespace cho mỗi route, một backend tài nguyên và một bảng ánh xạ trang - namespace bạn tự quản lý thủ công. Kích thước trang đạt 163.4 KB trên Next.js, vẫn cao hơn **+22 KB** so với 141.3 KB của Intlayer vốn không cần bất kỳ cấu hình nào. Xem [tối ưu hóa bundle](https://intlayer.org/vi/doc/concept/bundle-optimization).
|
|
502
|
+
|
|
503
|
+
</Question>
|
|
504
|
+
|
|
505
|
+
<Question title="Tôi có phải viết lại các component để di chuyển không?">
|
|
506
|
+
|
|
507
|
+
Không. `@intlayer/i18next`, `@intlayer/react-i18next` và `@intlayer/next-i18next` giữ nguyên `useTranslation`, `t()`, `<Trans>`, `{{interpolation}}`, các dạng số nhiều `_one` / `_other`, hậu tố ngữ cảnh và `returnObjects`. Chỉ một dòng plugin trong `next.config.ts` hoặc `vite.config.ts`. Chi tiết từng bước trong [hướng dẫn di chuyển next-i18next](https://intlayer.org/vi/doc/migration/next-i18next).
|
|
508
|
+
|
|
509
|
+
</Question>
|
|
510
|
+
|
|
511
|
+
<Question title="Điều gì xảy ra với các plugin i18next của tôi?">
|
|
512
|
+
|
|
513
|
+
Các backend và plugin phát hiện ngôn ngữ vẫn được chấp nhận nhưng ở trạng thái bất hoạt: không còn gì để tải hoặc phát hiện trong thời gian chạy. Việc phát hiện ngôn ngữ trở thành cấu hình định tuyến của Intlayer (tiền tố URL, cookie, header). Nếu ứng dụng của bạn lấy bản dịch từ CMS tại thời điểm yêu cầu, hãy sử dụng [Intlayer CMS](https://intlayer.org/vi/doc/concept/cms) hoặc lệnh `intlayer pull` / `push` thay thế.
|
|
514
|
+
|
|
515
|
+
</Question>
|
|
516
|
+
|
|
517
|
+
</FAQ>
|
|
421
518
|
|
|
422
519
|
## Các bài so sánh liên quan
|
|
423
520
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
- [
|
|
521
|
+
Cùng benchmark, các thư viện khác:
|
|
522
|
+
|
|
523
|
+
- [next-intl vs Intlayer](https://intlayer.org/vi/blog/next-intl-vs-intlayer)
|
|
524
|
+
- [Lingui vs Intlayer](https://intlayer.org/vi/blog/lingui-vs-intlayer)
|
|
525
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/vi/blog/vue-i18n-vs-intlayer-benchmark)
|
|
427
526
|
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/vi/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
428
527
|
- [react-i18next vs react-intl vs Intlayer](https://intlayer.org/vi/blog/react-i18next-vs-react-intl-vs-intlayer)
|
|
528
|
+
|
|
529
|
+
Tìm hiểu sâu hơn về i18next:
|
|
530
|
+
|
|
531
|
+
- [i18next vs @intlayer/i18next](https://intlayer.org/vi/blog/i18next-vs-intlayer-i18next), đo lường adapter trên cùng một ứng dụng
|
|
429
532
|
- [i18next có bị lỗi thời không?](https://intlayer.org/vi/blog/is-i18next-outdated)
|
|
533
|
+
- [Sử dụng Intlayer với i18next](https://intlayer.org/vi/blog/intlayer-with-i18next) và [với react-i18next](https://intlayer.org/vi/blog/intlayer-with-react-i18next)
|
|
534
|
+
- [Cách quốc tế hóa ứng dụng Next.js với next-i18next](https://intlayer.org/vi/blog/nextjs-internationalization-using-next-i18next)
|
|
535
|
+
|
|
536
|
+
Tài liệu tham khảo:
|
|
537
|
+
|
|
538
|
+
- [Báo cáo benchmark Next.js](https://intlayer.org/vi/doc/benchmark/nextjs) và [báo cáo benchmark TanStack Start](https://intlayer.org/vi/doc/benchmark/tanstack)
|
|
539
|
+
- Adapter tương thích: [i18next](https://intlayer.org/vi/doc/compatibility/i18next), [react-i18next](https://intlayer.org/vi/doc/compatibility/react-i18next), [next-i18next](https://intlayer.org/vi/doc/compatibility/next-i18next)
|
|
540
|
+
- Hướng dẫn di chuyển: [i18next](https://intlayer.org/vi/doc/migration/i18next), [react-i18next](https://intlayer.org/vi/doc/migration/react-i18next), [next-i18next](https://intlayer.org/vi/doc/migration/next-i18next)
|
|
541
|
+
- [Tối ưu hóa bundle](https://intlayer.org/vi/doc/concept/bundle-optimization) và [trình biên dịch Intlayer](https://intlayer.org/vi/doc/compiler)
|
|
542
|
+
- [i18n theo component vs i18n tập trung](https://intlayer.org/vi/blog/per-component-vs-centralized-i18n)
|
|
543
|
+
- [i18n dựa trên compiler vs khai báo](https://intlayer.org/vi/blog/compiler-vs-declarative-i18n)
|
|
430
544
|
|
|
431
545
|
## Lượt gắn sao trên GitHub
|
|
432
546
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-09-13
|
|
3
|
-
updatedAt: 2026-09-
|
|
3
|
+
updatedAt: 2026-09-22
|
|
4
4
|
title: "Lingui vs Intlayer: Điểm chuẩn & So sánh 2026"
|
|
5
5
|
description: "Hai thư viện i18n dựa trên trình biên dịch được đo lường trên Next.js và TanStack Start. Kích thước bundle, rò rỉ nội dung, kích thước component, quá trình hydrate, độ phản hồi chuyển đổi ngôn ngữ và trải nghiệm lập trình viên."
|
|
6
6
|
keywords:
|
|
@@ -24,6 +24,8 @@ author: aymericzip
|
|
|
24
24
|
|
|
25
25
|
# Lingui VS Intlayer | Điểm chuẩn quốc tế hóa (i18n) trên React & Next.js
|
|
26
26
|
|
|
27
|
+

|
|
28
|
+
|
|
27
29
|
Lingui và Intlayer là hai thư viện trong bài đánh giá điểm chuẩn này dựa trên một **trình biên dịch (compiler)** thay vì một runtime thuần túy. Lingui trích xuất các thông điệp từ macro trong thời gian build và biên dịch các danh mục theo từng ngôn ngữ. Intlayer biên dịch các từ điển theo từng component và thực hiện tree-shake chúng theo từng ngôn ngữ. Về mặt lý thuyết, chúng phải rất gần nhau. Các con số cho thấy chúng bắt đầu phân kỳ ở đâu.
|
|
28
30
|
|
|
29
31
|
Dữ liệu được lấy từ [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom), một bộ công cụ mã nguồn mở xây dựng cùng một ứng dụng với mỗi thư viện và ghi lại những gì trình duyệt thực sự tải xuống và thực thi.
|
|
@@ -96,6 +98,10 @@ Intlayer không có biến thể "scoped": trình biên dịch tự động gi
|
|
|
96
98
|
|
|
97
99
|
### Kết quả trên Next.js
|
|
98
100
|
|
|
101
|
+
Chọn các chỉ số và thư viện mà bạn quan tâm:
|
|
102
|
+
|
|
103
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
104
|
+
|
|
99
105
|
| Thư viện | Chiến lược | Kích thước Lib (gz) | JS trang TB (gz) | Rò rỉ ngôn ngữ | Rò rỉ trang | TB component (gz) | Độ phản hồi E2E | Hydrate |
|
|
100
106
|
| --------------------- | -------------- | ------------------: | ---------------: | -------------: | ----------: | ----------------: | --------------: | ------: |
|
|
101
107
|
| **base** (không i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -114,6 +120,15 @@ Intlayer không có biến thể "scoped": trình biên dịch tự động gi
|
|
|
114
120
|
- **Dự phòng ngôn ngữ nguồn bị rò rỉ.** Ngay cả trong các thiết lập tối ưu hóa, **3-15% chuỗi `en` vẫn bị đưa vào các trang `fr`**. Macro của Lingui giữ lại thông điệp nguồn như một phương án dự phòng, do đó nó nằm trong bundle bên cạnh bản dịch. Intlayer giải quyết các dự phòng tại thời gian build và chỉ gửi đúng ngôn ngữ đang hoạt động.
|
|
115
121
|
- **Kích thước component bùng nổ trong `scoped-dynamic`.** Mỗi component được biên dịch riêng lẻ đạt trung bình **152.6 KB**, vì danh mục của mọi route đều có thể truy cập được từ component import nó. Component tương tự sử dụng `useIntlayer()` chỉ đạt trung bình **6.9 KB**.
|
|
116
122
|
|
|
123
|
+
<ClickToOpenIframe
|
|
124
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.md"
|
|
125
|
+
width="100%"
|
|
126
|
+
height="600px"
|
|
127
|
+
style="border:none;"
|
|
128
|
+
/>
|
|
129
|
+
|
|
130
|
+
> Bảng đầy đủ, từng thư viện và từng chiến lược, trong [báo cáo benchmark Next.js](https://intlayer.org/vi/doc/benchmark/nextjs).
|
|
131
|
+
|
|
117
132
|
### Kết quả trên TanStack Start
|
|
118
133
|
|
|
119
134
|
| Thư viện | Chiến lược | Kích thước Lib (gz) | JS trang TB (gz) | Rò rỉ ngôn ngữ | Rò rỉ trang | TB component (gz) | Độ phản hồi E2E | Hydrate |
|
|
@@ -135,8 +150,19 @@ Intlayer không có biến thể "scoped": trình biên dịch tự động gi
|
|
|
135
150
|
- **Hàng `static` của Intlayer vốn đã có 0% rò rỉ trang** vì chỉ các từ điển được import bởi các component trên trang mới được đóng gói. Một dòng cấu hình (`importMode: 'dynamic'`) cũng loại bỏ luôn tình trạng rò rỉ ngôn ngữ.
|
|
136
151
|
- **`@intlayer/lingui`** giữ nguyên cú pháp macro của Lingui và phân phối từ các từ điển Intlayer. Nó chấp nhận hy sinh một phần dung lượng trang (137 KB, do runtime của macro vẫn tồn tại) để đổi lấy component nhỏ hơn (12.8 KB) và quá trình hydrate nhanh hơn Lingui gốc. Đây là một bước chuyển đổi dần, không phải đích đến cuối cùng.
|
|
137
152
|
|
|
153
|
+
<ClickToOpenIframe
|
|
154
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.md"
|
|
155
|
+
width="100%"
|
|
156
|
+
height="600px"
|
|
157
|
+
style="border:none;"
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
> Bảng đầy đủ trong [báo cáo benchmark TanStack Start](https://intlayer.org/vi/doc/benchmark/tanstack).
|
|
161
|
+
|
|
138
162
|
## Tại sao lại có khoảng cách? Hai trình biên dịch, hai đơn vị xử lý
|
|
139
163
|
|
|
164
|
+

|
|
165
|
+
|
|
140
166
|
Cả hai thư viện đều thực hiện biên dịch. Sự khác biệt nằm ở chỗ chúng **biên dịch cái gì**.
|
|
141
167
|
|
|
142
168
|
**Lingui biên dịch các danh mục.** Macro trong mã nguồn của bạn được trích xuất vào một tệp `.po` cho mỗi ngôn ngữ, sau đó được biên dịch thành một module JS cho mỗi ngôn ngữ. Đơn vị xử lý là **ngôn ngữ**. Việc chia nhỏ hơn nữa, theo từng route hoặc theo từng component, đồng nghĩa với việc tạo nhiều danh mục, cấu hình `lingui.config.ts` để trích xuất từng danh mục từ các tập tin khác nhau, và tải đúng danh mục trên mỗi route. Phiên bản `I18n` runtime là biến toàn cục; mọi lệnh gọi `useLingui()` đều đăng ký component với nó.
|
|
@@ -176,7 +202,9 @@ Cả hai thư viện đều thực hiện biên dịch. Sự khác biệt nằm
|
|
|
176
202
|
└── about.content.ts
|
|
177
203
|
```
|
|
178
204
|
|
|
179
|
-
Đó là lý do tại sao mẫu `scoped-dynamic` là kết quả build tự động của Intlayer nhưng lại là một dự án cấu hình thủ công đầy gian nan đối với Lingui.
|
|
205
|
+
Đó là lý do tại sao mẫu `scoped-dynamic` là kết quả build tự động của Intlayer nhưng lại là một dự án cấu hình thủ công đầy gian nan đối với Lingui. Khoảng cách nới rộng theo cả hai chiều cùng lúc: số trang và số ngôn ngữ:
|
|
206
|
+
|
|
207
|
+

|
|
180
208
|
|
|
181
209
|
> Để có được các số liệu của hàng `dynamic`, hãy đặt `dictionary.importMode: 'dynamic'` trong `intlayer.config.ts`. Xem thêm [tài liệu tối ưu hóa bundle](https://intlayer.org/vi/doc/concept/bundle-optimization).
|
|
182
210
|
|
|
@@ -184,7 +212,8 @@ Cả hai thư viện đều thực hiện biên dịch. Sự khác biệt nằm
|
|
|
184
212
|
|
|
185
213
|
### Cài đặt
|
|
186
214
|
|
|
187
|
-
|
|
215
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
216
|
+
<Tab label="Lingui" value="lingui">
|
|
188
217
|
|
|
189
218
|
```ts fileName="lingui.config.ts"
|
|
190
219
|
import { defineConfig } from "@lingui/cli";
|
|
@@ -215,7 +244,8 @@ export const loadCatalog = async (locale: string) => {
|
|
|
215
244
|
|
|
216
245
|
Sau đó thêm `@lingui/babel-plugin-lingui-macro` (hoặc `@lingui/swc-plugin`) vào bundler, chạy `lingui extract` sau khi sửa đổi mã nguồn, chạy `lingui compile` trước khi build và bọc cây component trong `<I18nProvider i18n={i18n}>`.
|
|
217
246
|
|
|
218
|
-
|
|
247
|
+
</Tab>
|
|
248
|
+
<Tab label="Intlayer" value="intlayer">
|
|
219
249
|
|
|
220
250
|
```ts fileName="intlayer.config.ts"
|
|
221
251
|
import { type IntlayerConfig, Locales } from "intlayer";
|
|
@@ -232,9 +262,12 @@ export default config;
|
|
|
232
262
|
|
|
233
263
|
Thêm `intlayer()` vào `vite.config.ts` (hoặc `withIntlayer()` vào `next.config.ts`) và bọc cây ứng dụng trong `<IntlayerProvider>`. Không cần bước trích xuất hay biên dịch riêng biệt: từ điển được xây dựng tự động khi bundler chạy.
|
|
234
264
|
|
|
265
|
+
</Tab>
|
|
266
|
+
</Tabs>
|
|
235
267
|
### Component
|
|
236
268
|
|
|
237
|
-
|
|
269
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
270
|
+
<Tab label="Lingui" value="lingui">
|
|
238
271
|
|
|
239
272
|
```tsx fileName="src/components/Counter.tsx"
|
|
240
273
|
import { useState } from "react";
|
|
@@ -258,7 +291,8 @@ export const Counter = () => {
|
|
|
258
291
|
|
|
259
292
|
Văn bản tiếng Anh nằm trực tiếp trong component; văn bản tiếng Pháp nằm trong `src/locales/fr/messages.po` dưới dạng một ID đã được băm, sau khi chạy `lingui extract`. Nếu quên chạy lệnh hoặc quên `compile`, ứng dụng sẽ lặng lẽ quay về tiếng Anh.
|
|
260
293
|
|
|
261
|
-
|
|
294
|
+
</Tab>
|
|
295
|
+
<Tab label="Intlayer" value="intlayer">
|
|
262
296
|
|
|
263
297
|
```ts fileName="src/components/Counter/index.content.ts"
|
|
264
298
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -297,11 +331,14 @@ export const Counter = () => {
|
|
|
297
331
|
|
|
298
332
|
Cả hai ngôn ngữ đều nằm trong cùng một tệp ngay cạnh component. Việc thiếu giá trị `fr` sẽ gây ra lỗi khi build, và sai key sẽ báo lỗi TypeScript ngay lập tức.
|
|
299
333
|
|
|
334
|
+
</Tab>
|
|
335
|
+
</Tabs>
|
|
300
336
|
### Bên ngoài các component
|
|
301
337
|
|
|
302
338
|
Metadata, loaders, các hàm server: bất kỳ nơi nào không có cây React.
|
|
303
339
|
|
|
304
|
-
|
|
340
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
341
|
+
<Tab label="Lingui" value="lingui">
|
|
305
342
|
|
|
306
343
|
```ts fileName="src/routes/$locale/about.tsx"
|
|
307
344
|
import { setupI18n } from "@lingui/core";
|
|
@@ -324,7 +361,8 @@ export const loader = async ({ params }: { params: { locale: string } }) => {
|
|
|
324
361
|
|
|
325
362
|
Cần tạo phiên bản `I18n` mới cho mỗi lần gọi, tự tay tải đúng danh mục và dùng `msg` + `i18n._()` thay vì `t`. Như ghi nhận từ [báo cáo điểm chuẩn](https://github.com/intlayer-org/benchmark-bloom/blob/main/report/NOTE.md), việc xác định khi nào dùng `t`, `` t` ` ``, `i18n.t()`, `msg` hay `<Trans>` không hề dễ đoán.
|
|
326
363
|
|
|
327
|
-
|
|
364
|
+
</Tab>
|
|
365
|
+
<Tab label="Intlayer" value="intlayer">
|
|
328
366
|
|
|
329
367
|
```ts fileName="src/routes/$locale/about.tsx"
|
|
330
368
|
import { getIntlayer } from "intlayer";
|
|
@@ -336,6 +374,9 @@ export const loader = async ({ params }: { params: { locale: string } }) => {
|
|
|
336
374
|
};
|
|
337
375
|
```
|
|
338
376
|
|
|
377
|
+
</Tab>
|
|
378
|
+
</Tabs>
|
|
379
|
+
|
|
339
380
|
## Giữ lại macro Lingui, tận dụng từ điển Intlayer
|
|
340
381
|
|
|
341
382
|
`@intlayer/lingui` là một adapter tương thích trực tiếp dành cho `@lingui/core` và `@lingui/react`. Các macro tiếp tục được biên dịch như trước; các lệnh gọi `i18n._()` trong runtime mà chúng biên dịch thành sẽ được cung cấp từ các từ điển Intlayer, với plugin đồng bộ `.po` giữ cho các danh mục hiện tại của bạn đóng vai trò là nguồn dữ liệu chuẩn. Các mẫu số nhiều và lựa chọn ICU hiển thị hoàn toàn tương tự.
|
|
@@ -353,16 +394,82 @@ Giữ `@lingui/babel-plugin-lingui-macro` / `@lingui/swc-plugin` chạy trước
|
|
|
353
394
|
|
|
354
395
|
## Khi nào nên chọn thư viện nào?
|
|
355
396
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
397
|
+
<AccordionGroup>
|
|
398
|
+
<Accordion header="Chọn Lingui">
|
|
399
|
+
|
|
400
|
+
Bạn muốn **ICU MessageFormat** với các macro có kiểu dữ liệu, dịch giả của bạn làm việc với tệp **`.po`** qua quy trình TMS hiện có, bạn thích viết trực tiếp chuỗi nguồn trong JSX và nhóm của bạn thoải mái quản lý quy trình trích xuất / biên dịch / chia nhỏ danh mục. JS trên mỗi trang của nó rất cạnh tranh khi đã thiết lập lazy loading.
|
|
401
|
+
|
|
402
|
+
</Accordion>
|
|
403
|
+
<Accordion header="Chọn Intlayer">
|
|
404
|
+
|
|
405
|
+
Bạn muốn **nội dung có phạm vi theo component**, **TypeScript chặt chẽ**, **báo lỗi thiếu khóa ngay khi build**, **tree-shaking và lazy loading không tốn công sức**, component nhỏ gọn, hydrate nhanh, chuyển đổi ngôn ngữ tức thì và các công cụ biên tập tích hợp ([Visual Editor](https://intlayer.org/vi/doc/concept/editor), [CMS](https://intlayer.org/vi/doc/concept/cms), [dịch thuật AI](https://intlayer.org/vi/doc/concept/auto-fill), [máy chủ MCP](https://intlayer.org/vi/doc/mcp-server)). Đặc biệt phù hợp cho các codebase mô-đun lớn và hệ thống thiết kế.
|
|
406
|
+
|
|
407
|
+
</Accordion>
|
|
408
|
+
<Accordion header="Chọn @intlayer/lingui">
|
|
409
|
+
|
|
410
|
+
Bạn đang dùng Lingui và muốn chuyển dần sang từ điển của Intlayer mà không cần chỉnh sửa macro. Các danh mục `.po` của bạn vẫn là nguồn chân lý duy nhất thông qua [plugin đồng bộ hóa PO](https://intlayer.org/vi/doc/compatibility/lingui). Được đo lường cạnh nhau trong [Lingui vs @intlayer/lingui](https://intlayer.org/vi/blog/lingui-vs-intlayer-lingui).
|
|
411
|
+
|
|
412
|
+
</Accordion>
|
|
413
|
+
</AccordionGroup>
|
|
414
|
+
|
|
415
|
+
## FAQ
|
|
416
|
+
|
|
417
|
+
<FAQ>
|
|
418
|
+
|
|
419
|
+
<Question title="Lingui cũng biên dịch. Tại sao đầu ra lại khác biệt đến vậy?">
|
|
420
|
+
|
|
421
|
+
Bởi vì đơn vị biên dịch khác nhau. Lingui biên dịch **một danh mục cho mỗi ngôn ngữ**: mọi thứ dưới cấp độ đó (danh mục theo route, lazy loading, loại bỏ fallback khỏi bundle) đều cần cấu hình thủ công. Intlayer biên dịch **một từ điển cho mỗi component**, do đó phạm vi theo route là kết quả tự nhiên của quá trình build. Đó là lý do component Lingui khi biên dịch độc lập nặng 58-153 KB so với 6-8 KB của Intlayer.
|
|
422
|
+
|
|
423
|
+
</Question>
|
|
424
|
+
|
|
425
|
+
<Question title="Tại sao rò rỉ ngôn ngữ không bao giờ đạt 0% với Lingui?">
|
|
426
|
+
|
|
427
|
+
Macro giữ lại thông điệp nguồn như một giải pháp dự phòng (fallback) lúc runtime, vì vậy chuỗi tiếng Anh được gửi kèm cùng với bản dịch. Benchmark ghi nhận **3-15% chuỗi `en` nằm trong các trang `fr`** ở mọi cấu hình tối ưu. Intlayer giải quyết fallback ngay khi build và chỉ phân phối ngôn ngữ đang hoạt động.
|
|
428
|
+
|
|
429
|
+
</Question>
|
|
430
|
+
|
|
431
|
+
<Question title="JavaScript mỗi trang của Lingui có thực sự cạnh tranh?">
|
|
432
|
+
|
|
433
|
+
Có, và trên TanStack Start nó thắng sít sao: 115.2 KB ở chế độ `dynamic` so với 118.6 KB của Intlayer. Các danh mục được biên dịch với mã ID băm rất nhỏ gọn. Nhưng chi phí phát sinh ở điểm khác: hydrate mất 28-34 ms so với 11-14 ms, và chuyển đổi ngôn ngữ mất **42 ms** trong thiết lập `scoped-dynamic`.
|
|
434
|
+
|
|
435
|
+
</Question>
|
|
436
|
+
|
|
437
|
+
<Question title="Tôi có phải từ bỏ macro để chuyển đổi không?">
|
|
438
|
+
|
|
439
|
+
Không. `@intlayer/lingui` giữ nguyên cách biên dịch `` t`...` ``, `<Trans>`, `msg`, `plural`, `select` và `selectOrdinal`; chỉ có nguồn giải quyết của `i18n._()` thay đổi. Tiếp tục giữ `@lingui/babel-plugin-lingui-macro` hoặc `@lingui/swc-plugin` trong bản build. Xem [tài liệu tương thích Lingui](https://intlayer.org/vi/doc/compatibility/lingui).
|
|
440
|
+
|
|
441
|
+
</Question>
|
|
442
|
+
|
|
443
|
+
<Question title="Còn các bước trích xuất và biên dịch thì sao?">
|
|
444
|
+
|
|
445
|
+
Chúng được giữ lại cho macro và biến mất đối với nội dung riêng của Intlayer. Các từ điển `.content.ts` được tạo tự động khi bundler chạy mà không cần lệnh CLI riêng, và [`intlayer test`](https://intlayer.org/vi/doc/concept/cli) sẽ làm dừng CI nếu thiếu khóa thay vì lặng lẽ quay lại chuỗi nguồn.
|
|
446
|
+
|
|
447
|
+
</Question>
|
|
448
|
+
|
|
449
|
+
</FAQ>
|
|
359
450
|
|
|
360
451
|
## So sánh liên quan
|
|
361
452
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
- [
|
|
365
|
-
- [
|
|
453
|
+
Cùng benchmark, các thư viện khác:
|
|
454
|
+
|
|
455
|
+
- [next-intl vs Intlayer](https://intlayer.org/vi/blog/next-intl-vs-intlayer)
|
|
456
|
+
- [i18next vs Intlayer](https://intlayer.org/vi/blog/i18next-vs-intlayer)
|
|
457
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/vi/blog/vue-i18n-vs-intlayer-benchmark)
|
|
458
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/vi/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
459
|
+
- [react-i18next vs react-intl vs Intlayer](https://intlayer.org/vi/blog/react-i18next-vs-react-intl-vs-intlayer)
|
|
460
|
+
|
|
461
|
+
Tìm hiểu thêm:
|
|
462
|
+
|
|
463
|
+
- [Lingui vs @intlayer/lingui](https://intlayer.org/vi/blog/lingui-vs-intlayer-lingui), adapter được đo lường trên cùng một ứng dụng
|
|
464
|
+
- [Compiler-driven vs declarative i18n](https://intlayer.org/vi/blog/compiler-vs-declarative-i18n)
|
|
465
|
+
- [Per-component vs centralized i18n](https://intlayer.org/vi/blog/per-component-vs-centralized-i18n)
|
|
466
|
+
- [ICU message format explained](https://intlayer.org/vi/blog/icu-message-format)
|
|
467
|
+
|
|
468
|
+
Tài liệu tham khảo:
|
|
469
|
+
|
|
470
|
+
- [Báo cáo benchmark Next.js](https://intlayer.org/vi/doc/benchmark/nextjs) và [báo cáo benchmark TanStack Start](https://intlayer.org/vi/doc/benchmark/tanstack)
|
|
471
|
+
- [Compat adapter: Lingui](https://intlayer.org/vi/doc/compatibility/lingui)
|
|
472
|
+
- [Tối ưu hóa bundle](https://intlayer.org/vi/doc/concept/bundle-optimization) và [trình biên dịch Intlayer](https://intlayer.org/vi/doc/compiler)
|
|
366
473
|
|
|
367
474
|
## Ngôi sao GitHub
|
|
368
475
|
|