@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: "next-intl vs @intlayer/next-intl: 相同的 API,不同的 Bundle"
|
|
5
5
|
description: 当 Next.js 应用程序的 next-intl 导入由 @intlayer/next-intl 兼容适配器提供时会发生什么。在相同代码上测量的 Bundle 大小、泄漏、组件大小和水合,以及适配器保留、忽略和无法替换的内容。
|
|
6
6
|
keywords:
|
|
@@ -26,6 +26,8 @@ author: aymericzip
|
|
|
26
26
|
|
|
27
27
|
# next-intl VS @intlayer/next-intl | 相同的 API,不同的 Bundle
|
|
28
28
|
|
|
29
|
+

|
|
30
|
+
|
|
29
31
|
`@intlayer/next-intl` 是一个兼容适配器:它暴露 `next-intl` API(`useTranslations`、`getTranslations`、`useLocale`、`t.rich()`、ICU 复数、`NextIntlClientProvider`...),并从 Intlayer 编译的字典中提供服务。应用代码不会改变。但 bundle 会改变。
|
|
30
32
|
|
|
31
33
|
本文在同一个 Next.js 应用上对两者进行了比较,一次使用 `next-intl` 构建,一次使用适配器构建。这些数据来自 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom),一个记录浏览器实际下载内容的开源套件。如果你想要 `next-intl` vs Intlayer 作为库的比较,请阅读 [next-intl vs Intlayer](https://intlayer.org/blog/next-intl-vs-intlayer)。本文是关于当你保持组件原样不变时,适配器改变了什么。
|
|
@@ -109,6 +111,10 @@ const AboutPage = () => {
|
|
|
109
111
|
|
|
110
112
|
### Next.js 上的结果
|
|
111
113
|
|
|
114
|
+
选择您关注的指标和库:
|
|
115
|
+
|
|
116
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
117
|
+
|
|
112
118
|
| 设置 | 策略 | 库大小 (gz) | 页面 JS 平均 (gz) | 语言环境泄漏 | 页面泄漏 | 组件平均 (gz) | E2E 响应性 | 水合 |
|
|
113
119
|
| ------------------------- | -------------- | ----------: | ----------------: | -----------: | -------: | ------------: | ----------: | ----------: |
|
|
114
120
|
| **base** (no i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -129,6 +135,15 @@ const AboutPage = () => {
|
|
|
129
135
|
- **Hydration 快 2 ms**(12.8 vs 14.7 ms):在 React 可以 hydrate 之前,无需从 RSC payload 反序列化消息对象。
|
|
130
136
|
- **adapter 不是原生 runtime。** `next-intlayer` 位于 **141.3 KB**,比基础应用多 0.3 KB,带有 5.5 KB 的 runtime。adapter 在 Intlayer 的核心之上提供 `next-intl` API 表面(`useFormatter`、`t.rich`、ICU resolver),因此有 8.0 KB 和每页 +6 KB。它是桥接器,而不是目的地。
|
|
131
137
|
|
|
138
|
+
<ClickToOpenIframe
|
|
139
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.md"
|
|
140
|
+
width="100%"
|
|
141
|
+
height="600px"
|
|
142
|
+
style="border:none;"
|
|
143
|
+
/>
|
|
144
|
+
|
|
145
|
+
> 完整表格、所有库和策略请参阅 [Next.js 基准测试报告](https://intlayer.org/zh/doc/benchmark/nextjs)。
|
|
146
|
+
|
|
132
147
|
### TanStack Start 上的结果(`use-intl`)
|
|
133
148
|
|
|
134
149
|
`use-intl` 是 `next-intl` 的框架无关核心。其 adapter `@intlayer/use-intl` 采用相同的设计,配合 Vite plugin(`@intlayer/use-intl/plugin`)。
|
|
@@ -152,11 +167,24 @@ const AboutPage = () => {
|
|
|
152
167
|
- **区域设置切换更快。** 优化的 `use-intl` 设置需要 **13-21 ms** 来更新 `html[lang]`;适配器需要 **4-9 ms**。更少的组件重新渲染,并且不会从消息树中重新提取任何内容。
|
|
153
168
|
- **`static` 保留每个区域设置。** 适配器的 `static` 行显示 49.7% 的区域设置泄漏,与 `static` 模式下的本地 Intlayer 相同:所有区域设置都被打包,只有页面的字典。一行配置(`importMode: 'dynamic'`)就可以消除它。
|
|
154
169
|
|
|
170
|
+
<ClickToOpenIframe
|
|
171
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.md"
|
|
172
|
+
width="100%"
|
|
173
|
+
height="600px"
|
|
174
|
+
style="border:none;"
|
|
175
|
+
/>
|
|
176
|
+
|
|
177
|
+
> 完整表格请参阅 [TanStack Start 基准测试报告](https://intlayer.org/zh/doc/benchmark/tanstack)。
|
|
178
|
+
|
|
155
179
|
## 为什么数字会变动
|
|
156
180
|
|
|
181
|
+

|
|
182
|
+
|
|
157
183
|
组件中没有任何改变,所以所有收益完全来自于 `useTranslations` 绑定的内容。
|
|
158
184
|
|
|
159
|
-
**使用 `next-intl`**,绑定是 provider。`NextIntlClientProvider` 为该 locale 接收整个 `messages` 对象;每个 `useTranslations("about")` 都从中读取。bundler 看到一个组件导入一个读取一个 context 的 hook,无法知道只使用了 `about` 分支。下面的路由都共享同一个消息对象,所以 page-leak 列显示约 ~90
|
|
185
|
+
**使用 `next-intl`**,绑定是 provider。`NextIntlClientProvider` 为该 locale 接收整个 `messages` 对象;每个 `useTranslations("about")` 都从中读取。bundler 看到一个组件导入一个读取一个 context 的 hook,无法知道只使用了 `about` 分支。下面的路由都共享同一个消息对象,所以 page-leak 列显示约 ~90%,直到你自己分割文件, 并且这种开销在页面和语言两个维度上同时增长:
|
|
186
|
+
|
|
187
|
+

|
|
160
188
|
|
|
161
189
|
```bash
|
|
162
190
|
.
|
|
@@ -280,25 +308,106 @@ export default withIntlayer(nextConfig);
|
|
|
280
308
|
|
|
281
309
|
## 开始前需要了解的限制
|
|
282
310
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
311
|
+
<AccordionGroup>
|
|
312
|
+
<Accordion header="路由配置迁移至 intlayer.config.ts">
|
|
313
|
+
|
|
314
|
+
`createNavigation(routing)` 和 `createMiddleware(routing)` 保留其函数签名但忽略该参数:支持的语言、默认语言和前缀策略均来自 Intlayer 的 `routing` 配置。如果您使用 `next-intl` 的本地化路径 `pathnames`(`/about` 转 `/a-propos`),适配器不会对其进行插值;Intlayer 的 `routing.rewrite` 涵盖了这种情况,但这是一项单独的改动。
|
|
315
|
+
|
|
316
|
+
</Accordion>
|
|
317
|
+
<Accordion header="未指定命名空间的 useTranslations() 不会被自动绑定">
|
|
318
|
+
|
|
319
|
+
优化过程需要一个静态命名空间来确定要导入的字典。无参数调用仍可通过引用每个字典的运行时注册表运行,但这恰恰是您试图消除的内容泄漏。请显式传递命名空间。
|
|
320
|
+
|
|
321
|
+
</Accordion>
|
|
322
|
+
<Accordion header="适配器并非零开销">
|
|
323
|
+
|
|
324
|
+
运行时体积为 8.0 KB,而原生 `next-intlayer` 为 5.5 KB,且每页比原生构建多出 +6-7 KB。这是为了兼容 `next-intl` API 表面所付出的代价。如果每个组件都迁移到了 `useIntlayer`,请直接移除适配器。
|
|
325
|
+
|
|
326
|
+
</Accordion>
|
|
327
|
+
<Accordion header="provider 上的 messages、timeZone 和 now 将被忽略">
|
|
328
|
+
|
|
329
|
+
格式化器由原生 `Intl` 提供支持,只有当前语言会影响其输出。如果您依赖强制的时区或固定的 `now` 来获得注水稳定的日期,请在调用处自行处理。参见[日期、时间和数字格式化](https://intlayer.org/zh/blog/date-time-number-formatting-locales)。
|
|
330
|
+
|
|
331
|
+
</Accordion>
|
|
332
|
+
</AccordionGroup>
|
|
287
333
|
|
|
288
334
|
## 何时使用哪一个?
|
|
289
335
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
336
|
+
<AccordionGroup>
|
|
337
|
+
<Accordion header="留在 next-intl">
|
|
338
|
+
|
|
339
|
+
您的应用规模较小,无需担心打包体积,且团队乐于手动维护命名空间和按页面 `pick()`。
|
|
340
|
+
|
|
341
|
+
</Accordion>
|
|
342
|
+
<Accordion header="使用 @intlayer/next-intl">
|
|
343
|
+
|
|
344
|
+
您目前已在使用 `next-intl`,希望在无需重写代码的情况下获得包体积、防泄漏和更快的注水收益,并获得类型化键以及 CLI / CMS 工具支持。这是任何现有 `next-intl` 代码库的最佳切入点。
|
|
345
|
+
|
|
346
|
+
</Accordion>
|
|
347
|
+
<Accordion header="使用原生 (next-intlayer)">
|
|
348
|
+
|
|
349
|
+
适用于新项目,或适配器完成过渡任务后。它是三者中最轻量级的(5.5 KB,每页仅增加 +0.3 KB),并解锁同步服务端组件、按组件就近维护 `.content.ts` 文件以及完整的全套功能。请阅读 [在 Next.js 中使用 Intlayer](https://intlayer.org/zh/doc/environment/nextjs)。
|
|
350
|
+
|
|
351
|
+
</Accordion>
|
|
352
|
+
</AccordionGroup>
|
|
353
|
+
|
|
354
|
+
## 常见问题
|
|
355
|
+
|
|
356
|
+
<FAQ>
|
|
357
|
+
|
|
358
|
+
<Question title="我的应用代码真的可以保持不变吗?">
|
|
359
|
+
|
|
360
|
+
在 Next.js 中,组件代码完全无需修改:基准测试构建仅修改了 `next.config.ts` 和 `intlayer.config.ts`。`src/i18n.ts` 中的 `getRequestConfig`、provider 上的 `messages` 属性以及每页的 `pick()` 调用都会变成无用代码,您后续可以将其删除。
|
|
361
|
+
|
|
362
|
+
</Question>
|
|
363
|
+
|
|
364
|
+
<Question title="ICU 消息支持情况如何?">
|
|
365
|
+
|
|
366
|
+
它们可以继续正常工作。`t("key", { count })`、`t.rich()`、`t.markup()`、`select`、`selectordinal`、`#` 和 `{ts, date, long}` 均由 Intlayer 的 ICU 解析器处理。参见 [ICU 消息格式](https://intlayer.org/zh/blog/icu-message-format)。
|
|
367
|
+
|
|
368
|
+
</Question>
|
|
369
|
+
|
|
370
|
+
<Question title="为什么适配器比原生 next-intlayer 更重?">
|
|
371
|
+
|
|
372
|
+
它在 Intlayer 核心之上承载了整个 `next-intl` API 表面:`useFormatter`、`t.rich`、ICU 解析器、导航辅助工具。这使得体积达到 8.0 KB(原生为 5.5 KB),且每页多出 +6 KB。它是过渡桥梁,而不是最终目的地。
|
|
373
|
+
|
|
374
|
+
</Question>
|
|
375
|
+
|
|
376
|
+
<Question title="我可以按组件逐个迁移吗?">
|
|
377
|
+
|
|
378
|
+
可以。任何组件都可以随时从 `useTranslations("about")` 切换到使用就近 `.content.ts` 文件的 `useIntlayer("about")`。JSON 和 `.content.ts` 字典可以共存并自动合并。
|
|
379
|
+
|
|
380
|
+
</Question>
|
|
381
|
+
|
|
382
|
+
<Question title="本地化路径 (pathnames) 能正常工作吗?">
|
|
383
|
+
|
|
384
|
+
不能通过 `next-intl` 的 `pathnames` 生效:适配器接受其用于类型推断但不会进行插值。请改用 Intlayer 的 `routing.rewrite`,它会将本地化字面量生成到类型注册表中。
|
|
385
|
+
|
|
386
|
+
</Question>
|
|
387
|
+
|
|
388
|
+
</FAQ>
|
|
293
389
|
|
|
294
390
|
## 相关比较
|
|
295
391
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
- [
|
|
299
|
-
- [
|
|
300
|
-
- [
|
|
301
|
-
|
|
392
|
+
同一适配器系列:
|
|
393
|
+
|
|
394
|
+
- [i18next vs @intlayer/i18next](https://intlayer.org/zh/blog/i18next-vs-intlayer-i18next)
|
|
395
|
+
- [Lingui vs @intlayer/lingui](https://intlayer.org/zh/blog/lingui-vs-intlayer-lingui)
|
|
396
|
+
- [vue-i18n vs @intlayer/vue-i18n](https://intlayer.org/zh/blog/vue-i18n-vs-intlayer-vue-i18n)
|
|
397
|
+
|
|
398
|
+
两款库的直接对比:
|
|
399
|
+
|
|
400
|
+
- [next-intl vs Intlayer](https://intlayer.org/zh/blog/next-intl-vs-intlayer), 相同基准测试
|
|
401
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/zh/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
402
|
+
- [Is next-intl outdated?](https://intlayer.org/zh/blog/is-next-intl-outdated)
|
|
403
|
+
|
|
404
|
+
参考文档:
|
|
405
|
+
|
|
406
|
+
- [Compat adapter: next-intl](https://intlayer.org/zh/doc/compatibility/next-intl)
|
|
407
|
+
- [迁移指南:从 next-intl 到 Intlayer](https://intlayer.org/zh/doc/migration/next-intl)
|
|
408
|
+
- [Next.js 基准测试报告](https://intlayer.org/zh/doc/benchmark/nextjs) 与 [TanStack Start 基准测试报告](https://intlayer.org/zh/doc/benchmark/tanstack)
|
|
409
|
+
- [包体积优化](https://intlayer.org/zh/doc/concept/bundle-optimization) 与 [Intlayer 编译器](https://intlayer.org/zh/doc/compiler)
|
|
410
|
+
- [可视化编辑器](https://intlayer.org/zh/doc/concept/editor)、[CMS](https://intlayer.org/zh/doc/concept/cms) 与 [AI 翻译](https://intlayer.org/zh/doc/concept/auto-fill)
|
|
302
411
|
|
|
303
412
|
## 总结
|
|
304
413
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-09-13
|
|
3
|
-
updatedAt: 2026-09-
|
|
3
|
+
updatedAt: 2026-09-22
|
|
4
4
|
title: "next-intl vs Intlayer: 2026 基准测试与对比"
|
|
5
5
|
description: Bundle 大小、内容泄漏、locale 切换响应性和开发者体验在 Next.js 和 TanStack Start 上的测量。你应该在 2026 年选择哪个 i18n 库?
|
|
6
6
|
keywords:
|
|
@@ -24,6 +24,8 @@ author: aymericzip
|
|
|
24
24
|
|
|
25
25
|
# next-intl VS Intlayer | Next.js 国际化 (i18n) 基准测试
|
|
26
26
|
|
|
27
|
+

|
|
28
|
+
|
|
27
29
|
`next-intl` 是 Next.js 最流行的 i18n 库。Intlayer 是一个基于编译器、组件作用域的替代方案。两者都可以本地化 App Router 应用程序。问题是应用程序构建后每个库的成本是多少。
|
|
28
30
|
|
|
29
31
|
本文不是教程。这是一个由 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) 的数据支持的比较,Benchmark Bloom 是一个开源基准测试套件,它使用每个库构建相同的应用程序,并测量浏览器实际下载和执行的内容。
|
|
@@ -96,6 +98,10 @@ Intlayer 没有"scoped"变体:编译器会自动按**组件**对内容进行
|
|
|
96
98
|
|
|
97
99
|
### Next.js (App Router)上的结果
|
|
98
100
|
|
|
101
|
+
选择您关注的指标和库:
|
|
102
|
+
|
|
103
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
104
|
+
|
|
99
105
|
| Library | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|
|
100
106
|
| ------------------------------ | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | --------: |
|
|
101
107
|
| **base** (no i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -116,6 +122,15 @@ Intlayer 没有"scoped"变体:编译器会自动按**组件**对内容进行
|
|
|
116
122
|
- **组件大小。** 调用 `useTranslations()` 的组件编译到平均 21.8 KB;使用 `useIntlayer()` 的相同组件编译到 6.9 KB。在 `scoped-static` 设置中,`next-intl` 组件跳升到 80.1 KB,因为每个组件都内联其命名空间 catalog。
|
|
117
123
|
- **Reactivity 和 hydration** 在 Next.js 上对两个库都处于相同的范围(15-18 ms)。这里都不是瓶颈。
|
|
118
124
|
|
|
125
|
+
<ClickToOpenIframe
|
|
126
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.md"
|
|
127
|
+
width="100%"
|
|
128
|
+
height="600px"
|
|
129
|
+
style="border:none;"
|
|
130
|
+
/>
|
|
131
|
+
|
|
132
|
+
> 完整表格、每个库和每种策略,请参阅 [Next.js 基准测试报告](https://intlayer.org/zh/doc/benchmark/nextjs)。
|
|
133
|
+
|
|
119
134
|
### TanStack Start 上的结果(`use-intl`)
|
|
120
135
|
|
|
121
136
|
`use-intl` 是 `next-intl` 的框架无关核心。相同的 API,相同的消息格式。在 TanStack Start 上将其与 `intlayer` 进行比较,移除了方程的 Next.js 特定部分。
|
|
@@ -139,8 +154,19 @@ Intlayer 没有"scoped"变体:编译器会自动按**组件**对内容进行
|
|
|
139
154
|
- **组件大小是架构的亮点**:使用 `use-intl` 每个组件 76-87 KB,而使用 Intlayer 仅 6-8 KB。`useTranslations()` 将每个组件绑定到全局消息树;`useIntlayer()` 将其绑定到自己的字典。
|
|
140
155
|
- **区域设置切换**使用 Intlayer 快 2-4 倍(3 毫秒 vs 7-21 毫秒)。
|
|
141
156
|
|
|
157
|
+
<ClickToOpenIframe
|
|
158
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.md"
|
|
159
|
+
width="100%"
|
|
160
|
+
height="600px"
|
|
161
|
+
style="border:none;"
|
|
162
|
+
/>
|
|
163
|
+
|
|
164
|
+
> 完整表格请参阅 [TanStack Start 基准测试报告](https://intlayer.org/zh/doc/benchmark/tanstack)。
|
|
165
|
+
|
|
142
166
|
## 为什么存在差距?集中式目录 vs. 编译的字典
|
|
143
167
|
|
|
168
|
+

|
|
169
|
+
|
|
144
170
|
`next-intl` 遵循经典模型:每个区域设置一个 JSON,在 `getRequestConfig` 中加载,推送到 `NextIntlClientProvider`,通过 `t("namespace.key")` 读取。
|
|
145
171
|
|
|
146
172
|
```bash
|
|
@@ -162,6 +188,10 @@ Intlayer 没有"scoped"变体:编译器会自动按**组件**对内容进行
|
|
|
162
188
|
|
|
163
189
|
运行时无法知道页面将使用哪些 key,因此安全的默认做法是发送整个 catalog。优化意味着**你**需要将 catalog 拆分成 namespace,**你**需要决定每个页面需要哪些 namespace,并且**你**需要在组件移动时保持该映射同步。基准测试中的 `scoped-dynamic` 行是该工作的回报,但大多数团队从未实现过。
|
|
164
190
|
|
|
191
|
+
未能实现这一目标的成本在两个维度上同时增长:页面和语言环境:
|
|
192
|
+
|
|
193
|
+

|
|
194
|
+
|
|
165
195
|
Intlayer 翻转了这个责任。内容在组件旁边声明:
|
|
166
196
|
|
|
167
197
|
```bash
|
|
@@ -189,7 +219,8 @@ Intlayer 翻转了这个责任。内容在组件旁边声明:
|
|
|
189
219
|
|
|
190
220
|
### Client 组件
|
|
191
221
|
|
|
192
|
-
|
|
222
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
223
|
+
<Tab label="next-intl" value="next-intl">
|
|
193
224
|
|
|
194
225
|
```json fileName="messages/en.json"
|
|
195
226
|
{
|
|
@@ -226,7 +257,8 @@ export const Counter = () => {
|
|
|
226
257
|
|
|
227
258
|
> 记住在渲染此组件的每个页面上,将 `counter` 命名空间包含在传递给 `NextIntlClientProvider` 的消息中。
|
|
228
259
|
|
|
229
|
-
|
|
260
|
+
</Tab>
|
|
261
|
+
<Tab label="Intlayer" value="intlayer">
|
|
230
262
|
|
|
231
263
|
```ts fileName="src/components/Counter/index.content.ts"
|
|
232
264
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -269,11 +301,14 @@ export const Counter = () => {
|
|
|
269
301
|
|
|
270
302
|
无需在页面上注册任何内容:该组件包含其自己的内容。
|
|
271
303
|
|
|
304
|
+
</Tab>
|
|
305
|
+
</Tabs>
|
|
272
306
|
### 同步服务器组件
|
|
273
307
|
|
|
274
308
|
设计系统组件(导航栏、页脚、卡片)通常是作为客户端组件的子组件渲染的服务器组件,因此它们不能是 `async`。
|
|
275
309
|
|
|
276
|
-
|
|
310
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
311
|
+
<Tab label="next-intl" value="next-intl">
|
|
277
312
|
|
|
278
313
|
```tsx fileName="src/components/ServerCounter.tsx"
|
|
279
314
|
type ServerCounterProps = {
|
|
@@ -291,7 +326,8 @@ export const ServerCounter = ({ t, formattedCount }: ServerCounterProps) => (
|
|
|
291
326
|
|
|
292
327
|
页面必须 `await getTranslations("counter")` 和 `await getFormatter()`,然后将结果作为 props 向下传递。该组件不再是自包含的。
|
|
293
328
|
|
|
294
|
-
|
|
329
|
+
</Tab>
|
|
330
|
+
<Tab label="Intlayer" value="intlayer">
|
|
295
331
|
|
|
296
332
|
```tsx fileName="src/components/ServerCounter.tsx"
|
|
297
333
|
import { useIntlayer } from "next-intlayer/server";
|
|
@@ -310,9 +346,12 @@ export const ServerCounter = ({ count }: { count: number }) => {
|
|
|
310
346
|
};
|
|
311
347
|
```
|
|
312
348
|
|
|
349
|
+
</Tab>
|
|
350
|
+
</Tabs>
|
|
313
351
|
### 元数据
|
|
314
352
|
|
|
315
|
-
|
|
353
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
354
|
+
<Tab label="next-intl" value="next-intl">
|
|
316
355
|
|
|
317
356
|
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
318
357
|
import type { Metadata } from "next";
|
|
@@ -347,7 +386,8 @@ export const generateMetadata = async ({
|
|
|
347
386
|
};
|
|
348
387
|
```
|
|
349
388
|
|
|
350
|
-
|
|
389
|
+
</Tab>
|
|
390
|
+
<Tab label="Intlayer" value="intlayer">
|
|
351
391
|
|
|
352
392
|
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
353
393
|
import { getIntlayer, getMultilingualUrls } from "intlayer";
|
|
@@ -371,6 +411,9 @@ export const generateMetadata = async ({
|
|
|
371
411
|
};
|
|
372
412
|
```
|
|
373
413
|
|
|
414
|
+
</Tab>
|
|
415
|
+
</Tabs>
|
|
416
|
+
|
|
374
417
|
## 保持 next-intl API,获得 Intlayer 的输出
|
|
375
418
|
|
|
376
419
|
您不必重写组件来获得上述基准数字。`@intlayer/next-intl` 是一个开箱即用的适配器:它保持 `useTranslations`、`getTranslations`、`useFormatter`、`t.rich()`、ICU 复数形式和 `next-intl/navigation` 助手,并从 Intlayer 编译器编译的 Intlayer 字典中提供它们。
|
|
@@ -393,17 +436,84 @@ export default withIntlayer(nextConfig);
|
|
|
393
436
|
|
|
394
437
|
## 何时选择哪个?
|
|
395
438
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
439
|
+
<AccordionGroup>
|
|
440
|
+
<Accordion header="选择 next-intl">
|
|
441
|
+
|
|
442
|
+
您需要 Next.js 的生态标准,依赖 ICU MessageFormat,您的应用规模较小或中等,或者您与需要集中式 JSON 的翻译平台(Crowdin、Phrase、Lokalise...)集成。如果注重性能,请预留时间按命名空间划分目录并在每个页面使用 `pick()` 选择消息。
|
|
443
|
+
|
|
444
|
+
</Accordion>
|
|
445
|
+
<Accordion header="选择 Intlayer">
|
|
446
|
+
|
|
447
|
+
您需要**组件级作用域内容**、**严格的 TypeScript**、**构建时缺失键报错**、**零成本 tree-shaking 和按需加载**、同步服务端组件以及内置编辑工具([可视化编辑器](https://intlayer.org/zh/doc/concept/editor)、[CMS](https://intlayer.org/zh/doc/concept/cms)、[AI 自动翻译](https://intlayer.org/zh/doc/concept/auto-fill)、[MCP 服务端](https://intlayer.org/zh/doc/mcp-server))。特别适用于大型模块化代码库和设计系统。
|
|
448
|
+
|
|
449
|
+
</Accordion>
|
|
450
|
+
<Accordion header="选择 @intlayer/next-intl">
|
|
451
|
+
|
|
452
|
+
您已经在项目中使用了 `next-intl`,希望在无需重写的情况下获得包体积缩减优势。[兼容适配器](https://intlayer.org/zh/doc/compatibility/next-intl)保留了您的导入和 `messages/{locale}.json` 文件作为单一真实来源。在 [next-intl 对比 @intlayer/next-intl](https://intlayer.org/zh/blog/next-intl-vs-intlayer-next-intl) 中进行了同台实测。
|
|
453
|
+
|
|
454
|
+
</Accordion>
|
|
455
|
+
</AccordionGroup>
|
|
456
|
+
|
|
457
|
+
## 常见问题
|
|
458
|
+
|
|
459
|
+
<FAQ>
|
|
460
|
+
|
|
461
|
+
<Question title="next-intl 比 Intlayer 慢吗?">
|
|
462
|
+
|
|
463
|
+
在渲染阶段不是。两者的差异在于传输内容:`next-intl` 在每个页面上增加 **+12.6 KB gzip** 的运行时开销,并且在常见的配置下,每个页面都会携带 ~90% 的无关页面文本。在 Next.js 上语言切换与注水(hydration)耗时相近(15-18 毫秒);在 TanStack Start 上,`use-intl` 耗时 7-21 毫秒,而 Intlayer 仅需 3-4 毫秒。
|
|
464
|
+
|
|
465
|
+
</Question>
|
|
466
|
+
|
|
467
|
+
<Question title="使用 next-intl 可以实现 0% 泄漏吗?">
|
|
468
|
+
|
|
469
|
+
可以,通过 `scoped-dynamic` 配置:将 `messages/{locale}.json` 按路由拆分为单个命名空间,然后在每个页面中使用 `pick(messages, [...])` 并在组件调整时持续维护该映射关系。基准测试中的 `scoped-*` 行正代表这项工作。而 Intlayer 天然就能达到 0%,因为编译器会在组件层级对内容进行作用域划分。请参阅[包体积优化](https://intlayer.org/zh/doc/concept/bundle-optimization)。
|
|
470
|
+
|
|
471
|
+
</Question>
|
|
472
|
+
|
|
473
|
+
<Question title="迁移时需要重写组件吗?">
|
|
474
|
+
|
|
475
|
+
不需要。`@intlayer/next-intl` 保留了 `useTranslations`、`getTranslations`、`useFormatter`、`t.rich()`、ICU 复数语法和导航助手,并通过编译后的字典进行提供。只需在 `next.config.ts` 中添加一行插件配置。详情请参阅 [next-intl 迁移指南](https://intlayer.org/zh/doc/migration/next-intl)。
|
|
476
|
+
|
|
477
|
+
</Question>
|
|
478
|
+
|
|
479
|
+
<Question title="Intlayer 支持 ICU MessageFormat 吗?">
|
|
480
|
+
|
|
481
|
+
原生 API 正在积极完善 ICU 支持。兼容适配器(`@intlayer/next-intl`、`@intlayer/use-intl`)均能完美执行 ICU:复数、`select`、`selectordinal`、`#` 和 `{ts, date, long}` 都会经过 Intlayer 的 ICU 解析器处理。详情请参阅 [ICU 消息格式解析](https://intlayer.org/zh/blog/icu-message-format)。
|
|
482
|
+
|
|
483
|
+
</Question>
|
|
484
|
+
|
|
485
|
+
<Question title="我可以保留 messages/{locale}.json 文件吗?">
|
|
486
|
+
|
|
487
|
+
可以。[JSON 同步插件](https://intlayer.org/zh/doc/compatibility/next-intl)会读取这些文件,将其顶层键拆分为字典,并在 CLI 或 CMS 更新时将翻译写回同一文件。译者的工作流程完全保持不变。
|
|
488
|
+
|
|
489
|
+
</Question>
|
|
490
|
+
|
|
491
|
+
</FAQ>
|
|
399
492
|
|
|
400
493
|
## 相关比较
|
|
401
494
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
- [
|
|
405
|
-
- [
|
|
406
|
-
- [
|
|
495
|
+
同一基准测试,其他库:
|
|
496
|
+
|
|
497
|
+
- [i18next vs Intlayer](https://intlayer.org/zh/blog/i18next-vs-intlayer)
|
|
498
|
+
- [Lingui vs Intlayer](https://intlayer.org/zh/blog/lingui-vs-intlayer)
|
|
499
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/zh/blog/vue-i18n-vs-intlayer-benchmark)
|
|
500
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/zh/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
501
|
+
- [react-i18next vs react-intl vs Intlayer](https://intlayer.org/zh/blog/react-i18next-vs-react-intl-vs-intlayer)
|
|
502
|
+
|
|
503
|
+
深入了解 next-intl:
|
|
504
|
+
|
|
505
|
+
- [next-intl vs @intlayer/next-intl](https://intlayer.org/zh/blog/next-intl-vs-intlayer-next-intl), 在同一应用上实测的适配器
|
|
506
|
+
- [Is next-intl outdated?](https://intlayer.org/zh/blog/is-next-intl-outdated)
|
|
507
|
+
- [Using Intlayer with next-intl](https://intlayer.org/zh/blog/intlayer-with-next-intl)
|
|
508
|
+
- [How to internationalize a Next.js app with next-intl](https://intlayer.org/zh/blog/nextjs-internationalization-using-next-intl)
|
|
509
|
+
|
|
510
|
+
参考文档:
|
|
511
|
+
|
|
512
|
+
- [Next.js 基准测试报告](https://intlayer.org/zh/doc/benchmark/nextjs) 与 [TanStack Start 基准测试报告](https://intlayer.org/zh/doc/benchmark/tanstack)
|
|
513
|
+
- [兼容适配器:next-intl](https://intlayer.org/zh/doc/compatibility/next-intl) 与 [迁移指南](https://intlayer.org/zh/doc/migration/next-intl)
|
|
514
|
+
- [包体积优化](https://intlayer.org/zh/doc/concept/bundle-optimization) 与 [Intlayer 编译器](https://intlayer.org/zh/doc/compiler)
|
|
515
|
+
- [组件级 vs 集中式 i18n](https://intlayer.org/zh/blog/per-component-vs-centralized-i18n)
|
|
516
|
+
- [编译器驱动 vs 声明式 i18n](https://intlayer.org/zh/blog/compiler-vs-declarative-i18n)
|
|
407
517
|
|
|
408
518
|
## GitHub Stars
|
|
409
519
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-09-13
|
|
3
|
-
updatedAt: 2026-09-
|
|
3
|
+
updatedAt: 2026-09-22
|
|
4
4
|
title: "vue-i18n vs @intlayer/vue-i18n:相同的 API,不同的 Bundle"
|
|
5
5
|
description: 当 Vue 3 应用保持其 vue-i18n 调用但通过 @intlayer/vue-i18n compat 适配器提供服务时会发生什么变化。在相同的 Vite + Vue 代码上测量的每页 JavaScript、运行时大小、组件大小和泄漏,以及适配器保留、忽略和无法替换的内容。
|
|
6
6
|
keywords:
|
|
@@ -25,6 +25,8 @@ author: aymericzip
|
|
|
25
25
|
|
|
26
26
|
# vue-i18n VS @intlayer/vue-i18n | 相同的 API,不同的 Bundle
|
|
27
27
|
|
|
28
|
+

|
|
29
|
+
|
|
28
30
|
`@intlayer/vue-i18n` 是一个兼容适配器:它公开了 `vue-i18n` API(`createI18n`、`useI18n`、`t()`、`d()`、`n()`、`$t`、`v-t`、`i18n.global.locale`...),并从 Intlayer 编译的字典中提供服务。你的 `.vue` 文件不会改变。改变的是 `t("footer.github")` 绑定的内容。
|
|
29
31
|
|
|
30
32
|
本文在同一个 Vite + Vue 3 应用上测量了这个替换,该应用分别使用 `vue-i18n` 和适配器构建。数据来自 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom)。如需了解 `vue-i18n` 和 Intlayer 作为库的对比,请阅读 [vue-i18n vs Intlayer](https://intlayer.org/blog/vue-i18n-vs-intlayer) 和 [vue-i18n vs Intlayer 基准测试](https://intlayer.org/blog/vue-i18n-vs-intlayer-benchmark)。本文讨论的是当你保持组件不变时,适配器会带来什么改变。
|
|
@@ -105,6 +107,10 @@ const { t } = useI18n(_dicHash_footer);
|
|
|
105
107
|
|
|
106
108
|
### Vite + Vue 3 的结果
|
|
107
109
|
|
|
110
|
+
选择您关注的指标和库:
|
|
111
|
+
|
|
112
|
+
<I18nBenchmark framework="vite-vue" vertical/>
|
|
113
|
+
|
|
108
114
|
| Setup | Strategy | Lib size (gz) | Lib size (min) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Page load |
|
|
109
115
|
| ------------------------ | -------- | ------------: | -------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | ---------: |
|
|
110
116
|
| **base** (no i18n) | - | 0.0 KB | 0.0 KB | 41.3 KB | 0.0% | - | 1.1 KB | 1.8 ms | 10.8 ms |
|
|
@@ -124,11 +130,24 @@ const { t } = useI18n(_dicHash_footer);
|
|
|
124
130
|
- **响应性和页面加载。** 对于两者而言,语言环境切换成本低廉(1.5-2.8 ms);一旦消息在内存中,Vue 的响应性系统会实现这一点。页面加载从 13.6 ms 降低到 **9.3 ms**,与减少 88 KB 的 JavaScript 解析量一致。
|
|
125
131
|
- **关于原生行。** `vue-intlayer` 在此运行中在 `static` 模式下捆绑了每个区域设置,达到 57.1 KB,运行时为 3.9 KB;适配器的同步字典携带更少的外国语言环境字符串,因此每页数据更低。原生运行时仍然是三者中最轻的,其 `.content.ts` 模型是 SFC `<i18n>` 块找到其等效项的地方。
|
|
126
132
|
|
|
133
|
+
<ClickToOpenIframe
|
|
134
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_vue.md"
|
|
135
|
+
width="100%"
|
|
136
|
+
height="600px"
|
|
137
|
+
style="border:none;"
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
> 完整表格、各个库及每种策略,请参阅 [Vue 基准测试报告](https://intlayer.org/zh/doc/benchmark/vue)。
|
|
141
|
+
|
|
127
142
|
## 为什么数字会变化
|
|
128
143
|
|
|
144
|
+

|
|
145
|
+
|
|
129
146
|
`src/components/` 中的内容没有改变,所以收益来自 `useI18n` 绑定到的内容。
|
|
130
147
|
|
|
131
|
-
**使用 `vue-i18n`** 时,绑定是全局实例。`createI18n({ messages: { en, fr, ... } })` 是一个导入,包含所有内容;每个调用 `useI18n()` 的组件都可以访问所有内容,因此 bundler 无法在实例以下进行分割。优化意味着 _你_ 需要按路由拆分 `en.json`,在路由守卫中调用 `setLocaleMessage()`,并在组件移动时保持路由到文件的映射正确。
|
|
148
|
+
**使用 `vue-i18n`** 时,绑定是全局实例。`createI18n({ messages: { en, fr, ... } })` 是一个导入,包含所有内容;每个调用 `useI18n()` 的组件都可以访问所有内容,因此 bundler 无法在实例以下进行分割。优化意味着 _你_ 需要按路由拆分 `en.json`,在路由守卫中调用 `setLocaleMessage()`,并在组件移动时保持路由到文件的映射正确。 浪费在页面和语言两个维度上同时增长:
|
|
149
|
+
|
|
150
|
+

|
|
132
151
|
|
|
133
152
|
```bash
|
|
134
153
|
.
|
|
@@ -258,26 +277,107 @@ export const i18n = createI18n({ locale: "en" });
|
|
|
258
277
|
|
|
259
278
|
## 开始前需要了解的限制
|
|
260
279
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
280
|
+
<AccordionGroup>
|
|
281
|
+
<Accordion header="不读取 SFC <i18n> 块">
|
|
282
|
+
|
|
283
|
+
如果您的消息位于组件内部,则需要将它们移动到语言文件或 `.content.ts` 中,这具有相同的理念并提供类型支持。
|
|
284
|
+
|
|
285
|
+
</Accordion>
|
|
286
|
+
<Accordion header="移除了运行时消息加载">
|
|
287
|
+
|
|
288
|
+
`setLocaleMessage()` 和 `mergeLocaleMessage()` 会发出警告并直接返回。在运行时从 CMS 获取的翻译需要使用 [Intlayer CMS](https://intlayer.org/zh/doc/concept/cms) 或 `intlayer pull` / `push` 命令。
|
|
289
|
+
|
|
290
|
+
</Accordion>
|
|
291
|
+
<Accordion header="messages 是回退方案,并非零成本">
|
|
292
|
+
|
|
293
|
+
在 `createI18n()` 中保留 JSON 导入会在包中保留 75 KB。一旦 `intlayer test` 通过,即可将其删除。
|
|
294
|
+
|
|
295
|
+
</Accordion>
|
|
296
|
+
<Accordion header="适配器不是原生运行时">
|
|
297
|
+
|
|
298
|
+
`vue-intlayer` 仅 3.9 KB,而适配器为 7.9 KB。一旦所有组件都迁移到 `useIntlayer`,即可将其移除。
|
|
299
|
+
|
|
300
|
+
</Accordion>
|
|
301
|
+
</AccordionGroup>
|
|
265
302
|
|
|
266
303
|
## 何时使用哪个?
|
|
267
304
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
305
|
+
<AccordionGroup>
|
|
306
|
+
<Accordion header="继续使用 vue-i18n">
|
|
307
|
+
|
|
308
|
+
您的应用依赖于 SFC `<i18n>` 块、运行时 `setLocaleMessage()` 流程,或者每页 90 KB 对您的用户群而言并不是问题。
|
|
309
|
+
|
|
310
|
+
</Accordion>
|
|
311
|
+
<Accordion header="使用 @intlayer/vue-i18n">
|
|
312
|
+
|
|
313
|
+
您正在使用 `vue-i18n`,希望在不修改任何 `.vue` 文件的前提下节省 88 KB、实现组件体积缩小 23 倍、0% 页面泄漏、类型化键和 CI 检查。这是现有 `vue-i18n` 代码库的最佳切入点。
|
|
314
|
+
|
|
315
|
+
</Accordion>
|
|
316
|
+
<Accordion header="转向原生 (vue-intlayer)">
|
|
317
|
+
|
|
318
|
+
适用于新项目,或在适配器完成过渡任务之后。它具有最轻量的运行时(3.9 KB)以及按组件划分的 `.content.ts` 模式,用类型化内容取代 `<i18n>` 块。请从 [Intlayer 与 Vue](https://intlayer.org/zh/doc/environment/vite-and-vue) 或 [与 Nuxt](https://intlayer.org/zh/doc/environment/nuxt-and-vue) 开始。
|
|
319
|
+
|
|
320
|
+
</Accordion>
|
|
321
|
+
</AccordionGroup>
|
|
322
|
+
|
|
323
|
+
## 常见问题解答
|
|
324
|
+
|
|
325
|
+
<FAQ>
|
|
326
|
+
|
|
327
|
+
<Question title="我需要修改我的 .vue 文件吗?">
|
|
328
|
+
|
|
329
|
+
不需要。基准测试构建仅修改了 `vite.config.ts`、`intlayer.config.ts` 以及 `src/i18n.ts` 中引入 `messages` 的一行代码。所有 `useI18n()`、`$t`、`v-t` 和 Options API 的调用位置均保持原样。
|
|
330
|
+
|
|
331
|
+
</Question>
|
|
332
|
+
|
|
333
|
+
<Question title="为什么组件体积缩小了 23 倍?">
|
|
334
|
+
|
|
335
|
+
因为 `useI18n()` 不再访问全局实例。`createI18n({ messages })` 会持有所有语言的全部消息,因此单独编译的组件会拖入 196 KB。使用适配器后,它仅访问自己的字典:8.4 KB。
|
|
336
|
+
|
|
337
|
+
</Question>
|
|
338
|
+
|
|
339
|
+
<Question title="d() 和 n() 格式化功能如何处理?">
|
|
340
|
+
|
|
341
|
+
完全保留。传递给 `createI18n()` 的 `datetimeFormats` 和 `numberFormats` 依然有效,由原生 `Intl` 提供支持。请参阅[日期、时间和数字格式化](https://intlayer.org/zh/blog/date-time-number-formatting-locales)。
|
|
342
|
+
|
|
343
|
+
</Question>
|
|
344
|
+
|
|
345
|
+
<Question title="它是否适用于 Nuxt?">
|
|
346
|
+
|
|
347
|
+
`@intlayer/vue-i18n` 针对 Vite + Vue。对于 `@nuxtjs/i18n`,请使用 [Nuxt i18n 兼容适配器](https://intlayer.org/zh/doc/compatibility/nuxtjs-i18n),原生设置请参阅 [Intlayer 与 Nuxt](https://intlayer.org/zh/doc/environment/nuxt-and-vue)。
|
|
348
|
+
|
|
349
|
+
</Question>
|
|
350
|
+
|
|
351
|
+
<Question title="我可以按组件逐个迁移吗?">
|
|
352
|
+
|
|
353
|
+
可以。任何组件都可以通过同级放置的内容文件从 `useI18n()` 切换到 `useIntlayer("footer")`。JSON 和 `.content.ts` 字典可以并存并合并。
|
|
354
|
+
|
|
355
|
+
</Question>
|
|
356
|
+
|
|
357
|
+
</FAQ>
|
|
271
358
|
|
|
272
359
|
## 相关比较
|
|
273
360
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
- [next-intl vs @intlayer/next-intl](https://intlayer.org/blog/next-intl-vs-intlayer-next-intl)
|
|
277
|
-
- [i18next vs @intlayer/i18next](https://intlayer.org/blog/i18next-vs-intlayer-i18next)
|
|
278
|
-
- [Lingui vs @intlayer/lingui](https://intlayer.org/blog/lingui-vs-intlayer-lingui)
|
|
279
|
-
|
|
280
|
-
|
|
361
|
+
同系列适配器:
|
|
362
|
+
|
|
363
|
+
- [next-intl vs @intlayer/next-intl](https://intlayer.org/zh/blog/next-intl-vs-intlayer-next-intl)
|
|
364
|
+
- [i18next vs @intlayer/i18next](https://intlayer.org/zh/blog/i18next-vs-intlayer-i18next)
|
|
365
|
+
- [Lingui vs @intlayer/lingui](https://intlayer.org/zh/blog/lingui-vs-intlayer-lingui)
|
|
366
|
+
|
|
367
|
+
两两直接对比:
|
|
368
|
+
|
|
369
|
+
- [vue-i18n vs Intlayer](https://intlayer.org/zh/blog/vue-i18n-vs-intlayer), features and DX
|
|
370
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/zh/blog/vue-i18n-vs-intlayer-benchmark)
|
|
371
|
+
- [Is vue-i18n outdated?](https://intlayer.org/zh/blog/is-vue-i18n-outdated)
|
|
372
|
+
- [How to pick a Vue i18n library](https://intlayer.org/zh/blog/how-to-pick-vue-i18n-library)
|
|
373
|
+
|
|
374
|
+
参考文档:
|
|
375
|
+
|
|
376
|
+
- [Compat adapter: vue-i18n](https://intlayer.org/zh/doc/compatibility/vue-i18n) and [Nuxt i18n](https://intlayer.org/zh/doc/compatibility/nuxtjs-i18n)
|
|
377
|
+
- [迁移指南:从 vue-i18n 到 Intlayer](https://intlayer.org/zh/doc/migration/vue-i18n)
|
|
378
|
+
- [Vue 基准测试报告](https://intlayer.org/zh/doc/benchmark/vue)
|
|
379
|
+
- [包体积优化](https://intlayer.org/zh/doc/concept/bundle-optimization)与 [Intlayer 编译器](https://intlayer.org/zh/doc/compiler)
|
|
380
|
+
- [可视化编辑器](https://intlayer.org/zh/doc/concept/editor)、[CMS](https://intlayer.org/zh/doc/concept/cms) 与 [AI 翻译](https://intlayer.org/zh/doc/concept/auto-fill)
|
|
281
381
|
|
|
282
382
|
## 总结
|
|
283
383
|
|
|
@@ -285,4 +385,4 @@ export const i18n = createI18n({ locale: "en" });
|
|
|
285
385
|
|
|
286
386
|
所有原始数据、测试应用程序和脚本都在 [Benchmark Bloom 仓库](https://github.com/intlayer-org/benchmark-bloom) 中。自己运行它。
|
|
287
387
|
|
|
288
|
-
有关更多详细信息,请参考 ['Why Intlayer?' 文档](https://intlayer.org/doc/why)。
|
|
388
|
+
有关更多详细信息,请参考 ['Why Intlayer?' 文档](https://intlayer.org/zh/doc/why)。
|