@intlayer/docs 9.5.6 → 9.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ar/i18next_vs_intlayer.md +130 -16
- package/blog/ar/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +288 -0
- 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/is_intlayer_lighter_than_paraglide.md +285 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/is_intlayer_lighter_than_paraglide.md +284 -0
- 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/blog.entry.cjs +20 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +60 -40
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +20 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +60 -40
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +3 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +19 -16
- package/docs/ar/benchmark/solid.md +26 -9
- package/docs/ar/benchmark/svelte.md +22 -7
- package/docs/ar/benchmark/tanstack.md +20 -16
- package/docs/ar/benchmark/vue.md +19 -10
- package/docs/ar/chrome_extension.md +130 -0
- package/docs/ar/cli/index.md +11 -1
- package/docs/ar/cli/infra.md +162 -0
- package/docs/ar/cli/init.md +24 -1
- package/docs/ar/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/de/benchmark/solid.md +26 -9
- package/docs/de/benchmark/svelte.md +22 -7
- package/docs/de/benchmark/tanstack.md +20 -16
- package/docs/de/benchmark/vue.md +19 -10
- package/docs/de/chrome_extension.md +130 -0
- package/docs/de/cli/index.md +11 -1
- package/docs/de/cli/infra.md +162 -0
- package/docs/de/cli/init.md +24 -1
- package/docs/de/cli/upgrade.md +125 -0
- 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/agent_skills.md +29 -1
- package/docs/en/benchmark/nextjs.md +19 -16
- package/docs/en/benchmark/solid.md +26 -9
- package/docs/en/benchmark/svelte.md +22 -7
- package/docs/en/benchmark/tanstack.md +21 -17
- package/docs/en/benchmark/vue.md +20 -11
- package/docs/en/chrome_extension.md +130 -0
- package/docs/en/cli/index.md +11 -1
- package/docs/en/cli/infra.md +175 -0
- package/docs/en/cli/init.md +25 -1
- package/docs/en/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/en-GB/benchmark/solid.md +26 -9
- package/docs/en-GB/benchmark/svelte.md +22 -7
- package/docs/en-GB/benchmark/tanstack.md +20 -16
- package/docs/en-GB/benchmark/vue.md +20 -11
- package/docs/en-GB/chrome_extension.md +130 -0
- package/docs/en-GB/cli/index.md +11 -1
- package/docs/en-GB/cli/infra.md +162 -0
- package/docs/en-GB/cli/init.md +24 -1
- package/docs/en-GB/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/es/benchmark/solid.md +26 -9
- package/docs/es/benchmark/svelte.md +22 -7
- package/docs/es/benchmark/tanstack.md +20 -16
- package/docs/es/benchmark/vue.md +19 -10
- package/docs/es/chrome_extension.md +130 -0
- package/docs/es/cli/index.md +11 -1
- package/docs/es/cli/infra.md +162 -0
- package/docs/es/cli/init.md +24 -1
- package/docs/es/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/fr/benchmark/solid.md +26 -9
- package/docs/fr/benchmark/svelte.md +22 -7
- package/docs/fr/benchmark/tanstack.md +20 -16
- package/docs/fr/benchmark/vue.md +20 -11
- package/docs/fr/chrome_extension.md +130 -0
- package/docs/fr/cli/index.md +11 -1
- package/docs/fr/cli/infra.md +162 -0
- package/docs/fr/cli/init.md +24 -1
- package/docs/fr/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/hi/benchmark/solid.md +26 -9
- package/docs/hi/benchmark/svelte.md +22 -7
- package/docs/hi/benchmark/tanstack.md +20 -16
- package/docs/hi/benchmark/vue.md +20 -11
- package/docs/hi/chrome_extension.md +130 -0
- package/docs/hi/cli/index.md +11 -1
- package/docs/hi/cli/infra.md +162 -0
- package/docs/hi/cli/init.md +24 -1
- package/docs/hi/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/id/benchmark/solid.md +26 -9
- package/docs/id/benchmark/svelte.md +22 -7
- package/docs/id/benchmark/tanstack.md +20 -16
- package/docs/id/benchmark/vue.md +20 -11
- package/docs/id/chrome_extension.md +130 -0
- package/docs/id/cli/index.md +11 -1
- package/docs/id/cli/infra.md +162 -0
- package/docs/id/cli/init.md +24 -1
- package/docs/id/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/it/benchmark/solid.md +26 -9
- package/docs/it/benchmark/svelte.md +22 -7
- package/docs/it/benchmark/tanstack.md +20 -16
- package/docs/it/benchmark/vue.md +19 -10
- package/docs/it/chrome_extension.md +130 -0
- package/docs/it/cli/index.md +11 -1
- package/docs/it/cli/infra.md +162 -0
- package/docs/it/cli/init.md +24 -1
- package/docs/it/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/ja/benchmark/solid.md +26 -9
- package/docs/ja/benchmark/svelte.md +22 -7
- package/docs/ja/benchmark/tanstack.md +18 -14
- package/docs/ja/benchmark/vue.md +19 -10
- package/docs/ja/chrome_extension.md +130 -0
- package/docs/ja/cli/index.md +11 -1
- package/docs/ja/cli/infra.md +162 -0
- package/docs/ja/cli/init.md +24 -1
- package/docs/ja/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/ko/benchmark/solid.md +26 -9
- package/docs/ko/benchmark/svelte.md +22 -7
- package/docs/ko/benchmark/tanstack.md +20 -16
- package/docs/ko/benchmark/vue.md +20 -11
- package/docs/ko/chrome_extension.md +130 -0
- package/docs/ko/cli/index.md +11 -1
- package/docs/ko/cli/infra.md +162 -0
- package/docs/ko/cli/init.md +24 -1
- package/docs/ko/cli/upgrade.md +126 -0
- 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 +19 -16
- package/docs/pl/benchmark/solid.md +26 -9
- package/docs/pl/benchmark/svelte.md +22 -7
- package/docs/pl/benchmark/tanstack.md +20 -16
- package/docs/pl/benchmark/vue.md +20 -11
- package/docs/pl/chrome_extension.md +130 -0
- package/docs/pl/cli/index.md +11 -1
- package/docs/pl/cli/infra.md +162 -0
- package/docs/pl/cli/init.md +24 -1
- package/docs/pl/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/pt/benchmark/solid.md +26 -9
- package/docs/pt/benchmark/svelte.md +22 -7
- package/docs/pt/benchmark/tanstack.md +20 -16
- package/docs/pt/benchmark/vue.md +19 -10
- package/docs/pt/chrome_extension.md +130 -0
- package/docs/pt/cli/index.md +11 -1
- package/docs/pt/cli/infra.md +162 -0
- package/docs/pt/cli/init.md +24 -1
- package/docs/pt/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/ru/benchmark/solid.md +26 -9
- package/docs/ru/benchmark/svelte.md +22 -7
- package/docs/ru/benchmark/tanstack.md +20 -16
- package/docs/ru/benchmark/vue.md +20 -11
- package/docs/ru/chrome_extension.md +130 -0
- package/docs/ru/cli/index.md +11 -1
- package/docs/ru/cli/infra.md +162 -0
- package/docs/ru/cli/init.md +24 -1
- package/docs/ru/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/tr/benchmark/solid.md +26 -9
- package/docs/tr/benchmark/svelte.md +22 -7
- package/docs/tr/benchmark/tanstack.md +20 -16
- package/docs/tr/benchmark/vue.md +20 -11
- package/docs/tr/chrome_extension.md +130 -0
- package/docs/tr/cli/index.md +11 -1
- package/docs/tr/cli/infra.md +162 -0
- package/docs/tr/cli/init.md +24 -1
- package/docs/tr/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/uk/benchmark/solid.md +26 -9
- package/docs/uk/benchmark/svelte.md +22 -7
- package/docs/uk/benchmark/tanstack.md +20 -16
- package/docs/uk/benchmark/vue.md +20 -11
- package/docs/uk/chrome_extension.md +130 -0
- package/docs/uk/cli/index.md +11 -1
- package/docs/uk/cli/infra.md +162 -0
- package/docs/uk/cli/init.md +24 -1
- package/docs/uk/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/vi/benchmark/solid.md +26 -9
- package/docs/vi/benchmark/svelte.md +22 -7
- package/docs/vi/benchmark/tanstack.md +20 -16
- package/docs/vi/benchmark/vue.md +20 -11
- package/docs/vi/chrome_extension.md +130 -0
- package/docs/vi/cli/index.md +11 -1
- package/docs/vi/cli/infra.md +162 -0
- package/docs/vi/cli/init.md +24 -1
- package/docs/vi/cli/upgrade.md +125 -0
- 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 +19 -16
- package/docs/zh/benchmark/solid.md +26 -9
- package/docs/zh/benchmark/svelte.md +22 -7
- package/docs/zh/benchmark/tanstack.md +19 -15
- package/docs/zh/benchmark/vue.md +20 -11
- package/docs/zh/chrome_extension.md +130 -0
- package/docs/zh/cli/index.md +11 -1
- package/docs/zh/cli/infra.md +162 -0
- package/docs/zh/cli/init.md +24 -1
- package/docs/zh/cli/upgrade.md +125 -0
- 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 +6 -6
- package/src/generated/blog.entry.ts +20 -0
- package/src/generated/docs.entry.ts +60 -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: 2026 Benchmark & Comparison"
|
|
5
5
|
description: "react-i18next and next-i18next measured against Intlayer on Next.js and TanStack Start. Bundle size, content leakage, locale-switch reactivity and developer experience."
|
|
6
6
|
keywords:
|
|
@@ -25,6 +25,8 @@ author: aymericzip
|
|
|
25
25
|
|
|
26
26
|
# i18next VS Intlayer | React & Next.js Internationalisation (i18n) Benchmark
|
|
27
27
|
|
|
28
|
+

|
|
29
|
+
|
|
28
30
|
`i18next` is the most widely used i18n framework in the JavaScript ecosystem. Through `react-i18next` and `next-i18next`, it powers a large share of React and Next.js applications. Intlayer is a compiler-based, component-scoped alternative.
|
|
29
31
|
|
|
30
32
|
This article compares them on measurements rather than feature lists. The numbers come from [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom), an open-source suite that builds the same application with each library and records what the browser actually downloads.
|
|
@@ -99,6 +101,10 @@ For each build, the suite records:
|
|
|
99
101
|
|
|
100
102
|
### Results on Next.js (`next-i18next`)
|
|
101
103
|
|
|
104
|
+
Pick the metrics and the libraries you care about:
|
|
105
|
+
|
|
106
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
107
|
+
|
|
102
108
|
| Library | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|
|
103
109
|
| --------------------------------- | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | --------: |
|
|
104
110
|
| **base** (no i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -119,6 +125,15 @@ For each build, the suite records:
|
|
|
119
125
|
- **Component size.** A component calling `useTranslation()` compiles to 26-79 KB depending on the setup; the same component with `useIntlayer()` compiles to 6.9 KB.
|
|
120
126
|
- **Hydration** spikes to 27.7 ms in the `dynamic` setup: the i18next instance initialises and resolves its backend on the client before React can 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
|
+
> Full table, every library and every strategy, in the [Next.js benchmark report](https://intlayer.org/en-GB/doc/benchmark/nextjs).
|
|
136
|
+
|
|
122
137
|
### Results on TanStack Start (`react-i18next`)
|
|
123
138
|
|
|
124
139
|
Same test app on TanStack Start with plain `react-i18next`, which removes the Next.js-specific wiring from the comparison.
|
|
@@ -141,8 +156,19 @@ Same test app on TanStack Start with plain `react-i18next`, which removes the Ne
|
|
|
141
156
|
- Intlayer's `static` row already has **0% page leakage** because only the dictionaries imported by the page's components are bundled. Enabling `importMode: 'dynamic'` removes the locale leakage too.
|
|
142
157
|
- **Component size**: 24-27 KB per component with `react-i18next` versus 6-8 KB with Intlayer. `useTranslation()` binds every component to the global i18next instance.
|
|
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
|
+
> Full table in the [TanStack Start benchmark report](https://intlayer.org/en-GB/doc/benchmark/tanstack).
|
|
167
|
+
|
|
144
168
|
## Why the gap? Global instance vs. compiled dictionaries
|
|
145
169
|
|
|
170
|
+

|
|
171
|
+
|
|
146
172
|
`i18next` was designed in 2012 as a runtime: a global instance holds a resource store, plugins extend it, and `t()` looks keys up at render time. This is what makes it so flexible (any framework, any backend, any format) and also what makes it costly:
|
|
147
173
|
|
|
148
174
|
```bash
|
|
@@ -166,7 +192,13 @@ Same test app on TanStack Start with plain `react-i18next`, which removes the Ne
|
|
|
166
192
|
└── page.tsx # must know it needs ["common", "about"]
|
|
167
193
|
```
|
|
168
194
|
|
|
169
|
-
The instance cannot know which keys a component will request, so it keeps whatever namespaces you tell it to load. Optimising means **you** split catalogues into namespaces, **you** list the namespaces each page needs, and **you** keep that list correct as components move between pages.
|
|
195
|
+
The instance cannot know which keys a component will request, so it keeps whatever namespaces you tell it to load. Optimising means **you** split catalogues into namespaces, **you** list the namespaces each page needs, and **you** keep that list correct as components move between pages.
|
|
196
|
+
|
|
197
|
+
The bill grows on two axes at once, pages and locales:
|
|
198
|
+
|
|
199
|
+

|
|
200
|
+
|
|
201
|
+
As the [benchmark notes](https://github.com/intlayer-org/benchmark-bloom/blob/main/report/NOTE.md) put it: "maintaining type safety and knowing exactly which namespace should be included on which page is a nightmare".
|
|
170
202
|
|
|
171
203
|
Intlayer removes the instance. Content is declared next to the component, and the compiler resolves the dependency graph at build time:
|
|
172
204
|
|
|
@@ -193,7 +225,8 @@ Intlayer removes the instance. Content is declared next to the component, and th
|
|
|
193
225
|
|
|
194
226
|
### Setup
|
|
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
|
Plus a client-side `I18nProvider` that re-creates the instance with the same options, a `generateStaticParams`, and a `namespaces` list on every page.
|
|
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
|
### Client component
|
|
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
|
> The page rendering this component must load the `about` namespace, and `t("counter.label")` is a plain string until you augment `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` and `increment` are typed; a typo is a TypeScript error, a missing French value is a build error.
|
|
347
386
|
|
|
387
|
+
</Tab>
|
|
388
|
+
</Tabs>
|
|
389
|
+
|
|
348
390
|
### Synchronous server component
|
|
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
|
The page calls `i18n.getFixedT(locale, "about")` and threads `t` and `locale` down as 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
|
## Keep the i18next API, get Intlayer's output
|
|
389
436
|
|
|
390
437
|
You don't have to rewrite components to get the benchmark numbers above. `@intlayer/i18next`, `@intlayer/react-i18next` and `@intlayer/next-i18next` are drop-in adapters: `useTranslation`, `t()`, `<Trans>`, `{{interpolation}}`, `_one` / `_other` plurals, context suffixes and `returnObjects` keep working, served from Intlayer dictionaries compiled by the Intlayer compiler.
|
|
@@ -415,18 +462,85 @@ See the migration guides: [i18next](https://intlayer.org/en-GB/doc/migration/i18
|
|
|
415
462
|
|
|
416
463
|
## When to choose which?
|
|
417
464
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
465
|
+
<AccordionGroup>
|
|
466
|
+
<Accordion header="Choose i18next">
|
|
467
|
+
|
|
468
|
+
If you need its plugin ecosystem (detectors, backends, ICU, Locize), you localise outside React too (Node services, vanilla JS, other frameworks), your team already knows it, or a translation platform expects `locales/{lng}/{ns}.json`. Budget the time to namespace catalogues, wire a backend and maintain the page-to-namespace map if performance matters.
|
|
469
|
+
|
|
470
|
+
</Accordion>
|
|
471
|
+
<Accordion header="Choose Intlayer">
|
|
472
|
+
|
|
473
|
+
You want **component-scoped content**, **strict TypeScript**, **build-time missing-key errors**, **zero-effort tree-shaking and lazy loading**, instant locale switching, synchronous server components, and built-in editorial tooling ([Visual Editor](https://intlayer.org/en-GB/doc/concept/editor), [CMS](https://intlayer.org/en-GB/doc/concept/cms), [AI translation](https://intlayer.org/en-GB/doc/concept/auto-fill), [MCP server](https://intlayer.org/en-GB/doc/mcp-server)). Especially relevant for large, modular codebases and design systems.
|
|
474
|
+
|
|
475
|
+
</Accordion>
|
|
476
|
+
<Accordion header="Choose the @intlayer/*-i18next adapters">
|
|
477
|
+
|
|
478
|
+
You are already on i18next and want the bundle and reactivity gains without a rewrite. Your `locales/{lng}/{ns}.json` files stay the source of truth. Measured side by side in [i18next vs @intlayer/i18next](https://intlayer.org/en-GB/blog/i18next-vs-intlayer-i18next).
|
|
479
|
+
|
|
480
|
+
</Accordion>
|
|
481
|
+
</AccordionGroup>
|
|
482
|
+
|
|
483
|
+
## FAQ
|
|
484
|
+
|
|
485
|
+
<FAQ>
|
|
486
|
+
|
|
487
|
+
<Question title="Why is i18next so much heavier than the other libraries?">
|
|
488
|
+
|
|
489
|
+
It was designed as a framework-agnostic runtime: a global instance, a plugin pipeline, a resource store, a key resolver. That flexibility is compiled into every bundle. An empty component that only imports the library costs **19.7 KB gzip** with `next-i18next` against **5.5 KB** with `next-intlayer`, and the cost is paid on every page whatever your content weighs.
|
|
490
|
+
|
|
491
|
+
</Question>
|
|
492
|
+
|
|
493
|
+
<Question title="Does lazy loading with a backend fix it?">
|
|
494
|
+
|
|
495
|
+
It fixes the bytes, not the latency. Moving to `i18next-resources-to-backend` saves ~49 KB per page but puts a network round-trip on the locale switch: **123 ms** in the `dynamic` setup and **185 ms** in `scoped-static`, against **3-4 ms** with Intlayer. Hydration also jumps to 27.7 ms because the instance resolves its backend before React can hydrate.
|
|
496
|
+
|
|
497
|
+
</Question>
|
|
498
|
+
|
|
499
|
+
<Question title="Can I reach 0% leakage with i18next?">
|
|
500
|
+
|
|
501
|
+
Yes, with `scoped-dynamic`: one namespace per route, a resources backend and a page-to-namespace map you maintain by hand. It lands at 163.4 KB per page on Next.js, still **+22 KB** over Intlayer's 141.3 KB, which needed no configuration. See [bundle optimization](https://intlayer.org/en-GB/doc/concept/bundle-optimization).
|
|
502
|
+
|
|
503
|
+
</Question>
|
|
504
|
+
|
|
505
|
+
<Question title="Do I have to rewrite my components to migrate?">
|
|
506
|
+
|
|
507
|
+
No. `@intlayer/i18next`, `@intlayer/react-i18next` and `@intlayer/next-i18next` keep `useTranslation`, `t()`, `<Trans>`, `{{interpolation}}`, `_one` / `_other` plurals, context suffixes and `returnObjects`. One plugin line in `next.config.ts` or `vite.config.ts`. Step by step in the [next-i18next migration guide](https://intlayer.org/en-GB/doc/migration/next-i18next).
|
|
508
|
+
|
|
509
|
+
</Question>
|
|
510
|
+
|
|
511
|
+
<Question title="What happens to my i18next plugins?">
|
|
512
|
+
|
|
513
|
+
Backends and language detectors are accepted but inert: there is nothing left to load or detect at runtime. Locale detection becomes Intlayer's routing config (URL prefix, cookie, header). If your app fetches translations from a CMS at request time, use the [Intlayer CMS](https://intlayer.org/en-GB/doc/concept/cms) or `intlayer pull` / `push` instead.
|
|
514
|
+
|
|
515
|
+
</Question>
|
|
516
|
+
|
|
517
|
+
</FAQ>
|
|
421
518
|
|
|
422
519
|
## Related comparisons
|
|
423
520
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
- [
|
|
521
|
+
Same benchmark, other libraries:
|
|
522
|
+
|
|
523
|
+
- [next-intl vs Intlayer](https://intlayer.org/en-GB/blog/next-intl-vs-intlayer)
|
|
524
|
+
- [Lingui vs Intlayer](https://intlayer.org/en-GB/blog/lingui-vs-intlayer)
|
|
525
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/en-GB/blog/vue-i18n-vs-intlayer-benchmark)
|
|
427
526
|
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/en-GB/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
428
527
|
- [react-i18next vs react-intl vs Intlayer](https://intlayer.org/en-GB/blog/react-i18next-vs-react-intl-vs-intlayer)
|
|
528
|
+
|
|
529
|
+
Going further on i18next:
|
|
530
|
+
|
|
531
|
+
- [i18next vs @intlayer/i18next](https://intlayer.org/en-GB/blog/i18next-vs-intlayer-i18next), the adapters measured on the same app
|
|
429
532
|
- [Is i18next outdated?](https://intlayer.org/en-GB/blog/is-i18next-outdated)
|
|
533
|
+
- [Using Intlayer with i18next](https://intlayer.org/en-GB/blog/intlayer-with-i18next) and [with react-i18next](https://intlayer.org/en-GB/blog/intlayer-with-react-i18next)
|
|
534
|
+
- [How to internationalize a Next.js app with next-i18next](https://intlayer.org/en-GB/blog/nextjs-internationalization-using-next-i18next)
|
|
535
|
+
|
|
536
|
+
Reference docs:
|
|
537
|
+
|
|
538
|
+
- [Next.js benchmark report](https://intlayer.org/en-GB/doc/benchmark/nextjs) and [TanStack Start benchmark report](https://intlayer.org/en-GB/doc/benchmark/tanstack)
|
|
539
|
+
- Compat adapters: [i18next](https://intlayer.org/en-GB/doc/compatibility/i18next), [react-i18next](https://intlayer.org/en-GB/doc/compatibility/react-i18next), [next-i18next](https://intlayer.org/en-GB/doc/compatibility/next-i18next)
|
|
540
|
+
- Migration guides: [i18next](https://intlayer.org/en-GB/doc/migration/i18next), [react-i18next](https://intlayer.org/en-GB/doc/migration/react-i18next), [next-i18next](https://intlayer.org/en-GB/doc/migration/next-i18next)
|
|
541
|
+
- [Bundle optimization](https://intlayer.org/en-GB/doc/concept/bundle-optimization) and [the Intlayer compiler](https://intlayer.org/en-GB/doc/compiler)
|
|
542
|
+
- [Per-component vs centralized i18n](https://intlayer.org/en-GB/blog/per-component-vs-centralized-i18n)
|
|
543
|
+
- [Compiler-driven vs declarative i18n](https://intlayer.org/en-GB/blog/compiler-vs-declarative-i18n)
|
|
430
544
|
|
|
431
545
|
## GitHub STARs
|
|
432
546
|
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-23
|
|
3
|
+
updatedAt: 2026-09-23
|
|
4
|
+
title: Is Intlayer Lighter than Paraglide?
|
|
5
|
+
description: Paraglide looks almost free in i18n benchmarks because its code is generated into your repo. Here is where that weight actually goes, why per-node locale reads cost you, and how Intlayer's dynamic loading ships one locale instead of all of them.
|
|
6
|
+
keywords:
|
|
7
|
+
- Paraglide
|
|
8
|
+
- Intlayer
|
|
9
|
+
- Internationalisation
|
|
10
|
+
- i18n
|
|
11
|
+
- Bundle size
|
|
12
|
+
- Tree shaking
|
|
13
|
+
- Benchmark
|
|
14
|
+
- Blog
|
|
15
|
+
slugs:
|
|
16
|
+
- blog
|
|
17
|
+
- is-intlayer-lighter-than-paraglide
|
|
18
|
+
author: aymericzip
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Is Intlayer Lighter than Paraglide?
|
|
22
|
+
|
|
23
|
+
Yes.
|
|
24
|
+
|
|
25
|
+
`Paraglide` has a good reputation for being the lightest i18n solution around, and at first sight the [benchmark](https://intlayer.org/en-GB/doc/benchmark/tanstack) agrees: its library size is close to zero. But a library size of zero does not mean zero bytes shipped. It means the bytes live somewhere the metric does not look.
|
|
26
|
+
|
|
27
|
+
<TOC/>
|
|
28
|
+
|
|
29
|
+
## Key Takeaways
|
|
30
|
+
|
|
31
|
+
**The library size is hidden, not gone:**
|
|
32
|
+
|
|
33
|
+
Paraglide generates its runtime and message functions into your codebase. That code ships to the browser, but it is counted as _your_ code, not as the library's.
|
|
34
|
+
|
|
35
|
+
**No provider is not a free win:**
|
|
36
|
+
|
|
37
|
+
Every `m.my_key()` call resolves the locale on its own, reading the cookie or storage for each rendered node, instead of reading it once from a context.
|
|
38
|
+
|
|
39
|
+
**No dynamic loading:**
|
|
40
|
+
|
|
41
|
+
Paraglide imports every locale of a message into your client bundle. Intlayer with `importMode: 'dynamic'` or `'fetch'` loads only the locale being rendered.
|
|
42
|
+
|
|
43
|
+
**Tree shaking is not guaranteed:**
|
|
44
|
+
|
|
45
|
+
In some of our benchmarks, Paraglide's advertised tree shaking did not take effect. Check your own bundle.
|
|
46
|
+
|
|
47
|
+
## Where Does Paraglide's Weight Go?
|
|
48
|
+
|
|
49
|
+
In the benchmark reports, the "library size" metric measures the provider and hooks of each i18n library in an empty component, before any content is added.
|
|
50
|
+
|
|
51
|
+
| Library (TanStack Start) | Lib size (gz) | Lib size (min) |
|
|
52
|
+
| ----------------------------- | ------------- | -------------- |
|
|
53
|
+
| `@inlang/paraglide-js@2.15.1` | 1.8 KB | 4.5 KB |
|
|
54
|
+
| `react-intlayer@9.5.1` | 5.0 KB | 15.2 KB |
|
|
55
|
+
|
|
56
|
+
Read in isolation, Paraglide wins. But Paraglide is a compiler: it reads your `messages/*.json` files and writes a `paraglide/` folder into your repository, containing a `runtime.js` (locale detection, cookie and storage strategies, URL localisation) and one JavaScript function per message.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
src/paraglide/
|
|
60
|
+
├── runtime.js # locale detection, strategies, URL helpers
|
|
61
|
+
├── server.js
|
|
62
|
+
├── messages.js # re-exports every message
|
|
63
|
+
└── messages/
|
|
64
|
+
├── _index.js
|
|
65
|
+
├── en.js
|
|
66
|
+
└── fr.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Because this code sits in your `src/` folder and you import it with a relative path, the bundler attributes it to your application, not to a `node_modules` package. The library size column shows almost nothing, while the same logic still ships in your page bundle.
|
|
70
|
+
|
|
71
|
+
Generating code is not a bad idea in itself: the generated runtime only includes the logic your configuration needs (prefix strategy, cookie vs. local storage, etc.). Intlayer reaches the same result differently, by injecting environment variables at build time so the bundler drops the branches your configuration does not use. Both approaches end up 3 to 10 times lighter than `i18next` or `next-intl`.
|
|
72
|
+
|
|
73
|
+
So the fair comparison is not the library size. It is **the JavaScript actually sent per page**.
|
|
74
|
+
|
|
75
|
+
## Page Weight, Measured
|
|
76
|
+
|
|
77
|
+
TanStack Start app, 10 pages, measured on the `en` and `fr` routes, gzipped:
|
|
78
|
+
|
|
79
|
+
| Setup | Page JS avg (gz) | Above base | Locale leak | Other-page leak |
|
|
80
|
+
| ---------------------------------- | ---------------- | ----------- | ----------- | --------------- |
|
|
81
|
+
| Base (no i18n) | 111.0 KB | - | 0.0% | 0.0% |
|
|
82
|
+
| `paraglide` (any strategy) | 125.1 KB | +14.1 KB | 49.7% | 0.0% |
|
|
83
|
+
| `intlayer` (`importMode: static`) | 125.8 KB | +14.8 KB | 50.0% | 0.0% |
|
|
84
|
+
| `intlayer` (`importMode: dynamic`) | **118.6 KB** | **+7.6 KB** | **0.0%** | **0.0%** |
|
|
85
|
+
|
|
86
|
+
Next.js 16 App Router, same app:
|
|
87
|
+
|
|
88
|
+
| Setup | Page JS avg (gz) | Above base |
|
|
89
|
+
| ---------------- | ---------------- | ----------- |
|
|
90
|
+
| Base (no i18n) | 141.0 KB | - |
|
|
91
|
+
| `paraglide-next` | 155.3 KB | +14.3 KB |
|
|
92
|
+
| `next-intlayer` | **141.3 KB** | **+0.3 KB** |
|
|
93
|
+
|
|
94
|
+
<I18nBenchmark framework="tanstack" vertical/>
|
|
95
|
+
|
|
96
|
+
> Full data in the [TanStack Start benchmark report](https://intlayer.org/en-GB/doc/benchmark/tanstack) and the [Next.js benchmark report](https://intlayer.org/en-GB/doc/benchmark/nextjs). Every bundle can be inspected in the [benchmark repository](https://github.com/intlayer-org/benchmark-i18n).
|
|
97
|
+
|
|
98
|
+
Two things stand out:
|
|
99
|
+
|
|
100
|
+
- In `static` mode, Intlayer ships practically the same content as Paraglide (125.8 KB vs. 125.1 KB). That is expected: both include every locale of the messages a page uses.
|
|
101
|
+
- Paraglide stays at 125.1 KB whatever the strategy, because it has no dynamic mode. Every line in the table above is the static one.
|
|
102
|
+
|
|
103
|
+
## No Provider: A Good Idea That Isn't
|
|
104
|
+
|
|
105
|
+
Paraglide has no provider. You import a message and call it:
|
|
106
|
+
|
|
107
|
+
```tsx fileName="Hero.tsx"
|
|
108
|
+
import { m } from "../paraglide/messages.js";
|
|
109
|
+
|
|
110
|
+
export const Hero = () => (
|
|
111
|
+
<section>
|
|
112
|
+
<h1>{m.hero_title()}</h1>
|
|
113
|
+
<p>{m.hero_description()}</p>
|
|
114
|
+
<button>{m.hero_cta()}</button>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
No context, no wrapper, no hook. It looks simpler. But the locale still has to come from somewhere. Each generated message function looks roughly like this (simplified):
|
|
120
|
+
|
|
121
|
+
```js fileName="paraglide/messages/_index.js"
|
|
122
|
+
export const hero_title = (inputs = {}, options = {}) => {
|
|
123
|
+
const locale = options.locale ?? getLocale(); // resolved on every call
|
|
124
|
+
|
|
125
|
+
if (locale === "en") return en.hero_title(inputs);
|
|
126
|
+
if (locale === "fr") return fr.hero_title(inputs);
|
|
127
|
+
// ...one branch per locale
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
And `getLocale()` walks the configured strategies (cookie, local storage, URL, base locale) to find the current locale. So every text node you render (`<>{m.my_key()}</>`) runs its own locale resolution, including reading `document.cookie` in the browser. A page with 200 translated strings resolves the locale 200 times per render, and again on every re-render.
|
|
132
|
+
|
|
133
|
+
A provider-based library reads the locale **once**, stores it in a context (or a signal, or a store), and every node reads a value already in memory. The provider costs a few hundred bytes. Skipping it costs CPU on every render, and it shows in the benchmark: Paraglide's page load and language-switch timings are consistently behind Intlayer's on TanStack Start (22.1 ms vs. 14.6 ms page load, 4.3 ms vs. 3.2 ms E2E reactivity).
|
|
134
|
+
|
|
135
|
+
## Developer Experience
|
|
136
|
+
|
|
137
|
+
Paraglide's source of truth is JSON, but you never import the JSON. You import the generated `.js`:
|
|
138
|
+
|
|
139
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
140
|
+
<Tab label="Paraglide" value="paraglide">
|
|
141
|
+
|
|
142
|
+
```json fileName="messages/en.json"
|
|
143
|
+
{
|
|
144
|
+
"hero_title": "Ship your app in every language"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```json fileName="messages/fr.json"
|
|
149
|
+
{
|
|
150
|
+
"hero_title": "Publiez votre app dans toutes les langues"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx fileName="Hero.tsx"
|
|
155
|
+
// Only exists after the compiler has regenerated it from the JSON
|
|
156
|
+
import { m } from "../paraglide/messages.js";
|
|
157
|
+
|
|
158
|
+
export const Hero = () => <h1>{m.hero_title()}</h1>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
</Tab>
|
|
162
|
+
<Tab label="Intlayer" value="intlayer">
|
|
163
|
+
|
|
164
|
+
```ts fileName="Hero.content.ts"
|
|
165
|
+
import { t, type Dictionary } from "intlayer";
|
|
166
|
+
|
|
167
|
+
export default {
|
|
168
|
+
key: "hero",
|
|
169
|
+
content: {
|
|
170
|
+
title: t({
|
|
171
|
+
"en-GB": "Ship your app in every language",
|
|
172
|
+
en: "Ship your app in every language",
|
|
173
|
+
fr: "Publiez votre app dans toutes les langues",
|
|
174
|
+
}),
|
|
175
|
+
},
|
|
176
|
+
} satisfies Dictionary;
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
```tsx fileName="Hero.tsx"
|
|
180
|
+
import { useIntlayer } from "react-intlayer";
|
|
181
|
+
|
|
182
|
+
export const Hero = () => {
|
|
183
|
+
const { title } = useIntlayer("hero");
|
|
184
|
+
|
|
185
|
+
return <h1>{title}</h1>;
|
|
186
|
+
};
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
</Tab>
|
|
190
|
+
</Tabs>
|
|
191
|
+
|
|
192
|
+
That loop has a cost:
|
|
193
|
+
|
|
194
|
+
- Every change to a JSON file requires a regeneration before the import resolves or the types update.
|
|
195
|
+
- The generated `paraglide/` folder is either committed, which means merge conflicts on generated files in every PR touching copy, or ignored, which means a generation step before every type check, test and CI job.
|
|
196
|
+
- Every string becomes a function call. Constants turn into `m.key()` everywhere, including places where a plain value would do.
|
|
197
|
+
|
|
198
|
+
## Tree Shaking: Check Your Bundle
|
|
199
|
+
|
|
200
|
+
Paraglide's main promise is that unused messages are tree-shaken, since each message is its own export. In the Svelte + Vite benchmark, it works as advertised.
|
|
201
|
+
|
|
202
|
+
In other setups, it did not. In our [Next.js](https://intlayer.org/en-GB/doc/benchmark/nextjs) run, Paraglide's pages weigh 14 KB more than the base app, where `next-intlayer` adds 0.3 KB. Earlier runs on TanStack Start showed messages from other pages ending up in the route bundle as well.
|
|
203
|
+
|
|
204
|
+
Tree shaking depends on your bundler (Turbopack, Rolldown, Rollup), on how messages are imported (`import { m }` vs. `import * as m`), and on side-effect analysis. If you pick Paraglide for its size, open your bundle visualiser and check that it holds in your app.
|
|
205
|
+
|
|
206
|
+
## No Dynamic Loading
|
|
207
|
+
|
|
208
|
+
This is the structural limit. Paraglide has no way to load one locale at a time: every message function statically imports the implementation of each locale, so every locale ends up in your client bundle.
|
|
209
|
+
|
|
210
|
+
With 2 locales, that is half your translation payload wasted, which matches the ~50% locale leak measured above. With 10 locales, 90% of it. With 30 locales, 97%.
|
|
211
|
+
|
|
212
|
+
Moving to dynamic loading would not fix it either: with one function per message, loading each one lazily would mean thousands of requests.
|
|
213
|
+
|
|
214
|
+
Intlayer lets you choose, globally or per dictionary:
|
|
215
|
+
|
|
216
|
+
```ts fileName="intlayer.config.ts"
|
|
217
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
218
|
+
|
|
219
|
+
const config: IntlayerConfig = {
|
|
220
|
+
internationalisation: {
|
|
221
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
222
|
+
defaultLocale: Locales.ENGLISH,
|
|
223
|
+
},
|
|
224
|
+
dictionary: {
|
|
225
|
+
importMode: "dynamic", // 'static' | 'dynamic' | 'fetch'
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export default config;
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
| `importMode` | What ships to the client | vs. Paraglide |
|
|
233
|
+
| ------------ | ------------------------------------------------------- | ---------------------------------- |
|
|
234
|
+
| `static` | All locales of the dictionaries the page uses | Theoretically the same content |
|
|
235
|
+
| `dynamic` | Only the current locale, lazy-loaded per dictionary | **N times smaller** with N locales |
|
|
236
|
+
| `fetch` | Only the current locale, fetched from the Live Sync API | **N times smaller** with N locales |
|
|
237
|
+
|
|
238
|
+
With the [build transformation](https://intlayer.org/en-GB/doc/concept/bundle-optimization) and `importMode: 'static'`, Intlayer loads, in theory, the exact same content as Paraglide. With `'dynamic'` or `'fetch'`, it loads only what the current locale needs: for an app in N locales, the translation payload is N times smaller than Paraglide's.
|
|
239
|
+
|
|
240
|
+
## Where Paraglide Still Fits
|
|
241
|
+
|
|
242
|
+
<AccordionGroup>
|
|
243
|
+
<Accordion header="Svelte + Vite with few locales">
|
|
244
|
+
|
|
245
|
+
If your stack is Svelte with Vite and you support two or three languages, tree shaking works as advertised and the locale overhead stays small.
|
|
246
|
+
|
|
247
|
+
</Accordion>
|
|
248
|
+
<Accordion header="Existing inlang workflow">
|
|
249
|
+
|
|
250
|
+
If your team already uses the inlang ecosystem (Fink, Sherlock, message format plugins), Paraglide integrates with it natively.
|
|
251
|
+
|
|
252
|
+
</Accordion>
|
|
253
|
+
</AccordionGroup>
|
|
254
|
+
|
|
255
|
+
## Try It on Your App
|
|
256
|
+
|
|
257
|
+
Check your live application's payload and locale leakage with the free [i18n SEO Scanner](https://intlayer.org/i18n-seo-scanner):
|
|
258
|
+
|
|
259
|
+
<ClickToOpenIframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
260
|
+
|
|
261
|
+
To set up Intlayer:
|
|
262
|
+
|
|
263
|
+
```bash packageManager="npm"
|
|
264
|
+
npx intlayer init --interactive
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
```bash packageManager="pnpm"
|
|
268
|
+
pnpm dlx intlayer init --interactive
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```bash packageManager="yarn"
|
|
272
|
+
yarn dlx intlayer init --interactive
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
```bash packageManager="bun"
|
|
276
|
+
bunx intlayer init --interactive
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Further Reading
|
|
280
|
+
|
|
281
|
+
- [TanStack Start i18n Benchmark](https://intlayer.org/en-GB/doc/benchmark/tanstack)
|
|
282
|
+
- [Next.js i18n Benchmark](https://intlayer.org/en-GB/doc/benchmark/nextjs)
|
|
283
|
+
- [Bundle Optimisation and `importMode`](https://intlayer.org/en-GB/doc/concept/bundle-optimization)
|
|
284
|
+
- [How to Pick a React i18n Library](https://intlayer.org/en-GB/blog/how-to-pick-react-i18n-library)
|
|
285
|
+
- [The Case for Compiler-Driven Internationalisation](https://intlayer.org/en-GB/blog/compiler-vs-declarative-i18n)
|