@intlayer/docs 9.5.2 → 9.5.4-canary.0
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/README.md +9 -9
- package/blog/ar/history_of_i18n.md +54 -54
- package/blog/ar/how_to_pick_react_i18n_library.md +548 -0
- package/blog/ar/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/ar/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/ar/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/ar/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/ar/i18next_vs_intlayer.md +445 -0
- package/blog/ar/is_i18next_outdated.md +6 -2
- package/blog/ar/is_next-intl_outdated.md +6 -2
- package/blog/ar/is_vue-i18n_outdated.md +8 -2
- package/blog/ar/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/ar/lingui_vs_intlayer.md +381 -0
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +9 -5
- package/blog/ar/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/ar/next-intl_vs_intlayer.md +397 -0
- package/blog/ar/per-component_vs_centralized_i18n.md +9 -4
- package/blog/ar/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +286 -0
- package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/de/history_of_i18n.md +54 -54
- package/blog/de/how_to_pick_react_i18n_library.md +548 -0
- package/blog/de/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/de/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/de/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/de/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/de/i18next_vs_intlayer.md +445 -0
- package/blog/de/is_i18next_outdated.md +6 -2
- package/blog/de/is_next-intl_outdated.md +6 -2
- package/blog/de/is_vue-i18n_outdated.md +8 -2
- package/blog/de/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/de/lingui_vs_intlayer.md +381 -0
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/de/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/de/next-intl_vs_intlayer.md +415 -0
- package/blog/de/per-component_vs_centralized_i18n.md +9 -4
- package/blog/de/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/de/vue-i18n_vs_intlayer_benchmark.md +355 -0
- package/blog/en/history_of_i18n.md +54 -54
- package/blog/en/how_to_pick_react_i18n_library.md +542 -0
- package/blog/en/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/en/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/en/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/en/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/en/i18next_vs_intlayer.md +445 -0
- package/blog/en/is_i18next_outdated.md +6 -2
- package/blog/en/is_next-intl_outdated.md +6 -2
- package/blog/en/is_vue-i18n_outdated.md +8 -2
- package/blog/en/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/en/lingui_vs_intlayer.md +381 -0
- package/blog/en/list_i18n_technologies/frameworks/react-router.md +2 -3
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/en/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/en/next-intl_vs_intlayer.md +415 -0
- package/blog/en/per-component_vs_centralized_i18n.md +9 -4
- package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/en/vue-i18n_vs_intlayer.md +1 -1
- package/blog/en/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/en-GB/history_of_i18n.md +54 -54
- package/blog/en-GB/how_to_pick_react_i18n_library.md +542 -0
- package/blog/en-GB/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/en-GB/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/en-GB/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/en-GB/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/en-GB/i18next_vs_intlayer.md +445 -0
- package/blog/en-GB/is_i18next_outdated.md +6 -2
- package/blog/en-GB/is_next-intl_outdated.md +6 -2
- package/blog/en-GB/is_vue-i18n_outdated.md +8 -2
- package/blog/en-GB/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/en-GB/lingui_vs_intlayer.md +381 -0
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/en-GB/next-intl_vs_intlayer.md +415 -0
- package/blog/en-GB/per-component_vs_centralized_i18n.md +9 -4
- package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/en-GB/vue-i18n_vs_intlayer.md +1 -1
- package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +245 -0
- package/blog/es/history_of_i18n.md +54 -54
- package/blog/es/how_to_pick_react_i18n_library.md +542 -0
- package/blog/es/how_to_pick_solid_i18n_library.md +446 -0
- package/blog/es/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/es/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/es/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/es/i18next_vs_intlayer.md +445 -0
- package/blog/es/is_i18next_outdated.md +6 -2
- package/blog/es/is_next-intl_outdated.md +6 -2
- package/blog/es/is_vue-i18n_outdated.md +8 -2
- package/blog/es/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/es/lingui_vs_intlayer.md +381 -0
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/es/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/es/next-intl_vs_intlayer.md +417 -0
- package/blog/es/per-component_vs_centralized_i18n.md +9 -4
- package/blog/es/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/es/vue-i18n_vs_intlayer_benchmark.md +363 -0
- package/blog/fr/history_of_i18n.md +54 -54
- package/blog/fr/how_to_pick_react_i18n_library.md +542 -0
- package/blog/fr/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/fr/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/fr/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/fr/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/fr/i18next_vs_intlayer.md +445 -0
- package/blog/fr/is_i18next_outdated.md +6 -2
- package/blog/fr/is_next-intl_outdated.md +6 -2
- package/blog/fr/is_vue-i18n_outdated.md +8 -2
- package/blog/fr/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/fr/lingui_vs_intlayer.md +381 -0
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/fr/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/fr/next-intl_vs_intlayer.md +417 -0
- package/blog/fr/per-component_vs_centralized_i18n.md +9 -4
- package/blog/fr/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +287 -0
- package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +39 -0
- package/blog/hi/history_of_i18n.md +54 -54
- package/blog/hi/how_to_pick_react_i18n_library.md +548 -0
- package/blog/hi/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/hi/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/hi/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/hi/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/hi/i18next_vs_intlayer.md +445 -0
- package/blog/hi/is_i18next_outdated.md +6 -2
- package/blog/hi/is_next-intl_outdated.md +6 -2
- package/blog/hi/is_vue-i18n_outdated.md +8 -2
- package/blog/hi/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/hi/lingui_vs_intlayer.md +381 -0
- package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +8 -4
- package/blog/hi/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/hi/next-intl_vs_intlayer.md +397 -0
- package/blog/hi/per-component_vs_centralized_i18n.md +9 -4
- package/blog/hi/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/id/history_of_i18n.md +54 -54
- package/blog/id/how_to_pick_react_i18n_library.md +548 -0
- package/blog/id/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/id/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/id/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/id/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/id/i18next_vs_intlayer.md +445 -0
- package/blog/id/is_i18next_outdated.md +6 -2
- package/blog/id/is_next-intl_outdated.md +6 -2
- package/blog/id/is_vue-i18n_outdated.md +8 -2
- package/blog/id/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/id/lingui_vs_intlayer.md +381 -0
- package/blog/id/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/id/next-intl_vs_intlayer-next-intl.md +310 -0
- package/blog/id/next-intl_vs_intlayer.md +397 -0
- package/blog/id/per-component_vs_centralized_i18n.md +9 -4
- package/blog/id/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +36 -0
- package/blog/id/vue-i18n_vs_intlayer.md +1 -1
- package/blog/id/vue-i18n_vs_intlayer_benchmark.md +41 -0
- package/blog/it/history_of_i18n.md +54 -54
- package/blog/it/how_to_pick_react_i18n_library.md +549 -0
- package/blog/it/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/it/how_to_pick_svelte_i18n_library.md +455 -0
- package/blog/it/how_to_pick_vue_i18n_library.md +449 -0
- package/blog/it/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/it/i18next_vs_intlayer.md +445 -0
- package/blog/it/is_i18next_outdated.md +6 -2
- package/blog/it/is_next-intl_outdated.md +6 -2
- package/blog/it/is_vue-i18n_outdated.md +8 -2
- package/blog/it/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/it/lingui_vs_intlayer.md +381 -0
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/it/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/it/next-intl_vs_intlayer.md +418 -0
- package/blog/it/per-component_vs_centralized_i18n.md +9 -4
- package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/it/vue-i18n_vs_intlayer_benchmark.md +34 -0
- package/blog/ja/history_of_i18n.md +54 -54
- package/blog/ja/how_to_pick_react_i18n_library.md +542 -0
- package/blog/ja/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/ja/how_to_pick_svelte_i18n_library.md +457 -0
- package/blog/ja/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/ja/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/ja/i18next_vs_intlayer.md +447 -0
- package/blog/ja/is_i18next_outdated.md +6 -2
- package/blog/ja/is_next-intl_outdated.md +6 -2
- package/blog/ja/is_vue-i18n_outdated.md +8 -2
- package/blog/ja/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/ja/lingui_vs_intlayer.md +381 -0
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/ja/next-intl_vs_intlayer-next-intl.md +310 -0
- package/blog/ja/next-intl_vs_intlayer.md +422 -0
- package/blog/ja/per-component_vs_centralized_i18n.md +9 -4
- package/blog/ja/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/ja/vue-i18n_vs_intlayer.md +1 -1
- package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/ko/history_of_i18n.md +54 -54
- package/blog/ko/how_to_pick_react_i18n_library.md +548 -0
- package/blog/ko/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/ko/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/ko/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/ko/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/ko/i18next_vs_intlayer.md +447 -0
- package/blog/ko/is_i18next_outdated.md +6 -2
- package/blog/ko/is_next-intl_outdated.md +6 -2
- package/blog/ko/is_vue-i18n_outdated.md +8 -2
- package/blog/ko/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/ko/lingui_vs_intlayer.md +381 -0
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/ko/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/ko/next-intl_vs_intlayer.md +397 -0
- package/blog/ko/per-component_vs_centralized_i18n.md +9 -4
- package/blog/ko/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/ko/vue-i18n_vs_intlayer.md +1 -1
- package/blog/ko/vue-i18n_vs_intlayer_benchmark.md +366 -0
- package/blog/pl/history_of_i18n.md +54 -54
- package/blog/pl/how_to_pick_react_i18n_library.md +549 -0
- package/blog/pl/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/pl/how_to_pick_svelte_i18n_library.md +460 -0
- package/blog/pl/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/pl/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/pl/i18next_vs_intlayer.md +445 -0
- package/blog/pl/is_i18next_outdated.md +6 -2
- package/blog/pl/is_next-intl_outdated.md +6 -2
- package/blog/pl/is_vue-i18n_outdated.md +8 -2
- package/blog/pl/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/pl/lingui_vs_intlayer.md +381 -0
- package/blog/pl/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/pl/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/pl/next-intl_vs_intlayer.md +397 -0
- package/blog/pl/per-component_vs_centralized_i18n.md +9 -4
- package/blog/pl/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +289 -0
- package/blog/pl/vue-i18n_vs_intlayer.md +1 -1
- package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/pt/history_of_i18n.md +54 -54
- package/blog/pt/how_to_pick_react_i18n_library.md +549 -0
- package/blog/pt/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/pt/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/pt/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/pt/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/pt/i18next_vs_intlayer.md +445 -0
- package/blog/pt/is_i18next_outdated.md +6 -2
- package/blog/pt/is_next-intl_outdated.md +6 -2
- package/blog/pt/is_vue-i18n_outdated.md +8 -2
- package/blog/pt/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/pt/lingui_vs_intlayer.md +381 -0
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/pt/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/pt/next-intl_vs_intlayer.md +411 -0
- package/blog/pt/per-component_vs_centralized_i18n.md +9 -4
- package/blog/pt/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/ru/history_of_i18n.md +54 -54
- package/blog/ru/how_to_pick_react_i18n_library.md +553 -0
- package/blog/ru/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/ru/how_to_pick_svelte_i18n_library.md +459 -0
- package/blog/ru/how_to_pick_vue_i18n_library.md +453 -0
- package/blog/ru/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/ru/i18next_vs_intlayer.md +445 -0
- package/blog/ru/is_i18next_outdated.md +6 -2
- package/blog/ru/is_next-intl_outdated.md +6 -2
- package/blog/ru/is_vue-i18n_outdated.md +8 -2
- package/blog/ru/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/ru/lingui_vs_intlayer.md +381 -0
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +9 -5
- package/blog/ru/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/ru/next-intl_vs_intlayer.md +417 -0
- package/blog/ru/per-component_vs_centralized_i18n.md +9 -4
- package/blog/ru/react-i18next_vs_react-intl_vs_intlayer.md +5 -1
- package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +54 -0
- package/blog/tr/history_of_i18n.md +54 -54
- package/blog/tr/how_to_pick_react_i18n_library.md +548 -0
- package/blog/tr/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/tr/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/tr/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/tr/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/tr/i18next_vs_intlayer.md +445 -0
- package/blog/tr/is_i18next_outdated.md +6 -2
- package/blog/tr/is_next-intl_outdated.md +6 -2
- package/blog/tr/is_vue-i18n_outdated.md +8 -2
- package/blog/tr/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/tr/lingui_vs_intlayer.md +381 -0
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/tr/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/tr/next-intl_vs_intlayer.md +397 -0
- package/blog/tr/per-component_vs_centralized_i18n.md +9 -4
- package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/tr/vue-i18n_vs_intlayer.md +1 -1
- package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/uk/history_of_i18n.md +54 -54
- package/blog/uk/how_to_pick_react_i18n_library.md +542 -0
- package/blog/uk/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/uk/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/uk/how_to_pick_vue_i18n_library.md +443 -0
- package/blog/uk/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/uk/i18next_vs_intlayer.md +445 -0
- package/blog/uk/is_i18next_outdated.md +6 -2
- package/blog/uk/is_next-intl_outdated.md +6 -2
- package/blog/uk/is_vue-i18n_outdated.md +8 -2
- package/blog/uk/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/uk/lingui_vs_intlayer.md +381 -0
- package/blog/uk/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/uk/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/uk/next-intl_vs_intlayer.md +397 -0
- package/blog/uk/per-component_vs_centralized_i18n.md +9 -4
- package/blog/uk/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +270 -0
- package/blog/uk/vue-i18n_vs_intlayer.md +1 -1
- package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/vi/history_of_i18n.md +54 -54
- package/blog/vi/how_to_pick_react_i18n_library.md +548 -0
- package/blog/vi/how_to_pick_solid_i18n_library.md +438 -0
- package/blog/vi/how_to_pick_svelte_i18n_library.md +448 -0
- package/blog/vi/how_to_pick_vue_i18n_library.md +442 -0
- package/blog/vi/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/vi/i18next_vs_intlayer.md +445 -0
- package/blog/vi/is_i18next_outdated.md +6 -2
- package/blog/vi/is_next-intl_outdated.md +6 -2
- package/blog/vi/is_vue-i18n_outdated.md +8 -2
- package/blog/vi/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/vi/lingui_vs_intlayer.md +381 -0
- package/blog/vi/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/vi/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/vi/next-intl_vs_intlayer.md +397 -0
- package/blog/vi/per-component_vs_centralized_i18n.md +9 -4
- package/blog/vi/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/vi/vue-i18n_vs_intlayer.md +1 -1
- package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +0 -0
- package/blog/zh/history_of_i18n.md +54 -54
- package/blog/zh/how_to_pick_react_i18n_library.md +548 -0
- package/blog/zh/how_to_pick_solid_i18n_library.md +451 -0
- package/blog/zh/how_to_pick_svelte_i18n_library.md +454 -0
- package/blog/zh/how_to_pick_vue_i18n_library.md +448 -0
- package/blog/zh/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/zh/i18next_vs_intlayer.md +445 -0
- package/blog/zh/is_i18next_outdated.md +6 -2
- package/blog/zh/is_next-intl_outdated.md +6 -2
- package/blog/zh/is_vue-i18n_outdated.md +8 -2
- package/blog/zh/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/zh/lingui_vs_intlayer.md +381 -0
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +10 -6
- package/blog/zh/next-intl_vs_intlayer-next-intl.md +309 -0
- package/blog/zh/next-intl_vs_intlayer.md +422 -0
- package/blog/zh/per-component_vs_centralized_i18n.md +9 -4
- package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +6 -2
- package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/zh/vue-i18n_vs_intlayer.md +1 -1
- package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +30 -0
- package/dist/cjs/generated/blog.entry.cjs +240 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +20 -0
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/esm/generated/blog.entry.mjs +240 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +20 -0
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/types/generated/blog.entry.d.ts +12 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts +1 -0
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +1 -1
- package/docs/ar/benchmark/solid.md +1 -1
- package/docs/ar/benchmark/svelte.md +1 -1
- package/docs/ar/benchmark/tanstack.md +1 -1
- package/docs/ar/benchmark/vue.md +1 -1
- package/docs/ar/bundle_optimization.md +5 -1
- package/docs/ar/how_works_intlayer.md +2 -2
- package/docs/ar/interest_of_intlayer.md +7 -7
- package/docs/ar/intlayer_CMS.md +1 -1
- package/docs/ar/intlayer_with_adonisjs.md +1 -1
- package/docs/ar/intlayer_with_analog.md +1 -1
- package/docs/ar/intlayer_with_angular_19.md +1 -1
- package/docs/ar/intlayer_with_angular_21.md +1 -1
- package/docs/ar/intlayer_with_astro.md +1 -1
- package/docs/ar/intlayer_with_astro_lit.md +1 -1
- package/docs/ar/intlayer_with_astro_preact.md +1 -1
- package/docs/ar/intlayer_with_astro_react.md +1 -1
- package/docs/ar/intlayer_with_astro_solid.md +1 -1
- package/docs/ar/intlayer_with_astro_svelte.md +1 -1
- package/docs/ar/intlayer_with_astro_vanilla.md +1 -1
- package/docs/ar/intlayer_with_astro_vue.md +1 -1
- package/docs/ar/intlayer_with_create_react_app.md +1 -1
- package/docs/ar/intlayer_with_express.md +1 -1
- package/docs/ar/intlayer_with_hono.md +1 -1
- package/docs/ar/intlayer_with_nestjs.md +1 -1
- package/docs/ar/intlayer_with_nextjs_14.md +1 -1
- package/docs/ar/intlayer_with_nextjs_15.md +1 -1
- package/docs/ar/intlayer_with_nextjs_16.md +1 -1
- package/docs/ar/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ar/intlayer_with_react_router_v7.md +1 -1
- package/docs/ar/intlayer_with_vite+preact.md +1 -1
- package/docs/ar/intlayer_with_vite+react.md +1 -1
- package/docs/ar/intlayer_with_vite+vue.md +1 -1
- package/docs/ar/introduction.md +0 -1
- package/docs/ar/readme.md +8 -8
- package/docs/bn/bundle_optimization.md +5 -1
- package/docs/bn/interest_of_intlayer.md +22 -22
- package/docs/bn/intlayer_CMS.md +1 -1
- package/docs/bn/intlayer_with_angular_21.md +1 -1
- package/docs/bn/intlayer_with_hono.md +1 -1
- package/docs/bn/introduction.md +0 -1
- package/docs/cs/bundle_optimization.md +5 -1
- package/docs/cs/interest_of_intlayer.md +7 -7
- package/docs/cs/intlayer_with_angular_21.md +1 -1
- package/docs/cs/intlayer_with_hono.md +1 -1
- package/docs/cs/introduction.md +0 -1
- package/docs/de/benchmark/nextjs.md +1 -1
- package/docs/de/benchmark/solid.md +1 -1
- package/docs/de/benchmark/svelte.md +1 -1
- package/docs/de/benchmark/tanstack.md +1 -1
- package/docs/de/benchmark/vue.md +1 -1
- package/docs/de/bundle_optimization.md +5 -1
- package/docs/de/how_works_intlayer.md +2 -2
- package/docs/de/interest_of_intlayer.md +7 -7
- package/docs/de/intlayer_CMS.md +1 -1
- package/docs/de/intlayer_with_adonisjs.md +1 -1
- package/docs/de/intlayer_with_analog.md +1 -1
- package/docs/de/intlayer_with_angular_19.md +1 -1
- package/docs/de/intlayer_with_angular_21.md +1 -1
- package/docs/de/intlayer_with_astro.md +1 -1
- package/docs/de/intlayer_with_astro_lit.md +1 -1
- package/docs/de/intlayer_with_astro_preact.md +1 -1
- package/docs/de/intlayer_with_astro_react.md +1 -1
- package/docs/de/intlayer_with_astro_solid.md +1 -1
- package/docs/de/intlayer_with_astro_svelte.md +1 -1
- package/docs/de/intlayer_with_astro_vanilla.md +1 -1
- package/docs/de/intlayer_with_astro_vue.md +1 -1
- package/docs/de/intlayer_with_create_react_app.md +1 -1
- package/docs/de/intlayer_with_express.md +1 -1
- package/docs/de/intlayer_with_hono.md +1 -1
- package/docs/de/intlayer_with_nestjs.md +1 -1
- package/docs/de/intlayer_with_nextjs_14.md +1 -1
- package/docs/de/intlayer_with_nextjs_15.md +1 -1
- package/docs/de/intlayer_with_nextjs_16.md +1 -1
- package/docs/de/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/de/intlayer_with_vite+preact.md +1 -1
- package/docs/de/intlayer_with_vite+react.md +1 -1
- package/docs/de/intlayer_with_vite+vue.md +1 -1
- package/docs/de/introduction.md +0 -1
- package/docs/de/readme.md +8 -8
- package/docs/en/benchmark/nextjs.md +1 -1
- package/docs/en/benchmark/solid.md +1 -1
- package/docs/en/benchmark/svelte.md +1 -1
- package/docs/en/benchmark/tanstack.md +1 -1
- package/docs/en/benchmark/vue.md +1 -1
- package/docs/en/bundle_optimization.md +5 -1
- package/docs/en/how_works_intlayer.md +2 -2
- package/docs/en/interest_of_intlayer.md +7 -7
- package/docs/en/intlayer_CMS.md +1 -1
- package/docs/en/intlayer_with_adonisjs.md +1 -1
- package/docs/en/intlayer_with_analog.md +1 -1
- package/docs/en/intlayer_with_angular_19.md +1 -1
- package/docs/en/intlayer_with_angular_21.md +1 -1
- package/docs/en/intlayer_with_astro.md +1 -1
- package/docs/en/intlayer_with_astro_lit.md +1 -1
- package/docs/en/intlayer_with_astro_preact.md +1 -1
- package/docs/en/intlayer_with_astro_react.md +1 -1
- package/docs/en/intlayer_with_astro_solid.md +1 -1
- package/docs/en/intlayer_with_astro_svelte.md +1 -1
- package/docs/en/intlayer_with_astro_vanilla.md +1 -1
- package/docs/en/intlayer_with_astro_vue.md +1 -1
- package/docs/en/intlayer_with_create_react_app.md +1 -1
- package/docs/en/intlayer_with_express.md +1 -1
- package/docs/en/intlayer_with_hono.md +1 -1
- package/docs/en/intlayer_with_nestjs.md +1 -1
- package/docs/en/intlayer_with_nextjs_14.md +1 -1
- package/docs/en/intlayer_with_nextjs_15.md +1 -1
- package/docs/en/intlayer_with_nextjs_16.md +1 -1
- package/docs/en/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en/intlayer_with_vite+preact.md +1 -1
- package/docs/en/intlayer_with_vite+react.md +1 -1
- package/docs/en/intlayer_with_vite+vue.md +1 -1
- package/docs/en/introduction.md +0 -1
- package/docs/en/readme.md +8 -8
- package/docs/en-GB/benchmark/nextjs.md +1 -1
- package/docs/en-GB/benchmark/solid.md +1 -1
- package/docs/en-GB/benchmark/svelte.md +1 -1
- package/docs/en-GB/benchmark/tanstack.md +1 -1
- package/docs/en-GB/benchmark/vue.md +1 -1
- package/docs/en-GB/bundle_optimization.md +5 -1
- package/docs/en-GB/how_works_intlayer.md +2 -2
- package/docs/en-GB/interest_of_intlayer.md +7 -7
- package/docs/en-GB/intlayer_CMS.md +1 -1
- package/docs/en-GB/intlayer_with_adonisjs.md +1 -1
- package/docs/en-GB/intlayer_with_analog.md +1 -1
- package/docs/en-GB/intlayer_with_angular_19.md +1 -1
- package/docs/en-GB/intlayer_with_angular_21.md +1 -1
- package/docs/en-GB/intlayer_with_astro.md +1 -1
- package/docs/en-GB/intlayer_with_astro_lit.md +1 -1
- package/docs/en-GB/intlayer_with_astro_preact.md +1 -1
- package/docs/en-GB/intlayer_with_astro_react.md +1 -1
- package/docs/en-GB/intlayer_with_astro_solid.md +1 -1
- package/docs/en-GB/intlayer_with_astro_svelte.md +1 -1
- package/docs/en-GB/intlayer_with_astro_vanilla.md +1 -1
- package/docs/en-GB/intlayer_with_astro_vue.md +1 -1
- package/docs/en-GB/intlayer_with_create_react_app.md +1 -1
- package/docs/en-GB/intlayer_with_express.md +1 -1
- package/docs/en-GB/intlayer_with_hono.md +1 -1
- package/docs/en-GB/intlayer_with_nestjs.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_14.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_15.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_16.md +1 -1
- package/docs/en-GB/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en-GB/intlayer_with_vite+preact.md +1 -1
- package/docs/en-GB/intlayer_with_vite+react.md +1 -1
- package/docs/en-GB/intlayer_with_vite+vue.md +1 -1
- package/docs/en-GB/introduction.md +0 -1
- package/docs/en-GB/readme.md +8 -8
- package/docs/es/benchmark/nextjs.md +1 -1
- package/docs/es/benchmark/solid.md +1 -1
- package/docs/es/benchmark/svelte.md +1 -1
- package/docs/es/benchmark/tanstack.md +1 -1
- package/docs/es/benchmark/vue.md +1 -1
- package/docs/es/bundle_optimization.md +5 -1
- package/docs/es/how_works_intlayer.md +2 -2
- package/docs/es/interest_of_intlayer.md +7 -7
- package/docs/es/intlayer_CMS.md +1 -1
- package/docs/es/intlayer_with_adonisjs.md +1 -1
- package/docs/es/intlayer_with_analog.md +1 -1
- package/docs/es/intlayer_with_angular_19.md +1 -1
- package/docs/es/intlayer_with_angular_21.md +1 -1
- package/docs/es/intlayer_with_astro.md +1 -1
- package/docs/es/intlayer_with_astro_lit.md +1 -1
- package/docs/es/intlayer_with_astro_preact.md +1 -1
- package/docs/es/intlayer_with_astro_react.md +1 -1
- package/docs/es/intlayer_with_astro_solid.md +1 -1
- package/docs/es/intlayer_with_astro_svelte.md +1 -1
- package/docs/es/intlayer_with_astro_vanilla.md +1 -1
- package/docs/es/intlayer_with_astro_vue.md +1 -1
- package/docs/es/intlayer_with_create_react_app.md +1 -1
- package/docs/es/intlayer_with_express.md +1 -1
- package/docs/es/intlayer_with_hono.md +1 -1
- package/docs/es/intlayer_with_nestjs.md +1 -1
- package/docs/es/intlayer_with_nextjs_14.md +1 -1
- package/docs/es/intlayer_with_nextjs_15.md +1 -1
- package/docs/es/intlayer_with_nextjs_16.md +1 -1
- package/docs/es/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/es/intlayer_with_vite+preact.md +1 -1
- package/docs/es/intlayer_with_vite+react.md +1 -1
- package/docs/es/intlayer_with_vite+vue.md +1 -1
- package/docs/es/introduction.md +0 -1
- package/docs/es/readme.md +8 -8
- package/docs/fr/benchmark/nextjs.md +1 -1
- package/docs/fr/benchmark/solid.md +1 -1
- package/docs/fr/benchmark/svelte.md +1 -1
- package/docs/fr/benchmark/tanstack.md +1 -1
- package/docs/fr/benchmark/vue.md +1 -1
- package/docs/fr/bundle_optimization.md +5 -1
- package/docs/fr/how_works_intlayer.md +2 -2
- package/docs/fr/interest_of_intlayer.md +7 -7
- package/docs/fr/intlayer_CMS.md +1 -1
- package/docs/fr/intlayer_with_adonisjs.md +1 -1
- package/docs/fr/intlayer_with_analog.md +1 -1
- package/docs/fr/intlayer_with_angular_19.md +1 -1
- package/docs/fr/intlayer_with_angular_21.md +1 -1
- package/docs/fr/intlayer_with_astro.md +1 -1
- package/docs/fr/intlayer_with_astro_lit.md +1 -1
- package/docs/fr/intlayer_with_astro_preact.md +1 -1
- package/docs/fr/intlayer_with_astro_react.md +1 -1
- package/docs/fr/intlayer_with_astro_solid.md +1 -1
- package/docs/fr/intlayer_with_astro_svelte.md +1 -1
- package/docs/fr/intlayer_with_astro_vanilla.md +1 -1
- package/docs/fr/intlayer_with_astro_vue.md +1 -1
- package/docs/fr/intlayer_with_create_react_app.md +1 -1
- package/docs/fr/intlayer_with_express.md +1 -1
- package/docs/fr/intlayer_with_hono.md +1 -1
- package/docs/fr/intlayer_with_nestjs.md +1 -1
- package/docs/fr/intlayer_with_nextjs_14.md +1 -1
- package/docs/fr/intlayer_with_nextjs_15.md +1 -1
- package/docs/fr/intlayer_with_nextjs_16.md +1 -1
- package/docs/fr/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/fr/intlayer_with_react_router_v7.md +2 -2
- package/docs/fr/intlayer_with_vite+preact.md +1 -1
- package/docs/fr/intlayer_with_vite+react.md +1 -1
- package/docs/fr/intlayer_with_vite+vue.md +1 -1
- package/docs/fr/introduction.md +0 -1
- package/docs/fr/readme.md +8 -8
- package/docs/hi/benchmark/nextjs.md +1 -1
- package/docs/hi/benchmark/solid.md +1 -1
- package/docs/hi/benchmark/svelte.md +1 -1
- package/docs/hi/benchmark/tanstack.md +1 -1
- package/docs/hi/benchmark/vue.md +1 -1
- package/docs/hi/bundle_optimization.md +5 -1
- package/docs/hi/how_works_intlayer.md +2 -2
- package/docs/hi/interest_of_intlayer.md +7 -7
- package/docs/hi/intlayer_CMS.md +1 -1
- package/docs/hi/intlayer_with_adonisjs.md +1 -1
- package/docs/hi/intlayer_with_analog.md +1 -1
- package/docs/hi/intlayer_with_angular_19.md +1 -1
- package/docs/hi/intlayer_with_angular_21.md +1 -1
- package/docs/hi/intlayer_with_astro.md +1 -1
- package/docs/hi/intlayer_with_astro_lit.md +1 -1
- package/docs/hi/intlayer_with_astro_preact.md +1 -1
- package/docs/hi/intlayer_with_astro_react.md +1 -1
- package/docs/hi/intlayer_with_astro_solid.md +1 -1
- package/docs/hi/intlayer_with_astro_svelte.md +1 -1
- package/docs/hi/intlayer_with_astro_vanilla.md +1 -1
- package/docs/hi/intlayer_with_astro_vue.md +1 -1
- package/docs/hi/intlayer_with_create_react_app.md +1 -1
- package/docs/hi/intlayer_with_express.md +1 -1
- package/docs/hi/intlayer_with_hono.md +1 -1
- package/docs/hi/intlayer_with_nestjs.md +1 -1
- package/docs/hi/intlayer_with_nextjs_14.md +1 -1
- package/docs/hi/intlayer_with_nextjs_15.md +1 -1
- package/docs/hi/intlayer_with_nextjs_16.md +1 -1
- package/docs/hi/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/hi/intlayer_with_react_router_v7.md +1 -1
- package/docs/hi/intlayer_with_vite+preact.md +1 -1
- package/docs/hi/intlayer_with_vite+react.md +1 -1
- package/docs/hi/intlayer_with_vite+vue.md +1 -1
- package/docs/hi/introduction.md +0 -1
- package/docs/hi/readme.md +8 -8
- package/docs/id/benchmark/nextjs.md +1 -1
- package/docs/id/benchmark/solid.md +1 -1
- package/docs/id/benchmark/svelte.md +1 -1
- package/docs/id/benchmark/tanstack.md +1 -1
- package/docs/id/benchmark/vue.md +1 -1
- package/docs/id/bundle_optimization.md +5 -1
- package/docs/id/how_works_intlayer.md +2 -2
- package/docs/id/interest_of_intlayer.md +7 -7
- package/docs/id/intlayer_CMS.md +1 -1
- package/docs/id/intlayer_with_adonisjs.md +1 -1
- package/docs/id/intlayer_with_analog.md +1 -1
- package/docs/id/intlayer_with_angular_19.md +1 -1
- package/docs/id/intlayer_with_angular_21.md +1 -1
- package/docs/id/intlayer_with_astro.md +1 -1
- package/docs/id/intlayer_with_astro_lit.md +1 -1
- package/docs/id/intlayer_with_astro_preact.md +1 -1
- package/docs/id/intlayer_with_astro_react.md +1 -1
- package/docs/id/intlayer_with_astro_solid.md +1 -1
- package/docs/id/intlayer_with_astro_svelte.md +1 -1
- package/docs/id/intlayer_with_astro_vanilla.md +1 -1
- package/docs/id/intlayer_with_astro_vue.md +1 -1
- package/docs/id/intlayer_with_create_react_app.md +1 -1
- package/docs/id/intlayer_with_express.md +1 -1
- package/docs/id/intlayer_with_hono.md +1 -1
- package/docs/id/intlayer_with_nestjs.md +1 -1
- package/docs/id/intlayer_with_nextjs_14.md +1 -1
- package/docs/id/intlayer_with_nextjs_15.md +1 -1
- package/docs/id/intlayer_with_nextjs_16.md +1 -1
- package/docs/id/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/id/intlayer_with_react_router_v7.md +1 -1
- package/docs/id/intlayer_with_vite+preact.md +1 -1
- package/docs/id/intlayer_with_vite+react.md +1 -1
- package/docs/id/intlayer_with_vite+vue.md +1 -1
- package/docs/id/introduction.md +0 -1
- package/docs/id/readme.md +8 -8
- package/docs/it/benchmark/nextjs.md +1 -1
- package/docs/it/benchmark/solid.md +1 -1
- package/docs/it/benchmark/svelte.md +1 -1
- package/docs/it/benchmark/tanstack.md +1 -1
- package/docs/it/benchmark/vue.md +1 -1
- package/docs/it/bundle_optimization.md +5 -1
- package/docs/it/how_works_intlayer.md +2 -2
- package/docs/it/interest_of_intlayer.md +7 -7
- package/docs/it/intlayer_CMS.md +1 -1
- package/docs/it/intlayer_with_adonisjs.md +1 -1
- package/docs/it/intlayer_with_analog.md +1 -1
- package/docs/it/intlayer_with_angular_19.md +1 -1
- package/docs/it/intlayer_with_angular_21.md +1 -1
- package/docs/it/intlayer_with_astro.md +1 -1
- package/docs/it/intlayer_with_astro_lit.md +1 -1
- package/docs/it/intlayer_with_astro_preact.md +1 -1
- package/docs/it/intlayer_with_astro_react.md +1 -1
- package/docs/it/intlayer_with_astro_solid.md +1 -1
- package/docs/it/intlayer_with_astro_svelte.md +1 -1
- package/docs/it/intlayer_with_astro_vanilla.md +1 -1
- package/docs/it/intlayer_with_astro_vue.md +1 -1
- package/docs/it/intlayer_with_create_react_app.md +1 -1
- package/docs/it/intlayer_with_express.md +1 -1
- package/docs/it/intlayer_with_hono.md +1 -1
- package/docs/it/intlayer_with_nestjs.md +1 -1
- package/docs/it/intlayer_with_nextjs_14.md +1 -1
- package/docs/it/intlayer_with_nextjs_15.md +1 -1
- package/docs/it/intlayer_with_nextjs_16.md +1 -1
- package/docs/it/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/it/intlayer_with_react_router_v7.md +2 -2
- package/docs/it/intlayer_with_vite+preact.md +1 -1
- package/docs/it/intlayer_with_vite+react.md +1 -1
- package/docs/it/intlayer_with_vite+vue.md +1 -1
- package/docs/it/introduction.md +0 -1
- package/docs/it/readme.md +8 -8
- package/docs/ja/benchmark/nextjs.md +1 -1
- package/docs/ja/benchmark/solid.md +1 -1
- package/docs/ja/benchmark/svelte.md +1 -1
- package/docs/ja/benchmark/tanstack.md +1 -1
- package/docs/ja/benchmark/vue.md +1 -1
- package/docs/ja/bundle_optimization.md +5 -1
- package/docs/ja/how_works_intlayer.md +2 -2
- package/docs/ja/interest_of_intlayer.md +7 -7
- package/docs/ja/intlayer_CMS.md +1 -1
- package/docs/ja/intlayer_with_adonisjs.md +1 -1
- package/docs/ja/intlayer_with_analog.md +1 -1
- package/docs/ja/intlayer_with_angular_19.md +1 -1
- package/docs/ja/intlayer_with_angular_21.md +1 -1
- package/docs/ja/intlayer_with_astro.md +1 -1
- package/docs/ja/intlayer_with_astro_lit.md +1 -1
- package/docs/ja/intlayer_with_astro_preact.md +1 -1
- package/docs/ja/intlayer_with_astro_react.md +1 -1
- package/docs/ja/intlayer_with_astro_solid.md +1 -1
- package/docs/ja/intlayer_with_astro_svelte.md +1 -1
- package/docs/ja/intlayer_with_astro_vanilla.md +1 -1
- package/docs/ja/intlayer_with_astro_vue.md +1 -1
- package/docs/ja/intlayer_with_create_react_app.md +1 -1
- package/docs/ja/intlayer_with_express.md +1 -1
- package/docs/ja/intlayer_with_hono.md +1 -1
- package/docs/ja/intlayer_with_nestjs.md +1 -1
- package/docs/ja/intlayer_with_nextjs_14.md +1 -1
- package/docs/ja/intlayer_with_nextjs_15.md +1 -1
- package/docs/ja/intlayer_with_nextjs_16.md +1 -1
- package/docs/ja/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ja/intlayer_with_vite+preact.md +1 -1
- package/docs/ja/intlayer_with_vite+react.md +1 -1
- package/docs/ja/intlayer_with_vite+vue.md +1 -1
- package/docs/ja/introduction.md +0 -1
- package/docs/ja/readme.md +8 -8
- package/docs/ko/benchmark/nextjs.md +1 -1
- package/docs/ko/benchmark/solid.md +1 -1
- package/docs/ko/benchmark/svelte.md +1 -1
- package/docs/ko/benchmark/tanstack.md +1 -1
- package/docs/ko/benchmark/vue.md +1 -1
- package/docs/ko/bundle_optimization.md +5 -1
- package/docs/ko/how_works_intlayer.md +2 -2
- package/docs/ko/interest_of_intlayer.md +7 -7
- package/docs/ko/intlayer_CMS.md +1 -1
- package/docs/ko/intlayer_with_adonisjs.md +1 -1
- package/docs/ko/intlayer_with_analog.md +1 -1
- package/docs/ko/intlayer_with_angular_19.md +1 -1
- package/docs/ko/intlayer_with_angular_21.md +1 -1
- package/docs/ko/intlayer_with_astro.md +1 -1
- package/docs/ko/intlayer_with_astro_lit.md +1 -1
- package/docs/ko/intlayer_with_astro_preact.md +1 -1
- package/docs/ko/intlayer_with_astro_react.md +1 -1
- package/docs/ko/intlayer_with_astro_solid.md +1 -1
- package/docs/ko/intlayer_with_astro_svelte.md +1 -1
- package/docs/ko/intlayer_with_astro_vanilla.md +1 -1
- package/docs/ko/intlayer_with_astro_vue.md +1 -1
- package/docs/ko/intlayer_with_create_react_app.md +1 -1
- package/docs/ko/intlayer_with_express.md +1 -1
- package/docs/ko/intlayer_with_hono.md +1 -1
- package/docs/ko/intlayer_with_nestjs.md +1 -1
- package/docs/ko/intlayer_with_nextjs_14.md +1 -1
- package/docs/ko/intlayer_with_nextjs_15.md +1 -1
- package/docs/ko/intlayer_with_nextjs_16.md +1 -1
- package/docs/ko/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ko/intlayer_with_react_router_v7.md +2 -2
- package/docs/ko/intlayer_with_vite+preact.md +1 -1
- package/docs/ko/intlayer_with_vite+react.md +1 -1
- package/docs/ko/intlayer_with_vite+vue.md +1 -1
- package/docs/ko/introduction.md +0 -1
- package/docs/ko/readme.md +8 -8
- package/docs/nl/bundle_optimization.md +5 -1
- package/docs/nl/interest_of_intlayer.md +7 -7
- package/docs/nl/intlayer_with_angular_21.md +1 -1
- package/docs/nl/intlayer_with_hono.md +1 -1
- package/docs/nl/introduction.md +0 -1
- package/docs/pl/benchmark/nextjs.md +1 -1
- package/docs/pl/benchmark/solid.md +1 -1
- package/docs/pl/benchmark/svelte.md +1 -1
- package/docs/pl/benchmark/tanstack.md +1 -1
- package/docs/pl/benchmark/vue.md +1 -1
- package/docs/pl/bundle_optimization.md +5 -1
- package/docs/pl/how_works_intlayer.md +2 -2
- package/docs/pl/interest_of_intlayer.md +7 -7
- package/docs/pl/intlayer_CMS.md +1 -1
- package/docs/pl/intlayer_with_adonisjs.md +1 -1
- package/docs/pl/intlayer_with_analog.md +1 -1
- package/docs/pl/intlayer_with_angular_19.md +1 -1
- package/docs/pl/intlayer_with_angular_21.md +1 -1
- package/docs/pl/intlayer_with_astro.md +1 -1
- package/docs/pl/intlayer_with_astro_lit.md +1 -1
- package/docs/pl/intlayer_with_astro_preact.md +1 -1
- package/docs/pl/intlayer_with_astro_react.md +1 -1
- package/docs/pl/intlayer_with_astro_solid.md +1 -1
- package/docs/pl/intlayer_with_astro_svelte.md +1 -1
- package/docs/pl/intlayer_with_astro_vanilla.md +1 -1
- package/docs/pl/intlayer_with_astro_vue.md +1 -1
- package/docs/pl/intlayer_with_create_react_app.md +1 -1
- package/docs/pl/intlayer_with_express.md +1 -1
- package/docs/pl/intlayer_with_hono.md +1 -1
- package/docs/pl/intlayer_with_nestjs.md +1 -1
- package/docs/pl/intlayer_with_nextjs_14.md +1 -1
- package/docs/pl/intlayer_with_nextjs_15.md +1 -1
- package/docs/pl/intlayer_with_nextjs_16.md +1 -1
- package/docs/pl/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/pl/intlayer_with_react_router_v7.md +2 -2
- package/docs/pl/intlayer_with_vite+preact.md +1 -1
- package/docs/pl/intlayer_with_vite+react.md +1 -1
- package/docs/pl/intlayer_with_vite+vue.md +1 -1
- package/docs/pl/introduction.md +0 -1
- package/docs/pl/readme.md +8 -8
- package/docs/pt/benchmark/nextjs.md +1 -1
- package/docs/pt/benchmark/solid.md +1 -1
- package/docs/pt/benchmark/svelte.md +1 -1
- package/docs/pt/benchmark/tanstack.md +1 -1
- package/docs/pt/benchmark/vue.md +1 -1
- package/docs/pt/bundle_optimization.md +5 -1
- package/docs/pt/how_works_intlayer.md +2 -2
- package/docs/pt/interest_of_intlayer.md +7 -7
- package/docs/pt/intlayer_CMS.md +1 -1
- package/docs/pt/intlayer_with_adonisjs.md +1 -1
- package/docs/pt/intlayer_with_analog.md +1 -1
- package/docs/pt/intlayer_with_angular_19.md +1 -1
- package/docs/pt/intlayer_with_angular_21.md +1 -1
- package/docs/pt/intlayer_with_astro.md +1 -1
- package/docs/pt/intlayer_with_astro_lit.md +1 -1
- package/docs/pt/intlayer_with_astro_preact.md +1 -1
- package/docs/pt/intlayer_with_astro_react.md +1 -1
- package/docs/pt/intlayer_with_astro_solid.md +1 -1
- package/docs/pt/intlayer_with_astro_svelte.md +1 -1
- package/docs/pt/intlayer_with_astro_vanilla.md +1 -1
- package/docs/pt/intlayer_with_astro_vue.md +1 -1
- package/docs/pt/intlayer_with_create_react_app.md +1 -1
- package/docs/pt/intlayer_with_express.md +1 -1
- package/docs/pt/intlayer_with_hono.md +1 -1
- package/docs/pt/intlayer_with_nestjs.md +1 -1
- package/docs/pt/intlayer_with_nextjs_14.md +1 -1
- package/docs/pt/intlayer_with_nextjs_15.md +1 -1
- package/docs/pt/intlayer_with_nextjs_16.md +1 -1
- package/docs/pt/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/pt/intlayer_with_react_router_v7.md +2 -2
- package/docs/pt/intlayer_with_vite+preact.md +1 -1
- package/docs/pt/intlayer_with_vite+react.md +1 -1
- package/docs/pt/intlayer_with_vite+vue.md +1 -1
- package/docs/pt/introduction.md +0 -1
- package/docs/pt/readme.md +8 -8
- package/docs/ru/benchmark/nextjs.md +1 -1
- package/docs/ru/benchmark/solid.md +1 -1
- package/docs/ru/benchmark/svelte.md +1 -1
- package/docs/ru/benchmark/tanstack.md +1 -1
- package/docs/ru/benchmark/vue.md +1 -1
- package/docs/ru/bundle_optimization.md +5 -1
- package/docs/ru/how_works_intlayer.md +2 -2
- package/docs/ru/interest_of_intlayer.md +7 -7
- package/docs/ru/intlayer_CMS.md +1 -1
- package/docs/ru/intlayer_with_adonisjs.md +1 -1
- package/docs/ru/intlayer_with_analog.md +1 -1
- package/docs/ru/intlayer_with_angular_19.md +1 -1
- package/docs/ru/intlayer_with_angular_21.md +1 -1
- package/docs/ru/intlayer_with_astro.md +1 -1
- package/docs/ru/intlayer_with_astro_lit.md +1 -1
- package/docs/ru/intlayer_with_astro_preact.md +1 -1
- package/docs/ru/intlayer_with_astro_react.md +1 -1
- package/docs/ru/intlayer_with_astro_solid.md +1 -1
- package/docs/ru/intlayer_with_astro_svelte.md +1 -1
- package/docs/ru/intlayer_with_astro_vanilla.md +1 -1
- package/docs/ru/intlayer_with_astro_vue.md +1 -1
- package/docs/ru/intlayer_with_create_react_app.md +1 -1
- package/docs/ru/intlayer_with_express.md +1 -1
- package/docs/ru/intlayer_with_hono.md +1 -1
- package/docs/ru/intlayer_with_nestjs.md +1 -1
- package/docs/ru/intlayer_with_nextjs_14.md +1 -1
- package/docs/ru/intlayer_with_nextjs_15.md +1 -1
- package/docs/ru/intlayer_with_nextjs_16.md +1 -1
- package/docs/ru/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ru/intlayer_with_react_router_v7.md +2 -2
- package/docs/ru/intlayer_with_vite+preact.md +1 -1
- package/docs/ru/intlayer_with_vite+react.md +1 -1
- package/docs/ru/intlayer_with_vite+vue.md +1 -1
- package/docs/ru/introduction.md +0 -1
- package/docs/ru/readme.md +8 -8
- package/docs/tr/benchmark/nextjs.md +1 -1
- package/docs/tr/benchmark/solid.md +1 -1
- package/docs/tr/benchmark/svelte.md +1 -1
- package/docs/tr/benchmark/tanstack.md +1 -1
- package/docs/tr/benchmark/vue.md +1 -1
- package/docs/tr/bundle_optimization.md +5 -1
- package/docs/tr/how_works_intlayer.md +2 -2
- package/docs/tr/interest_of_intlayer.md +7 -7
- package/docs/tr/intlayer_CMS.md +1 -1
- package/docs/tr/intlayer_with_adonisjs.md +1 -1
- package/docs/tr/intlayer_with_analog.md +1 -1
- package/docs/tr/intlayer_with_angular_19.md +1 -1
- package/docs/tr/intlayer_with_angular_21.md +1 -1
- package/docs/tr/intlayer_with_astro.md +1 -1
- package/docs/tr/intlayer_with_astro_lit.md +1 -1
- package/docs/tr/intlayer_with_astro_preact.md +1 -1
- package/docs/tr/intlayer_with_astro_react.md +1 -1
- package/docs/tr/intlayer_with_astro_solid.md +1 -1
- package/docs/tr/intlayer_with_astro_svelte.md +1 -1
- package/docs/tr/intlayer_with_astro_vanilla.md +1 -1
- package/docs/tr/intlayer_with_astro_vue.md +1 -1
- package/docs/tr/intlayer_with_create_react_app.md +1 -1
- package/docs/tr/intlayer_with_express.md +1 -1
- package/docs/tr/intlayer_with_hono.md +1 -1
- package/docs/tr/intlayer_with_nestjs.md +1 -1
- package/docs/tr/intlayer_with_nextjs_14.md +1 -1
- package/docs/tr/intlayer_with_nextjs_15.md +1 -1
- package/docs/tr/intlayer_with_nextjs_16.md +1 -1
- package/docs/tr/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/tr/intlayer_with_react_router_v7.md +1 -1
- package/docs/tr/intlayer_with_vite+preact.md +1 -1
- package/docs/tr/intlayer_with_vite+react.md +1 -1
- package/docs/tr/intlayer_with_vite+vue.md +1 -1
- package/docs/tr/introduction.md +0 -1
- package/docs/tr/readme.md +8 -8
- package/docs/uk/benchmark/nextjs.md +1 -1
- package/docs/uk/benchmark/solid.md +1 -1
- package/docs/uk/benchmark/svelte.md +1 -1
- package/docs/uk/benchmark/tanstack.md +1 -1
- package/docs/uk/benchmark/vue.md +1 -1
- package/docs/uk/bundle_optimization.md +5 -1
- package/docs/uk/how_works_intlayer.md +2 -2
- package/docs/uk/interest_of_intlayer.md +7 -7
- package/docs/uk/intlayer_CMS.md +1 -1
- package/docs/uk/intlayer_with_adonisjs.md +1 -1
- package/docs/uk/intlayer_with_analog.md +1 -1
- package/docs/uk/intlayer_with_angular_19.md +1 -1
- package/docs/uk/intlayer_with_angular_21.md +1 -1
- package/docs/uk/intlayer_with_astro.md +1 -1
- package/docs/uk/intlayer_with_astro_lit.md +1 -1
- package/docs/uk/intlayer_with_astro_preact.md +1 -1
- package/docs/uk/intlayer_with_astro_react.md +1 -1
- package/docs/uk/intlayer_with_astro_solid.md +1 -1
- package/docs/uk/intlayer_with_astro_svelte.md +1 -1
- package/docs/uk/intlayer_with_astro_vanilla.md +1 -1
- package/docs/uk/intlayer_with_astro_vue.md +1 -1
- package/docs/uk/intlayer_with_create_react_app.md +1 -1
- package/docs/uk/intlayer_with_express.md +1 -1
- package/docs/uk/intlayer_with_hono.md +1 -1
- package/docs/uk/intlayer_with_nestjs.md +1 -1
- package/docs/uk/intlayer_with_nextjs_14.md +1 -1
- package/docs/uk/intlayer_with_nextjs_15.md +1 -1
- package/docs/uk/intlayer_with_nextjs_16.md +1 -1
- package/docs/uk/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/uk/intlayer_with_react_router_v7.md +1 -1
- package/docs/uk/intlayer_with_vite+preact.md +1 -1
- package/docs/uk/intlayer_with_vite+react.md +1 -1
- package/docs/uk/intlayer_with_vite+vue.md +1 -1
- package/docs/uk/introduction.md +0 -1
- package/docs/uk/readme.md +8 -8
- package/docs/ur/bundle_optimization.md +5 -1
- package/docs/ur/interest_of_intlayer.md +7 -7
- package/docs/ur/intlayer_with_angular_21.md +1 -1
- package/docs/ur/intlayer_with_hono.md +1 -1
- package/docs/ur/introduction.md +0 -1
- package/docs/vi/benchmark/nextjs.md +1 -1
- package/docs/vi/benchmark/solid.md +1 -1
- package/docs/vi/benchmark/svelte.md +1 -1
- package/docs/vi/benchmark/tanstack.md +1 -1
- package/docs/vi/benchmark/vue.md +1 -1
- package/docs/vi/bundle_optimization.md +5 -1
- package/docs/vi/how_works_intlayer.md +2 -2
- package/docs/vi/interest_of_intlayer.md +7 -7
- package/docs/vi/intlayer_CMS.md +1 -1
- package/docs/vi/intlayer_with_adonisjs.md +1 -1
- package/docs/vi/intlayer_with_analog.md +1 -1
- package/docs/vi/intlayer_with_angular_19.md +1 -1
- package/docs/vi/intlayer_with_angular_21.md +1 -1
- package/docs/vi/intlayer_with_astro.md +1 -1
- package/docs/vi/intlayer_with_astro_lit.md +1 -1
- package/docs/vi/intlayer_with_astro_preact.md +1 -1
- package/docs/vi/intlayer_with_astro_react.md +1 -1
- package/docs/vi/intlayer_with_astro_solid.md +1 -1
- package/docs/vi/intlayer_with_astro_svelte.md +1 -1
- package/docs/vi/intlayer_with_astro_vanilla.md +1 -1
- package/docs/vi/intlayer_with_astro_vue.md +1 -1
- package/docs/vi/intlayer_with_create_react_app.md +1 -1
- package/docs/vi/intlayer_with_express.md +1 -1
- package/docs/vi/intlayer_with_hono.md +1 -1
- package/docs/vi/intlayer_with_nestjs.md +1 -1
- package/docs/vi/intlayer_with_nextjs_14.md +1 -1
- package/docs/vi/intlayer_with_nextjs_15.md +1 -1
- package/docs/vi/intlayer_with_nextjs_16.md +1 -1
- package/docs/vi/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/vi/intlayer_with_vite+preact.md +1 -1
- package/docs/vi/intlayer_with_vite+react.md +1 -1
- package/docs/vi/intlayer_with_vite+vue.md +1 -1
- package/docs/vi/introduction.md +0 -1
- package/docs/vi/readme.md +8 -8
- package/docs/zh/benchmark/nextjs.md +1 -1
- package/docs/zh/benchmark/solid.md +1 -1
- package/docs/zh/benchmark/svelte.md +1 -1
- package/docs/zh/benchmark/tanstack.md +1 -1
- package/docs/zh/benchmark/vue.md +1 -1
- package/docs/zh/bundle_optimization.md +5 -1
- package/docs/zh/how_works_intlayer.md +2 -2
- package/docs/zh/interest_of_intlayer.md +7 -7
- package/docs/zh/intlayer_CMS.md +1 -1
- package/docs/zh/intlayer_with_adonisjs.md +1 -1
- package/docs/zh/intlayer_with_analog.md +1 -1
- package/docs/zh/intlayer_with_angular_19.md +1 -1
- package/docs/zh/intlayer_with_angular_21.md +1 -1
- package/docs/zh/intlayer_with_astro.md +1 -1
- package/docs/zh/intlayer_with_astro_lit.md +1 -1
- package/docs/zh/intlayer_with_astro_preact.md +1 -1
- package/docs/zh/intlayer_with_astro_react.md +1 -1
- package/docs/zh/intlayer_with_astro_solid.md +1 -1
- package/docs/zh/intlayer_with_astro_svelte.md +1 -1
- package/docs/zh/intlayer_with_astro_vanilla.md +1 -1
- package/docs/zh/intlayer_with_astro_vue.md +1 -1
- package/docs/zh/intlayer_with_create_react_app.md +1 -1
- package/docs/zh/intlayer_with_express.md +1 -1
- package/docs/zh/intlayer_with_hono.md +1 -1
- package/docs/zh/intlayer_with_nestjs.md +1 -1
- package/docs/zh/intlayer_with_nextjs_14.md +1 -1
- package/docs/zh/intlayer_with_nextjs_15.md +1 -1
- package/docs/zh/intlayer_with_nextjs_16.md +1 -1
- package/docs/zh/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +2 -2
- package/docs/zh/intlayer_with_vite+preact.md +1 -1
- package/docs/zh/intlayer_with_vite+react.md +1 -1
- package/docs/zh/intlayer_with_vite+vue.md +1 -1
- package/docs/zh/introduction.md +0 -1
- package/docs/zh/readme.md +8 -8
- package/docs/zh-TW/bundle_optimization.md +5 -1
- package/docs/zh-TW/interest_of_intlayer.md +7 -7
- package/docs/zh-TW/intlayer_with_angular_21.md +1 -1
- package/docs/zh-TW/introduction.md +0 -1
- package/frequent_questions/ar/claude_code_token_consumption.md +152 -0
- package/frequent_questions/de/claude_code_token_consumption.md +152 -0
- package/frequent_questions/en/claude_code_token_consumption.md +152 -0
- package/frequent_questions/en-GB/claude_code_token_consumption.md +152 -0
- package/frequent_questions/es/claude_code_token_consumption.md +152 -0
- package/frequent_questions/fr/claude_code_token_consumption.md +152 -0
- package/frequent_questions/hi/claude_code_token_consumption.md +152 -0
- package/frequent_questions/id/claude_code_token_consumption.md +152 -0
- package/frequent_questions/it/claude_code_token_consumption.md +152 -0
- package/frequent_questions/ja/claude_code_token_consumption.md +152 -0
- package/frequent_questions/ko/claude_code_token_consumption.md +152 -0
- package/frequent_questions/pl/claude_code_token_consumption.md +152 -0
- package/frequent_questions/pt/claude_code_token_consumption.md +152 -0
- package/frequent_questions/ru/claude_code_token_consumption.md +152 -0
- package/frequent_questions/tr/claude_code_token_consumption.md +152 -0
- package/frequent_questions/uk/claude_code_token_consumption.md +152 -0
- package/frequent_questions/vi/claude_code_token_consumption.md +152 -0
- package/frequent_questions/zh/claude_code_token_consumption.md +152 -0
- package/package.json +8 -7
- package/src/generated/blog.entry.ts +240 -0
- package/src/generated/frequentQuestions.entry.ts +20 -0
- package/blog/en/___per-component_vs_centralized_i18n.md +0 -255
- package/blog/pl/___per-component_vs_centralized_i18n.md +0 -100
- package/docs/en/benchmark/___NOTE.md +0 -101
- package/docs/en/benchmark/___nextjs.md +0 -197
- package/docs/en/benchmark/___solid.md +0 -12
- package/docs/en/benchmark/___svelte.md +0 -16
- package/docs/en/benchmark/___tanstack.md +0 -190
- package/docs/en/benchmark/___vue.md +0 -7
- package/docs/pl/benchmark/___NOTE.md +0 -101
- package/docs/pl/benchmark/___nextjs.md +0 -198
- package/docs/pl/benchmark/___solid.md +0 -36
- package/docs/pl/benchmark/___svelte.md +0 -36
- package/docs/pl/benchmark/___tanstack.md +0 -36
- package/docs/pl/benchmark/___vue.md +0 -36
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-13
|
|
3
|
+
updatedAt: 2026-09-13
|
|
4
|
+
title: "next-intl vs Intlayer: 2026 基准测试与对比"
|
|
5
|
+
description: Bundle 大小、内容泄漏、locale 切换响应性和开发者体验在 Next.js 和 TanStack Start 上的测量。你应该在 2026 年选择哪个 i18n 库?
|
|
6
|
+
keywords:
|
|
7
|
+
- next-intl
|
|
8
|
+
- use-intl
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Internationalization
|
|
11
|
+
- i18n
|
|
12
|
+
- Benchmark
|
|
13
|
+
- Bundle size
|
|
14
|
+
- Blog
|
|
15
|
+
- Next.js
|
|
16
|
+
- TanStack Start
|
|
17
|
+
- JavaScript
|
|
18
|
+
- React
|
|
19
|
+
slugs:
|
|
20
|
+
- blog
|
|
21
|
+
- next-intl-vs-intlayer
|
|
22
|
+
author: aymericzip
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# next-intl VS Intlayer | Next.js 国际化 (i18n) 基准测试
|
|
26
|
+
|
|
27
|
+
`next-intl` 是 Next.js 最流行的 i18n 库。Intlayer 是一个基于编译器、组件作用域的替代方案。两者都可以本地化 App Router 应用程序。问题是应用程序构建后每个库的成本是多少。
|
|
28
|
+
|
|
29
|
+
本文不是教程。这是一个由 [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) 的数据支持的比较,Benchmark Bloom 是一个开源基准测试套件,它使用每个库构建相同的应用程序,并测量浏览器实际下载和执行的内容。
|
|
30
|
+
|
|
31
|
+
<TOC/>
|
|
32
|
+
|
|
33
|
+
> **tl;dr**: 在相同的 Next.js 应用上,`next-intl` 在每个页面上增加 **+12.6 KB gzip** 的 JavaScript,而 Intlayer 仅增加 **+0.3 KB**。无需额外工作,`next-intl` 在每个页面上附带 **~90% 的外语页面字符串**。要通过 `next-intl` 达到 0% 泄漏,需要命名空间作用域和按页面的 `pick(messages, [...])`。Intlayer 默认达到 0%,因为其编译器按组件作用内容。如果你想要 Intlayer 输出的 `next-intl` API,`@intlayer/next-intl` 适配器测得每个页面 **147.5 KB** 对比原始的 **153.6 KB**。
|
|
34
|
+
|
|
35
|
+
## 简而言之
|
|
36
|
+
|
|
37
|
+
- **next-intl** - 轻量级、文档齐全、支持 ICU 消息格式、App Router 第一类支持(含 middleware)、formatters 和 navigation 助手。内容存储在集中式 JSON catalogs 中;性能优化(namespaces、per-page message picking、lazy loading)需要你自己实现。
|
|
38
|
+
- **Intlayer** - 以组件为中心的内容模型。`.content.ts` 字典与服务的组件并置,build-time compiler 对每个组件和每个 locale 进行 tree-shake 和 lazy-load,从你的内容生成严格的 TypeScript 类型,缺失的翻译在 build 时会失败。提供 middleware、SEO 助手、Visual Editor / CMS 和 AI 辅助翻译。
|
|
39
|
+
|
|
40
|
+
| 库 | GitHub Stars | 总提交数 | 最后提交 | 首个版本 | NPM 版本 | NPM 下载量 |
|
|
41
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
42
|
+
| `aymericzip/intlayer` | [](https://github.com/aymericzip/intlayer/stargazers) | [](https://github.com/aymericzip/intlayer/commits) | [](https://github.com/aymericzip/intlayer/commits) | 2024年4月 | [](https://www.npmjs.com/package/intlayer) | [](https://www.npmjs.com/package/intlayer) |
|
|
43
|
+
| `amannn/next-intl` | [](https://github.com/amannn/next-intl/stargazers) | [](https://github.com/amannn/next-intl/commits) | [](https://github.com/amannn/next-intl/commits) | 2020年11月 | [](https://www.npmjs.com/package/next-intl) | [](https://www.npmjs.com/package/next-intl) |
|
|
44
|
+
|
|
45
|
+
> 徽章自动更新。快照会随时间变化。
|
|
46
|
+
|
|
47
|
+
## 并排功能比较
|
|
48
|
+
|
|
49
|
+
| 功能 | `next-intlayer` (Intlayer) | `next-intl` |
|
|
50
|
+
| ----------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
51
|
+
| **组件附近的翻译** | ✅ 是的,`.content.ts` 与每个组件并置 | ❌ 否,集中的 `messages/{locale}.json` |
|
|
52
|
+
| **TypeScript 集成** | ✅ 从内容自动生成的严格类型 | ✅ 良好,通过 `global.d.ts` 增强类型化的键 |
|
|
53
|
+
| **缺失翻译检测** | ✅ TypeScript 错误 + 构建时错误/警告 | ⚠️ 运行时回退 + 控制台警告 |
|
|
54
|
+
| **富内容(JSX / Markdown / 组件)** | ✅ 直接支持 | ⚠️ `t.rich()` / `t.markup()` 配合标签占位符 |
|
|
55
|
+
| **ICU 支持** | ⚠️ 开发中 | ✅ 是 |
|
|
56
|
+
| **格式化(日期、数字、货币)** | ✅ `useNumber`、`useDate` 等(底层使用 Intl) | ✅ `useFormatter()`(底层使用 Intl) |
|
|
57
|
+
| **本地化路由与中间件** | ✅ 内置代理/中间件,`getMultilingualUrls` | ✅ 内置中间件,`Link`,`redirect`,`usePathname` |
|
|
58
|
+
| **SEO 助手(hreflang、sitemap、robots)** | ✅ 内置助手 | ⚠️ 手动配置,基于路由配置 |
|
|
59
|
+
| **同步服务器组件** | ✅ `useIntlayer` 来自 `next-intlayer/server`,适用于任何子服务器组件 | ⚠️ `getTranslations` 是异步的;同步子组件需要通过 props 传递 `t` |
|
|
60
|
+
| **静态渲染** | ✅ 不阻止静态渲染 | ⚠️ 需要 `setRequestLocale()`;命名空间 catalogs 在我们的测试中仍会使页面退出静态渲染 |
|
|
61
|
+
| **Tree-shaking(仅发送使用过的内容)** | ✅ 按组件、按语言,由编译器自动化 | ⚠️ 手动:命名空间 + 每个页面的 `pick(messages, [...])` |
|
|
62
|
+
| **懒加载** | ✅ `importMode: 'dynamic'`(一行配置) | ⚠️ 手动在 `getRequestConfig` 中进行动态导入 |
|
|
63
|
+
| **清除未使用的内容** | ✅ 已过时的字典在构建时被移除 | ❌ 未内置 |
|
|
64
|
+
| **测试缺失的翻译 (CLI / CI)** | ✅ `npx intlayer content test` | ⚠️ 未内置;文档建议使用 `npx @lingual/i18n-check` |
|
|
65
|
+
| **AI 驱动的翻译** | ✅ 内置,使用您自己的提供者密钥 | ❌ 否 |
|
|
66
|
+
| **Visual Editor / CMS** | ✅ 免费可视化编辑器 + 可选 CMS | ❌ 否(外部本地化平台) |
|
|
67
|
+
| **MCP server & Agent Skills** | ✅ 是 | ❌ 否 |
|
|
68
|
+
| **Ecosystem / community** | ⚠️ 较小但增长迅速 | ✅ 大型,Next.js 的参考标准 |
|
|
69
|
+
|
|
70
|
+
## 基准测试
|
|
71
|
+
|
|
72
|
+
### 测量的内容
|
|
73
|
+
|
|
74
|
+
[Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) 套件使用每个库构建**相同的应用程序**:**10 个页面**(首页、关于、博客、职业、联系、常见问题、定价、产品、设置、团队),**10 个语言环境**(`en`、`fr`、`es`、`de`、`it`、`pt`、`zh`、`ja`、`ko`、`ru`),相同的组件和相同的内容。页面在 `en` 和 `fr` 中进行测量。每个库实现了多达四种**加载策略**,从最初的设置到最优的设置:
|
|
75
|
+
|
|
76
|
+
| 策略 | 描述 | 谁在这样做 |
|
|
77
|
+
| ------------------ | ------------------------------------------------------- | --------------------- |
|
|
78
|
+
| **static** | 每个 locale 和每个页面打包在一起 | 快速原型、AI 生成代码 |
|
|
79
|
+
| **dynamic** | 仅加载活跃的 locale,但同时加载所有页面 | 大多数项目 |
|
|
80
|
+
| **scoped-static** | 按路由命名空间,无懒加载 | 罕见 |
|
|
81
|
+
| **scoped-dynamic** | 按路由命名空间 + 懒加载。仅发送当前 locale 中的当前页面 | 性能预算严格的应用 |
|
|
82
|
+
|
|
83
|
+
Intlayer 没有"scoped"变体:编译器会自动按**组件**对内容进行作用域划分,因此其 `static` 和 `dynamic` 行已经是作用域的。
|
|
84
|
+
|
|
85
|
+
对于每次构建,该套件记录:
|
|
86
|
+
|
|
87
|
+
- **Lib size**: 仅导入 i18n 库的空组件的 gzip 大小。运行时的固定成本。
|
|
88
|
+
- **Page JS**: 每个页面下载的 gzip JavaScript,在所有页面和语言环境中平均计算。
|
|
89
|
+
- **Locale leak %**: 下载的 JS 中找到的已翻译字符串中属于用户**未**查看的语言环境的份额(在 `en` 和 `fr` 上进行指纹识别,因此 50% 表示"另一个测量的语言环境完全存在";使用 10 个捆绑的语言环境时,实际浪费更高)。
|
|
90
|
+
- **Page leak %**: 下载的 JS 中找到的已翻译字符串中属于用户**未**浏览的页面的份额。
|
|
91
|
+
- **Component avg**: 各个编译的每个组件的平均 gzip 大小。显示单个组件拖入多少 i18n 运行时。
|
|
92
|
+
- **E2E reactivity**: 选择新locale和`html[lang]`在DOM中更新之间的实时时间(Playwright,5次迭代)。
|
|
93
|
+
- **Hydration**: React hydration阶段持续时间。
|
|
94
|
+
|
|
95
|
+
> 下面的数字来自**2026-09-12**运行,使用`next-intl` 4.14.2、`use-intl` 4.14.2和`intlayer` 9.5.1。测试应用程序故意很小(每个locale只有几十个字符串),所以泄漏百分比描述的是一个**模式**:随着您的内容增长而增长,但运行时成本保持固定。
|
|
96
|
+
|
|
97
|
+
### Next.js (App Router)上的结果
|
|
98
|
+
|
|
99
|
+
| Library | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|
|
100
|
+
| ------------------------------ | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: | --------: |
|
|
101
|
+
| **base** (no i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
102
|
+
| `next-intl` | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
|
|
103
|
+
| `next-intl` | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
|
|
104
|
+
| `next-intl` | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
|
|
105
|
+
| `next-intl` | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
|
|
106
|
+
| **`next-intlayer`** | static | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **8.5 KB** | **15.5 ms** | 16.9 ms |
|
|
107
|
+
| **`next-intlayer`** | dynamic | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **6.9 KB** | **15.3 ms** | 15.9 ms |
|
|
108
|
+
| `@intlayer/next-intl` (compat) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
|
|
109
|
+
| `@intlayer/next-intl` (compat) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
|
|
110
|
+
|
|
111
|
+
**如何阅读**
|
|
112
|
+
|
|
113
|
+
- **运行时成本。** 基础应用程序每页重 141.0 KB。`next-intl` 将其增加到 153.6 KB(**每页额外 +12.6 KB gzip**),Intlayer 增加到 141.3 KB(**额外 +0.3 KB**)。这个差异不取决于你有多少个字符串:它是库运行时的成本。
|
|
114
|
+
- **Leakage.** 在两个最多团队实际使用的设置中(`static` 和 `dynamic`),`next-intl` 会在每个页面上传送 **~90% 的外语页面字符串**:整个 `en.json` 都会进入客户端 provider。要达到 0% 需要使用 `scoped-*` 设置:将目录分割成命名空间,然后在每个页面中 `pick()` 正确的。Intlayer 在两行中都是 0%,无需任何额外配置。
|
|
115
|
+
- **每页面 JS 大小在不同策略间对 `next-intl` 没有变化。** 测试内容很小,所以 ~90% 的泄漏这里只有几 KB。在一个有数百个字符串每页面的真实应用中,这个比例会成为主导成本。同时 +12.6 KB 的 runtime 在每个配置中都会被支付。
|
|
116
|
+
- **组件大小。** 调用 `useTranslations()` 的组件编译到平均 21.8 KB;使用 `useIntlayer()` 的相同组件编译到 6.9 KB。在 `scoped-static` 设置中,`next-intl` 组件跳升到 80.1 KB,因为每个组件都内联其命名空间 catalog。
|
|
117
|
+
- **Reactivity 和 hydration** 在 Next.js 上对两个库都处于相同的范围(15-18 ms)。这里都不是瓶颈。
|
|
118
|
+
|
|
119
|
+
### TanStack Start 上的结果(`use-intl`)
|
|
120
|
+
|
|
121
|
+
`use-intl` 是 `next-intl` 的框架无关核心。相同的 API,相同的消息格式。在 TanStack Start 上将其与 `intlayer` 进行比较,移除了方程的 Next.js 特定部分。
|
|
122
|
+
|
|
123
|
+
| Library | Strategy | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity |
|
|
124
|
+
| ----------------------------- | -------------- | ------------: | ---------------: | ----------: | --------: | -----------------: | -------------: |
|
|
125
|
+
| **base** (no i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms |
|
|
126
|
+
| `use-intl` | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms |
|
|
127
|
+
| `use-intl` | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms |
|
|
128
|
+
| `use-intl` | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms |
|
|
129
|
+
| `use-intl` | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms |
|
|
130
|
+
| **`intlayer`** | static | **5.0 KB** | **125.8 KB** | 50.0% | **0.0%** | **8.1 KB** | **3.2 ms** |
|
|
131
|
+
| **`intlayer`** | dynamic | **5.0 KB** | **118.6 KB** | **0.0%** | **0.0%** | **6.3 KB** | **3.6 ms** |
|
|
132
|
+
| `@intlayer/use-intl` (compat) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
|
|
133
|
+
|
|
134
|
+
**如何阅读**
|
|
135
|
+
|
|
136
|
+
- 朴素的 `use-intl` 设置比基础应用多装载了 **68.8 KB 的 JS**,其中一半的字符串属于错误的语言环境,90% 属于错误的页面。
|
|
137
|
+
- `use-intl` 在 `dynamic` 模式下达到 119.4 KB,接近 Intlayer 的 118.6 KB,但仍然存在 **89.8% 页面泄漏**:活跃 locale 的所有页面字符串都在每个页面加载。按路由作用域划分(`scoped-*`)可以消除泄漏,但需要额外支付约 9 KB 的 chunk 开销。
|
|
138
|
+
- Intlayer 的 `static` 行已经实现 **0% 页面泄漏**:编译器仅打包页面上的组件使用的字典。启用 `importMode: 'dynamic'`(在 `intlayer.config.ts` 中只需一行)也消除了 locale 泄漏。
|
|
139
|
+
- **组件大小是架构的亮点**:使用 `use-intl` 每个组件 76-87 KB,而使用 Intlayer 仅 6-8 KB。`useTranslations()` 将每个组件绑定到全局消息树;`useIntlayer()` 将其绑定到自己的字典。
|
|
140
|
+
- **区域设置切换**使用 Intlayer 快 2-4 倍(3 毫秒 vs 7-21 毫秒)。
|
|
141
|
+
|
|
142
|
+
## 为什么存在差距?集中式目录 vs. 编译的字典
|
|
143
|
+
|
|
144
|
+
`next-intl` 遵循经典模型:每个区域设置一个 JSON,在 `getRequestConfig` 中加载,推送到 `NextIntlClientProvider`,通过 `t("namespace.key")` 读取。
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
.
|
|
148
|
+
├── messages
|
|
149
|
+
│ ├── en.json
|
|
150
|
+
│ └── fr.json
|
|
151
|
+
└── src
|
|
152
|
+
├── i18n
|
|
153
|
+
│ ├── request.ts
|
|
154
|
+
│ └── routing.ts
|
|
155
|
+
├── middleware.ts
|
|
156
|
+
└── app
|
|
157
|
+
└── [locale]
|
|
158
|
+
├── layout.tsx
|
|
159
|
+
└── about
|
|
160
|
+
└── page.tsx
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
运行时无法知道页面将使用哪些 key,因此安全的默认做法是发送整个 catalog。优化意味着**你**需要将 catalog 拆分成 namespace,**你**需要决定每个页面需要哪些 namespace,并且**你**需要在组件移动时保持该映射同步。基准测试中的 `scoped-dynamic` 行是该工作的回报,但大多数团队从未实现过。
|
|
164
|
+
|
|
165
|
+
Intlayer 翻转了这个责任。内容在组件旁边声明:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
.
|
|
169
|
+
├── intlayer.config.ts
|
|
170
|
+
└── src
|
|
171
|
+
├── middleware.ts
|
|
172
|
+
├── app
|
|
173
|
+
│ └── [locale]
|
|
174
|
+
│ ├── layout.tsx
|
|
175
|
+
│ └── about
|
|
176
|
+
│ ├── page.tsx
|
|
177
|
+
│ └── page.content.ts
|
|
178
|
+
└── components
|
|
179
|
+
└── Counter
|
|
180
|
+
├── index.tsx
|
|
181
|
+
└── index.content.ts
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
在构建时,编译器(`@intlayer/swc` / `@intlayer/babel`)会检查哪个组件导入了哪个字典。它只为活跃的语言环境捆绑那些字典,并删除未被导入的字典。"scoped-dynamic"模式成为构建的输出,而不是团队必须维护的纪律。
|
|
185
|
+
|
|
186
|
+
> 要获得 `dynamic` 行的数字,请在 `intlayer.config.ts` 中设置 `dictionary.importMode: 'dynamic'`。请参阅 [bundle 优化文档](https://intlayer.org/doc/concept/bundle-optimization)。
|
|
187
|
+
|
|
188
|
+
## 开发者体验
|
|
189
|
+
|
|
190
|
+
### Client 组件
|
|
191
|
+
|
|
192
|
+
**next-intl**
|
|
193
|
+
|
|
194
|
+
```json fileName="messages/en.json"
|
|
195
|
+
{
|
|
196
|
+
"counter": {
|
|
197
|
+
"label": "Counter",
|
|
198
|
+
"increment": "Increment"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```tsx fileName="src/components/Counter.tsx"
|
|
204
|
+
"use client";
|
|
205
|
+
|
|
206
|
+
import { useState } from "react";
|
|
207
|
+
import { useTranslations, useFormatter } from "next-intl";
|
|
208
|
+
|
|
209
|
+
export const Counter = () => {
|
|
210
|
+
// 使用 useTranslations 获取 counter 命名空间的翻译
|
|
211
|
+
const t = useTranslations("counter");
|
|
212
|
+
// 使用 useFormatter 获取数字格式化工具
|
|
213
|
+
const format = useFormatter();
|
|
214
|
+
const [count, setCount] = useState(0);
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<div>
|
|
218
|
+
<p>{format.number(count)}</p>
|
|
219
|
+
<button aria-label={t("label")} onClick={() => setCount((c) => c + 1)}>
|
|
220
|
+
{t("increment")}
|
|
221
|
+
</button>
|
|
222
|
+
</div>
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
> 记住在渲染此组件的每个页面上,将 `counter` 命名空间包含在传递给 `NextIntlClientProvider` 的消息中。
|
|
228
|
+
|
|
229
|
+
**Intlayer**
|
|
230
|
+
|
|
231
|
+
```ts fileName="src/components/Counter/index.content.ts"
|
|
232
|
+
import { t, type Dictionary } from "intlayer";
|
|
233
|
+
|
|
234
|
+
const counterContent = {
|
|
235
|
+
key: "counter",
|
|
236
|
+
content: {
|
|
237
|
+
label: t({ zh: "计数器", en: "Counter", fr: "Compteur" }),
|
|
238
|
+
increment: t({ zh: "增加", en: "Increment", fr: "Incrémenter" }),
|
|
239
|
+
},
|
|
240
|
+
} satisfies Dictionary;
|
|
241
|
+
|
|
242
|
+
export default counterContent;
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```tsx fileName="src/components/Counter/index.tsx"
|
|
246
|
+
"use client";
|
|
247
|
+
|
|
248
|
+
import { useState } from "react";
|
|
249
|
+
import { useIntlayer } from "next-intlayer";
|
|
250
|
+
import { useNumber } from "next-intlayer/format";
|
|
251
|
+
|
|
252
|
+
export const Counter = () => {
|
|
253
|
+
// 获取国际化内容
|
|
254
|
+
const { label, increment } = useIntlayer("counter");
|
|
255
|
+
// 获取数字格式化工具
|
|
256
|
+
const number = useNumber();
|
|
257
|
+
const [count, setCount] = useState(0);
|
|
258
|
+
|
|
259
|
+
return (
|
|
260
|
+
<div>
|
|
261
|
+
<p>{number(count)}</p>
|
|
262
|
+
<button aria-label={label} onClick={() => setCount((c) => c + 1)}>
|
|
263
|
+
{increment}
|
|
264
|
+
</button>
|
|
265
|
+
</div>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
无需在页面上注册任何内容:该组件包含其自己的内容。
|
|
271
|
+
|
|
272
|
+
### 同步服务器组件
|
|
273
|
+
|
|
274
|
+
设计系统组件(导航栏、页脚、卡片)通常是作为客户端组件的子组件渲染的服务器组件,因此它们不能是 `async`。
|
|
275
|
+
|
|
276
|
+
**next-intl**
|
|
277
|
+
|
|
278
|
+
```tsx fileName="src/components/ServerCounter.tsx"
|
|
279
|
+
type ServerCounterProps = {
|
|
280
|
+
t: (key: string) => string;
|
|
281
|
+
formattedCount: string;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
export const ServerCounter = ({ t, formattedCount }: ServerCounterProps) => (
|
|
285
|
+
<div>
|
|
286
|
+
<p>{formattedCount}</p>
|
|
287
|
+
<button aria-label={t("label")}>{t("increment")}</button>
|
|
288
|
+
</div>
|
|
289
|
+
);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
页面必须 `await getTranslations("counter")` 和 `await getFormatter()`,然后将结果作为 props 向下传递。该组件不再是自包含的。
|
|
293
|
+
|
|
294
|
+
**Intlayer**
|
|
295
|
+
|
|
296
|
+
```tsx fileName="src/components/ServerCounter.tsx"
|
|
297
|
+
import { useIntlayer } from "next-intlayer/server";
|
|
298
|
+
import { useNumber } from "next-intlayer/server/format";
|
|
299
|
+
|
|
300
|
+
export const ServerCounter = ({ count }: { count: number }) => {
|
|
301
|
+
const { label, increment } = useIntlayer("counter");
|
|
302
|
+
const number = useNumber();
|
|
303
|
+
|
|
304
|
+
return (
|
|
305
|
+
<div>
|
|
306
|
+
<p>{number(count)}</p>
|
|
307
|
+
<button aria-label={label}>{increment}</button>
|
|
308
|
+
</div>
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 元数据
|
|
314
|
+
|
|
315
|
+
**next-intl**
|
|
316
|
+
|
|
317
|
+
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
318
|
+
import type { Metadata } from "next";
|
|
319
|
+
import { getTranslations } from "next-intl/server";
|
|
320
|
+
import { routing } from "@/i18n/routing";
|
|
321
|
+
|
|
322
|
+
// 本地化路径函数
|
|
323
|
+
const localizedPath = (locale: string, path: string) =>
|
|
324
|
+
locale === routing.defaultLocale ? path : `/${locale}${path}`;
|
|
325
|
+
|
|
326
|
+
// 生成元数据
|
|
327
|
+
export const generateMetadata = async ({
|
|
328
|
+
params,
|
|
329
|
+
}: {
|
|
330
|
+
params: Promise<{ locale: string }>;
|
|
331
|
+
}): Promise<Metadata> => {
|
|
332
|
+
const { locale } = await params;
|
|
333
|
+
const t = await getTranslations({ locale, namespace: "about" });
|
|
334
|
+
|
|
335
|
+
const languages = Object.fromEntries(
|
|
336
|
+
routing.locales.map((l) => [l, localizedPath(l, "/about")])
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
title: t("title"),
|
|
341
|
+
description: t("description"),
|
|
342
|
+
alternates: {
|
|
343
|
+
canonical: localizedPath(locale, "/about"),
|
|
344
|
+
languages: { ...languages, "x-default": "/about" },
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Intlayer**
|
|
351
|
+
|
|
352
|
+
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
353
|
+
import { getIntlayer, getMultilingualUrls } from "intlayer";
|
|
354
|
+
import type { Metadata } from "next";
|
|
355
|
+
import type { LocalPromiseParams } from "next-intlayer";
|
|
356
|
+
|
|
357
|
+
export const generateMetadata = async ({
|
|
358
|
+
params,
|
|
359
|
+
}: LocalPromiseParams): Promise<Metadata> => {
|
|
360
|
+
const { locale } = await params;
|
|
361
|
+
const metadata = getIntlayer("about-metadata", locale);
|
|
362
|
+
const multilingualUrls = getMultilingualUrls("/about");
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
...metadata,
|
|
366
|
+
alternates: {
|
|
367
|
+
canonical: multilingualUrls[locale as keyof typeof multilingualUrls],
|
|
368
|
+
languages: { ...multilingualUrls, "x-default": "/about" },
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
};
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## 保持 next-intl API,获得 Intlayer 的输出
|
|
375
|
+
|
|
376
|
+
您不必重写组件来获得上述基准数字。`@intlayer/next-intl` 是一个开箱即用的适配器:它保持 `useTranslations`、`getTranslations`、`useFormatter`、`t.rich()`、ICU 复数形式和 `next-intl/navigation` 助手,并从 Intlayer 编译器编译的 Intlayer 字典中提供它们。
|
|
377
|
+
|
|
378
|
+
```ts fileName="next.config.ts"
|
|
379
|
+
import type { NextConfig } from "next";
|
|
380
|
+
ts fileName="next.config.ts"
|
|
381
|
+
import { createNextIntlPlugin } from "@intlayer/next-intl/plugin";
|
|
382
|
+
|
|
383
|
+
const withIntlayer = createNextIntlPlugin();
|
|
384
|
+
|
|
385
|
+
const nextConfig: NextConfig = {};
|
|
386
|
+
|
|
387
|
+
export default withIntlayer(nextConfig);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
在基准测试中,同一应用的兼容性构建从**每页 153.6 KB 降至 147.5 KB**,从**每个组件 21.8 KB 降至 8.1 KB**,以及从**约 90% 的页面泄漏降至 0%**,应用代码保持不变。你现有的 `messages/{locale}.json` 文件可以通过 [JSON 同步插件](https://intlayer.org/doc/compatibility/next-intl)保持作为真实来源。
|
|
391
|
+
|
|
392
|
+
查看 [next-intl 迁移指南](https://intlayer.org/doc/migration/next-intl)获取分步说明。
|
|
393
|
+
|
|
394
|
+
## 何时选择哪个?
|
|
395
|
+
|
|
396
|
+
- **选择 next-intl** 如果你想要 Next.js 生态标准、依赖 ICU MessageFormat、应用规模小到中等,或者你集成了翻译平台(Crowdin、Phrase、Lokalise...)期望集中式 JSON。如果性能重要,需要预留时间来命名空间目录和按页面挑选消息。
|
|
397
|
+
- **选择 Intlayer** 如果你想要**组件作用域内容**、**严格的 TypeScript**、**构建时缺失键错误检测**、**零成本的 tree-shaking 和懒加载**、同步服务器组件,以及内置编辑工具(Visual Editor、CMS、AI 翻译、MCP server)。特别适合大型、模块化的 codebase 和设计系统。
|
|
398
|
+
- **选择 `@intlayer/next-intl`** 如果你已经在使用 `next-intl`,想要获得 bundle 优化而无需重写。
|
|
399
|
+
|
|
400
|
+
## 相关比较
|
|
401
|
+
|
|
402
|
+
- [i18next vs Intlayer](https://intlayer.org/blog/i18next-vs-intlayer) (同一基准测试)
|
|
403
|
+
- [Lingui vs Intlayer](https://intlayer.org/blog/lingui-vs-intlayer) (同一基准测试)
|
|
404
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/blog/vue-i18n-vs-intlayer-benchmark) (同一基准测试)
|
|
405
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
406
|
+
- [Is next-intl outdated?](https://intlayer.org/blog/is-next-intl-outdated)
|
|
407
|
+
|
|
408
|
+
## GitHub Stars
|
|
409
|
+
|
|
410
|
+
GitHub Stars 是项目受欢迎程度、社区信任度和长期相关性的强有力指标。虽然不是技术质量的直接衡量标准,但它们反映了有多少开发者认为该项目有用、关注其进展,以及可能采用它的开发者数量。
|
|
411
|
+
|
|
412
|
+
[](https://star-history.com/#amannn/next-intl&aymericzip/intlayer)
|
|
413
|
+
|
|
414
|
+
## 结论
|
|
415
|
+
|
|
416
|
+
`next-intl` 是一个可靠的、维护良好的库,基准测试证实它远不是 Next.js 上最差的选择。但是它的集中式目录模型将每项优化都交给了开发者:天真的设置会泄漏约 90% 的外语页面内容,而 runtime 本身在每个页面上就花费 +12.6 KB gzip。
|
|
417
|
+
|
|
418
|
+
Intlayer 将这些工作转移到编译器中。按组件字典、按语言环境的懒加载和无用内容清理是构建输出,而不是约定。在同一个应用上的结果:**每页 +0.3 KB**,**0% 泄漏**,组件**小 3 倍**,以及在 TanStack Start 上语言切换**快 2-4 倍**。
|
|
419
|
+
|
|
420
|
+
所有原始数据、测试应用和脚本都在 [Benchmark Bloom 仓库](https://github.com/intlayer-org/benchmark-bloom) 中。自己运行它。
|
|
421
|
+
|
|
422
|
+
有关更多详细信息,请参阅 ['为什么选择 Intlayer?' 文档](https://intlayer.org/doc/why)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-10
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-09-16
|
|
4
4
|
title: 每组件(Per-Component)与集中式(Centralized)i18n:Intlayer 的新方法
|
|
5
5
|
description: 深入探讨 React 国际化策略,对比集中式、按键(per-key)和按组件(per-component)方法,并介绍 Intlayer。
|
|
6
6
|
keywords:
|
|
@@ -63,6 +63,7 @@ extension Localization on String {
|
|
|
63
63
|
- 按键或按组件对内容检索进行细化。
|
|
64
64
|
|
|
65
65
|
</Column>
|
|
66
|
+
|
|
66
67
|
</Columns>
|
|
67
68
|
|
|
68
69
|
> 在本博文中,我不会专注于基于编译器的解决方案,我已经在这里覆盖过:[Compiler vs Declarative i18n](https://github.com/aymericzip/intlayer/blob/main/docs/blog/zh/compiler_vs_declarative_i18n.md).
|
|
@@ -80,6 +81,10 @@ extension Localization on String {
|
|
|
80
81
|
当然,library 的作者们也意识到这些限制并提供了解决方案。
|
|
81
82
|
其中包括:将内容拆分为命名空间、动态加载 JSON 文件(`await import()`),或在构建时剔除内容。
|
|
82
83
|
|
|
84
|
+
下图估算了一个理论应用的内容体积:1 到 10 个页面,翻译成 1 到 10 种语言,每页约 30 KB 文本。按 locale 动态加载内容可消除语言维度,按组件或路由划分内容可消除页面维度,只有两者结合才能让体积保持平稳。
|
|
85
|
+
|
|
86
|
+

|
|
87
|
+
|
|
83
88
|
与此同时,你应该知道,当你动态加载内容时,会向服务器引入额外的请求。每多一个 `useState` 或 hook,就意味着一次额外的服务器请求。
|
|
84
89
|
|
|
85
90
|
> 为了解决这一点,Intlayer 建议将多个内容定义分组到同一个键下,Intlayer 会合并这些内容。
|
|
@@ -112,9 +117,9 @@ extension Localization on String {
|
|
|
112
117
|
|
|
113
118
|
第一个示例没有为每个 locale 进行懒加载翻译,也没有进行命名空间拆分。第二个示例则包含内容清理(purging)和翻译的动态加载。
|
|
114
119
|
|
|
115
|
-
| 已优化的 bundle
|
|
116
|
-
|
|
|
117
|
-
|  |  |
|
|
118
123
|
|
|
119
124
|
因此,多亏了 namespaces,我们将结构从以下形式迁移:
|
|
120
125
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-01-02
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-09-16
|
|
4
4
|
title: react-i18next vs react-intl vs Intlayer
|
|
5
5
|
description: 将 react-i18next 与 next-intl 和 Intlayer 集成,用于 React 应用的国际化 (i18n)
|
|
6
6
|
keywords:
|
|
@@ -106,6 +106,10 @@ author: aymericzip
|
|
|
106
106
|
|
|
107
107
|
**重要性说明:** 更小的包体积和更少的未使用字符串能提升启动和导航性能。
|
|
108
108
|
|
|
109
|
+
下图估算了一个理论应用的内容体积:1 到 10 个页面,翻译成 1 到 10 种语言,每页约 30 KB 文本。按 locale 动态加载内容可消除语言维度,按组件或路由划分内容可消除页面维度,只有两者结合才能让体积保持平稳。
|
|
110
|
+
|
|
111
|
+

|
|
112
|
+
|
|
109
113
|
### 6) 开发体验(DX)、工具链与维护
|
|
110
114
|
|
|
111
115
|
- **react-intl / react-i18next**:拥有广泛的社区生态系统;对于编辑工作流,通常采用外部本地化平台。
|
|
@@ -130,7 +134,7 @@ author: aymericzip
|
|
|
130
134
|
|
|
131
135
|
GitHub stars 是项目受欢迎程度、社区信任度和长期相关性的强有力指标。虽然不是技术质量的直接衡量标准,但它们反映了有多少开发者认为该项目有用、关注其进展,以及可能会采用它。对于评估项目价值,stars 有助于比较不同替代方案的吸引力,并提供对生态系统增长的洞察。
|
|
132
136
|
|
|
133
|
-
[](https://
|
|
137
|
+
[](https://star-history.com/#formatjs/formatjs&i18next/react-i18next&aymericzip/intlayer)
|
|
134
138
|
|
|
135
139
|
## 结论
|
|
136
140
|
|