@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,397 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-13
|
|
3
|
+
updatedAt: 2026-09-13
|
|
4
|
+
title: "next-intl vs Intlayer: Điểm chuẩn & So sánh 2026"
|
|
5
|
+
description: "So sánh chi tiết giữa next-intl và Intlayer trên Next.js App Router và TanStack Start. Kích thước bundle, rò rỉ nội dung, kích thước component, hydrate và trải nghiệm lập trình viên."
|
|
6
|
+
keywords:
|
|
7
|
+
- next-intl
|
|
8
|
+
- use-intl
|
|
9
|
+
- Intlayer
|
|
10
|
+
- Internationalization
|
|
11
|
+
- i18n
|
|
12
|
+
- Benchmark
|
|
13
|
+
- Bundle size
|
|
14
|
+
- Next.js
|
|
15
|
+
- TanStack Start
|
|
16
|
+
- React
|
|
17
|
+
slugs:
|
|
18
|
+
- blog
|
|
19
|
+
- next-intl-vs-intlayer
|
|
20
|
+
author: aymericzip
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# next-intl VS Intlayer | Điểm chuẩn quốc tế hóa (i18n) trên React & Next.js
|
|
24
|
+
|
|
25
|
+
`next-intl` là lựa chọn mặc định cho i18n trên Next.js App Router hiện nay: tích hợp chặt chẽ với định tuyến, hỗ trợ đầy đủ ICU MessageFormat, và trải nghiệm lập trình quen thuộc với bất kỳ ai từng sử dụng các hệ thống i18n truyền thống.
|
|
26
|
+
|
|
27
|
+
`Intlayer` tiếp cận vấn đề theo một hướng hoàn toàn mới: không có từ điển tập trung, không cần khớp nối thủ công giữa namespace và route. Nội dung được khai báo ngay cạnh từng component, và trình biên dịch tại thời điểm build sẽ chỉ đóng gói đúng những gì trang đó thực sự cần.
|
|
28
|
+
|
|
29
|
+
Bài viết này so sánh cả hai thư viện dựa trên dữ liệu từ [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom), một bộ kiểm thử mã nguồn mở xây dựng cùng một ứng dụng với mỗi thư viện và ghi lại những gì trình duyệt thực sự tải xuống và thực thi.
|
|
30
|
+
|
|
31
|
+
<TOC/>
|
|
32
|
+
|
|
33
|
+
> **Tóm tắt (tl;dr)**: `next-intl` làm tăng ít nhất **+12.6 KB gzip** trên mỗi trang chỉ riêng cho runtime của nó, và làm rò rỉ **~90% chuỗi ký tự của các trang khác** trong các cấu hình tiêu chuẩn (`static` và `dynamic`). Để loại bỏ sự rò rỉ đó, lập trình viên phải chia nhỏ danh mục thành các namespace và chọn thủ công cho từng trang. Ngược lại, trình biên dịch của `Intlayer` đảm bảo **0% rò rỉ**, component **nhỏ hơn gấp 3 lần**, và chỉ tốn thêm **+0.3 KB** so với ứng dụng gốc mà không cần cấu hình phức tạp.
|
|
34
|
+
|
|
35
|
+
## Tóm lược
|
|
36
|
+
|
|
37
|
+
- **next-intl** - Tiêu chuẩn cộng đồng của Next.js. Các từ điển JSON tập trung cho từng ngôn ngữ, hỗ trợ đầy đủ định dạng ICU MessageFormat, tích hợp sâu vào quy trình xử lý request và định tuyến của Next.js.
|
|
38
|
+
- **Intlayer** - Mô hình nội dung lấy component làm trung tâm. Các tệp `.content.ts` đặt ngay cạnh component, trình biên dịch thực hiện tree-shaking và tải lười (lazy loading) theo component và ngôn ngữ, tự động tạo các kiểu TypeScript nghiêm ngặt.
|
|
39
|
+
|
|
40
|
+
| Thư viện | Ngôi sao GitHub | Tổng số commit | Commit cuối | Phiên bản đầu | Phiên bản NPM | Lượt tải NPM |
|
|
41
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
42
|
+
| `aymericzip/intlayer` | [](https://github.com/aymericzip/intlayer/stargazers) | [](https://github.com/aymericzip/intlayer/commits) | [](https://github.com/aymericzip/intlayer/commits) | Tháng 4 2024 | [](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) | Tháng 3 2021 | [](https://www.npmjs.com/package/next-intl) | [](https://www.npmjs.com/package/next-intl) |
|
|
44
|
+
|
|
45
|
+
> Huy hiệu được cập nhật tự động.
|
|
46
|
+
|
|
47
|
+
## So sánh tính năng chi tiết
|
|
48
|
+
|
|
49
|
+
| Tính năng | Intlayer (`react-intlayer` / `next-intlayer`) | next-intl (`next-intl` / `use-intl`) |
|
|
50
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
|
51
|
+
| **Bản dịch đặt cạnh component** | ✅ Có, `.content.ts` đặt ngay cạnh component | ❌ Các từ điển JSON tập trung trong thư mục `messages/` |
|
|
52
|
+
| **Tích hợp TypeScript** | ✅ Kiểu nghiêm ngặt được tạo tự động từ nội dung | ⚠️ Hỗ trợ thông qua cấu hình thủ công `global.d.ts` |
|
|
53
|
+
| **Phát hiện bản dịch còn thiếu** | ✅ Lỗi TypeScript + lỗi/cảnh báo tại thời điểm build | ⚠️ Runtime trả về key hoặc báo lỗi tùy thuộc vào cấu hình |
|
|
54
|
+
| **Nội dung phong phú (JSX / Markdown / component)** | ✅ Hỗ trợ trực tiếp | ⚠️ Thông qua `t.rich()` với việc truyền các component ánh xạ |
|
|
55
|
+
| **Hỗ trợ ICU MessageFormat** | ⚠️ Đang phát triển | ✅ Có, hỗ trợ đầy đủ tiêu chuẩn ICU |
|
|
56
|
+
| **Component server đồng bộ** | ✅ `useIntlayer` từ `next-intlayer/server` hoạt động trong component server con | ❌ Cần truyền bản dịch qua props từ component cha bất đồng bộ |
|
|
57
|
+
| **Tree-shaking** | ✅ Tự động cho từng component và từng ngôn ngữ | ⚠️ Đòi hỏi phải chia nhỏ namespace thủ công và sử dụng `pick()` |
|
|
58
|
+
| **Tải lười (Lazy loading)** | ✅ Một dòng cấu hình (`importMode: 'dynamic'`) | ⚠️ Yêu cầu import động thủ công trong `getRequestConfig` |
|
|
59
|
+
| **Trình chỉnh sửa trực quan / CMS** | ✅ Trình chỉnh sửa trực quan miễn phí + CMS tùy chọn | ❌ Không có |
|
|
60
|
+
| **Dịch thuật bằng AI** | ✅ Tích hợp sẵn, sử dụng API key của riêng bạn | ❌ Không có |
|
|
61
|
+
| **Máy chủ MCP & Kỹ năng Agent** | ✅ Có | ❌ Không có |
|
|
62
|
+
|
|
63
|
+
## Bài kiểm tra điểm chuẩn
|
|
64
|
+
|
|
65
|
+
### Những gì đã được đo lường
|
|
66
|
+
|
|
67
|
+
Bộ thử nghiệm [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) xây dựng **cùng một ứng dụng** với mỗi thư viện: **10 trang** (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), **10 ngôn ngữ** (`en`, `fr`, `es`, `de`, `it`, `pt`, `zh`, `ja`, `ko`, `ru`), component giống hệt nhau và nội dung giống hệt nhau. Các trang được đo lường bằng `en` và `fr`. Mỗi thư viện được thử nghiệm theo bốn **chiến lược tải**:
|
|
68
|
+
|
|
69
|
+
| Chiến lược | Mô tả | Đối tượng sử dụng |
|
|
70
|
+
| ------------------ | ------------------------------------------------------------------------------------- | ------------------------------------------ |
|
|
71
|
+
| **static** | Tất cả ngôn ngữ và trang được đóng gói cùng nhau từ đầu | Bản dựng thử nghiệm nhanh, mã do AI tạo |
|
|
72
|
+
| **dynamic** | Chỉ ngôn ngữ đang hoạt động được tải, nhưng bao gồm tất cả các trang | Đa số các dự án |
|
|
73
|
+
| **scoped-static** | Phân chia namespace theo route, không dùng lazy loading | Hiếm gặp |
|
|
74
|
+
| **scoped-dynamic** | Namespace theo route + lazy loading. Chỉ trang hiện tại và ngôn ngữ hiện tại được gửi | Các ứng dụng có yêu cầu hiệu năng khắt khe |
|
|
75
|
+
|
|
76
|
+
Intlayer không có biến thể "scoped": trình biên dịch tự động thu hẹp phạm vi nội dung **theo từng component**, do đó các hàng `static` và `dynamic` vốn đã được tối ưu hóa phạm vi.
|
|
77
|
+
|
|
78
|
+
Bộ công cụ ghi lại:
|
|
79
|
+
|
|
80
|
+
- **Kích thước thư viện (Lib size)**: kích thước gzip của component trống chỉ import thư viện i18n.
|
|
81
|
+
- **JS trang (Page JS)**: dung lượng JavaScript gzip tải về trên mỗi trang.
|
|
82
|
+
- **% rò rỉ ngôn ngữ (Locale leak %)**: tỷ lệ chuỗi thuộc về ngôn ngữ mà người dùng không xem.
|
|
83
|
+
- **% rò rỉ trang (Page leak %)**: tỷ lệ chuỗi thuộc về trang mà người dùng không truy cập.
|
|
84
|
+
- **Trung bình component (Component avg)**: kích thước gzip trung bình của mỗi component khi được biên dịch riêng lẻ.
|
|
85
|
+
- **Độ phản hồi E2E**: thời gian từ khi chọn ngôn ngữ mới đến khi DOM cập nhật `html[lang]`.
|
|
86
|
+
- **Hydrate (Hydration)**: thời lượng của giai đoạn hydrate trong React.
|
|
87
|
+
|
|
88
|
+
> Dữ liệu dưới đây được lấy từ lần chạy ngày **2026-09-12** với `next-intl` 4.14.2 và `intlayer` 9.5.1.
|
|
89
|
+
|
|
90
|
+
### Kết quả trên Next.js (App Router)
|
|
91
|
+
|
|
92
|
+
| Thư viện | Chiến lược | Kích thước Lib (gz) | JS trang TB (gz) | Rò rỉ ngôn ngữ | Rò rỉ trang | TB component (gz) | Độ phản hồi E2E | Hydrate |
|
|
93
|
+
| ----------------------------------- | -------------- | ------------------: | ---------------: | -------------: | ----------: | ----------------: | --------------: | ------: |
|
|
94
|
+
| **Ứng dụng gốc** (không i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
95
|
+
| `next-intl` | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
|
|
96
|
+
| `next-intl` | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
|
|
97
|
+
| `next-intl` | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
|
|
98
|
+
| `next-intl` | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
|
|
99
|
+
| **`next-intlayer`** | static | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **8.5 KB** | **15.5 ms** | 16.9 ms |
|
|
100
|
+
| **`next-intlayer`** | dynamic | **5.5 KB** | **141.3 KB** | **0.0%** | **0.0%** | **6.9 KB** | **15.3 ms** | 15.9 ms |
|
|
101
|
+
| `@intlayer/next-intl` (tương thích) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
|
|
102
|
+
| `@intlayer/next-intl` (tương thích) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
|
|
103
|
+
|
|
104
|
+
**Cách đọc kết quả**
|
|
105
|
+
|
|
106
|
+
- **Chi phí runtime.** Ứng dụng gốc nặng 141.0 KB trên mỗi trang. `next-intl` tăng lên 153.6 KB (**+12.6 KB gzip trên mỗi trang**), trong khi Intlayer chỉ tốn 141.3 KB (**+0.3 KB**).
|
|
107
|
+
- **Rò rỉ nội dung.** Trong các cấu hình phổ biến (`static` và `dynamic`), `next-intl` gửi **~90% chuỗi của các trang khác** trên mỗi trang vì toàn bộ tệp `en.json` được đưa vào client provider. Để đạt mức 0% đòi hỏi phải chia tách thủ công rất tỉ mỉ, trong khi Intlayer đạt được điều này mặc định.
|
|
108
|
+
- **Kích thước component.** Một component gọi `useTranslations()` có dung lượng trung bình 21.8 KB; cùng component đó với `useIntlayer()` chỉ nặng 6.9 KB.
|
|
109
|
+
|
|
110
|
+
### Kết quả trên TanStack Start (`use-intl`)
|
|
111
|
+
|
|
112
|
+
| Thư viện | Chiến lược | Kích thước Lib (gz) | JS trang TB (gz) | Rò rỉ ngôn ngữ | Rò rỉ trang | TB component (gz) | Độ phản hồi E2E |
|
|
113
|
+
| ---------------------------------- | -------------- | ------------------: | ---------------: | -------------: | ----------: | ----------------: | --------------: |
|
|
114
|
+
| **Ứng dụng gốc** (không i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms |
|
|
115
|
+
| `use-intl` | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms |
|
|
116
|
+
| `use-intl` | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms |
|
|
117
|
+
| `use-intl` | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms |
|
|
118
|
+
| `use-intl` | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms |
|
|
119
|
+
| **`intlayer`** | static | **5.0 KB** | **125.8 KB** | 50.0% | **0.0%** | **8.1 KB** | **3.2 ms** |
|
|
120
|
+
| **`intlayer`** | dynamic | **5.0 KB** | **118.6 KB** | **0.0%** | **0.0%** | **6.3 KB** | **3.6 ms** |
|
|
121
|
+
| `@intlayer/use-intl` (tương thích) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
|
|
122
|
+
|
|
123
|
+
**Cách đọc kết quả**
|
|
124
|
+
|
|
125
|
+
- Cấu hình đơn giản của `use-intl` gửi **nhiều hơn 68.8 KB JS trên mỗi trang** so với ứng dụng gốc.
|
|
126
|
+
- Ở chế độ `dynamic`, `use-intl` đạt mức 119.4 KB nhưng vẫn có **89.8% rò rỉ trang**.
|
|
127
|
+
- Sự khác biệt về mặt kiến trúc thể hiện rất rõ ở **kích thước component**: 76-87 KB với `use-intl` so với 6-8 KB với Intlayer.
|
|
128
|
+
- **Chuyển đổi ngôn ngữ** nhanh hơn từ 2 đến 4 lần với Intlayer (3 ms so với 7-21 ms).
|
|
129
|
+
|
|
130
|
+
## Tại sao lại có sự khác biệt? Danh mục tập trung vs từ điển biên dịch
|
|
131
|
+
|
|
132
|
+
`next-intl` tuân theo mô hình cổ điển: một tệp JSON cho mỗi ngôn ngữ, được nạp trong `getRequestConfig`, chuyển vào `NextIntlClientProvider` và đọc qua cú pháp `t("namespace.key")`.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
.
|
|
136
|
+
├── messages
|
|
137
|
+
│ ├── en.json
|
|
138
|
+
│ └── fr.json
|
|
139
|
+
└── src
|
|
140
|
+
├── i18n
|
|
141
|
+
│ ├── request.ts
|
|
142
|
+
│ └── routing.ts
|
|
143
|
+
├── middleware.ts
|
|
144
|
+
└── app
|
|
145
|
+
└── [locale]
|
|
146
|
+
├── layout.tsx
|
|
147
|
+
└── about
|
|
148
|
+
└── page.tsx
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Runtime không thể biết trước những key nào sẽ được trang sử dụng, vì vậy việc gửi toàn bộ danh mục là giải pháp an toàn duy nhất.
|
|
152
|
+
|
|
153
|
+
Intlayer đảo ngược hoàn toàn quy trình này. Nội dung được khai báo trực tiếp cạnh component:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
.
|
|
157
|
+
├── intlayer.config.ts
|
|
158
|
+
└── src
|
|
159
|
+
├── middleware.ts
|
|
160
|
+
└── app
|
|
161
|
+
└── [locale]
|
|
162
|
+
├── layout.tsx
|
|
163
|
+
└── about
|
|
164
|
+
├── page.tsx
|
|
165
|
+
└── page.content.ts
|
|
166
|
+
└── components
|
|
167
|
+
└── Counter
|
|
168
|
+
├── index.tsx
|
|
169
|
+
└── index.content.ts
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Tại thời điểm build, trình biên dịch nhận biết component nào import từ điển nào và chỉ đóng gói những từ điển cần thiết cho ngôn ngữ đang hoạt động.
|
|
173
|
+
|
|
174
|
+
> Để có được các số liệu của hàng `dynamic`, hãy đặt `dictionary.importMode: 'dynamic'` trong `intlayer.config.ts`. Xem thêm [tài liệu tối ưu hóa bundle](https://intlayer.org/vi/doc/concept/bundle-optimization).
|
|
175
|
+
|
|
176
|
+
## Trải nghiệm lập trình viên
|
|
177
|
+
|
|
178
|
+
### Client component
|
|
179
|
+
|
|
180
|
+
**next-intl**
|
|
181
|
+
|
|
182
|
+
```json fileName="messages/en.json"
|
|
183
|
+
{
|
|
184
|
+
"counter": {
|
|
185
|
+
"label": "Counter",
|
|
186
|
+
"increment": "Increment"
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```tsx fileName="src/components/Counter.tsx"
|
|
192
|
+
"use client";
|
|
193
|
+
|
|
194
|
+
import { useState } from "react";
|
|
195
|
+
import { useTranslations, useFormatter } from "next-intl";
|
|
196
|
+
|
|
197
|
+
export const Counter = () => {
|
|
198
|
+
const t = useTranslations("counter");
|
|
199
|
+
const format = useFormatter();
|
|
200
|
+
const [count, setCount] = useState(0);
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<div>
|
|
204
|
+
<p>{format.number(count)}</p>
|
|
205
|
+
<button aria-label={t("label")} onClick={() => setCount((c) => c + 1)}>
|
|
206
|
+
{t("increment")}
|
|
207
|
+
</button>
|
|
208
|
+
</div>
|
|
209
|
+
);
|
|
210
|
+
};
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Intlayer**
|
|
214
|
+
|
|
215
|
+
```ts fileName="src/components/Counter/index.content.ts"
|
|
216
|
+
import { t, type Dictionary } from "intlayer";
|
|
217
|
+
|
|
218
|
+
const counterContent = {
|
|
219
|
+
key: "counter",
|
|
220
|
+
content: {
|
|
221
|
+
label: t({ en: "Counter", fr: "Compteur" }),
|
|
222
|
+
increment: t({ en: "Increment", fr: "Incrémenter" }),
|
|
223
|
+
},
|
|
224
|
+
} satisfies Dictionary;
|
|
225
|
+
|
|
226
|
+
export default counterContent;
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```tsx fileName="src/components/Counter/index.tsx"
|
|
230
|
+
"use client";
|
|
231
|
+
|
|
232
|
+
import { useState } from "react";
|
|
233
|
+
import { useIntlayer } from "next-intlayer";
|
|
234
|
+
import { useNumber } from "next-intlayer/format";
|
|
235
|
+
|
|
236
|
+
export const Counter = () => {
|
|
237
|
+
const { label, increment } = useIntlayer("counter");
|
|
238
|
+
const number = useNumber();
|
|
239
|
+
const [count, setCount] = useState(0);
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div>
|
|
243
|
+
<p>{number(count)}</p>
|
|
244
|
+
<button aria-label={label} onClick={() => setCount((c) => c + 1)}>
|
|
245
|
+
{increment}
|
|
246
|
+
</button>
|
|
247
|
+
</div>
|
|
248
|
+
);
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Component server đồng bộ
|
|
253
|
+
|
|
254
|
+
Các thành phần giao diện chung (navbar, footer, thẻ) thường là các component server được kết xuất dưới dạng con của component client, do đó chúng không thể là `async`.
|
|
255
|
+
|
|
256
|
+
**next-intl**
|
|
257
|
+
|
|
258
|
+
```tsx fileName="src/components/ServerCounter.tsx"
|
|
259
|
+
type ServerCounterProps = {
|
|
260
|
+
t: (key: string) => string;
|
|
261
|
+
formattedCount: string;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export const ServerCounter = ({ t, formattedCount }: ServerCounterProps) => (
|
|
265
|
+
<div>
|
|
266
|
+
<p>{formattedCount}</p>
|
|
267
|
+
<button aria-label={t("label")}>{t("increment")}</button>
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Intlayer**
|
|
273
|
+
|
|
274
|
+
```tsx fileName="src/components/ServerCounter.tsx"
|
|
275
|
+
import { useIntlayer } from "next-intlayer/server";
|
|
276
|
+
import { useNumber } from "next-intlayer/server/format";
|
|
277
|
+
|
|
278
|
+
export const ServerCounter = ({ count }: { count: number }) => {
|
|
279
|
+
const { label, increment } = useIntlayer("counter");
|
|
280
|
+
const number = useNumber();
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<div>
|
|
284
|
+
<p>{number(count)}</p>
|
|
285
|
+
<button aria-label={label}>{increment}</button>
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
};
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Metadata
|
|
292
|
+
|
|
293
|
+
**next-intl**
|
|
294
|
+
|
|
295
|
+
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
296
|
+
import type { Metadata } from "next";
|
|
297
|
+
import { getTranslations } from "next-intl/server";
|
|
298
|
+
import { routing } from "@/i18n/routing";
|
|
299
|
+
|
|
300
|
+
const localizedPath = (locale: string, path: string) =>
|
|
301
|
+
locale === routing.defaultLocale ? path : `/${locale}${path}`;
|
|
302
|
+
|
|
303
|
+
export const generateMetadata = async ({
|
|
304
|
+
params,
|
|
305
|
+
}: {
|
|
306
|
+
params: Promise<{ locale: string }>;
|
|
307
|
+
}): Promise<Metadata> => {
|
|
308
|
+
const { locale } = await params;
|
|
309
|
+
const t = await getTranslations({ locale, namespace: "about" });
|
|
310
|
+
|
|
311
|
+
const languages = Object.fromEntries(
|
|
312
|
+
routing.locales.map((l) => [l, localizedPath(l, "/about")])
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
title: t("title"),
|
|
317
|
+
description: t("description"),
|
|
318
|
+
alternates: {
|
|
319
|
+
canonical: localizedPath(locale, "/about"),
|
|
320
|
+
languages: { ...languages, "x-default": "/about" },
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Intlayer**
|
|
327
|
+
|
|
328
|
+
```tsx fileName="src/app/[locale]/about/page.tsx"
|
|
329
|
+
import { getIntlayer, getMultilingualUrls } from "intlayer";
|
|
330
|
+
import type { Metadata } from "next";
|
|
331
|
+
import type { LocalPromiseParams } from "next-intlayer";
|
|
332
|
+
|
|
333
|
+
export const generateMetadata = async ({
|
|
334
|
+
params,
|
|
335
|
+
}: LocalPromiseParams): Promise<Metadata> => {
|
|
336
|
+
const { locale } = await params;
|
|
337
|
+
const metadata = getIntlayer("about-metadata", locale);
|
|
338
|
+
const multilingualUrls = getMultilingualUrls("/about");
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
...metadata,
|
|
342
|
+
alternates: {
|
|
343
|
+
canonical: multilingualUrls[locale as keyof typeof multilingualUrls],
|
|
344
|
+
languages: { ...multilingualUrls, "x-default": "/about" },
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Giữ lại API next-intl, tận dụng hiệu năng Intlayer
|
|
351
|
+
|
|
352
|
+
Bạn không cần viết lại toàn bộ component để có được kết quả hiệu năng vượt trội như trên. Gói `@intlayer/next-intl` là một adapter tương thích trực tiếp: nó giữ lại `useTranslations`, `getTranslations`, `useFormatter`, `t.rich()` và các dạng số nhiều ICU, đồng thời phân phối chúng từ các từ điển Intlayer được biên dịch bởi trình biên dịch Intlayer.
|
|
353
|
+
|
|
354
|
+
```ts fileName="next.config.ts"
|
|
355
|
+
import type { NextConfig } from "next";
|
|
356
|
+
import { createNextIntlPlugin } from "@intlayer/next-intl/plugin";
|
|
357
|
+
|
|
358
|
+
const withIntlayer = createNextIntlPlugin();
|
|
359
|
+
|
|
360
|
+
const nextConfig: NextConfig = {};
|
|
361
|
+
|
|
362
|
+
export default withIntlayer(nextConfig);
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Trong bài đánh giá, bản build tương thích của cùng ứng dụng đã giảm từ **153.6 KB xuống 147.5 KB** mỗi trang, kích thước component giảm từ **21.8 KB xuống 8.1 KB**, và rò rỉ trang giảm từ **~90% xuống 0%** mà không cần sửa đổi mã ứng dụng. Các tệp `messages/{locale}.json` hiện tại của bạn vẫn có thể đóng vai trò là nguồn dữ liệu chuẩn thông qua [plugin đồng bộ JSON](https://intlayer.org/vi/doc/compatibility/next-intl).
|
|
366
|
+
|
|
367
|
+
Xem thêm [hướng dẫn chuyển đổi next-intl](https://intlayer.org/vi/doc/migration/next-intl) để biết các bước chi tiết.
|
|
368
|
+
|
|
369
|
+
## Khi nào nên chọn thư viện nào?
|
|
370
|
+
|
|
371
|
+
- **Chọn next-intl** nếu bạn muốn tiêu chuẩn phổ biến trong cộng đồng Next.js, phụ thuộc nhiều vào ICU MessageFormat, ứng dụng có quy mô vừa và nhỏ, hoặc đang tích hợp với các nền tảng dịch thuật tập trung (Crowdin, Phrase, Lokalise...).
|
|
372
|
+
- **Chọn Intlayer** nếu bạn muốn **nội dung theo phạm vi component**, **TypeScript nghiêm ngặt**, **báo lỗi thiếu khóa ngay khi build**, **tự động tree-shaking và lazy loading không cần cấu hình**, component server đồng bộ, và bộ công cụ chỉnh sửa tích hợp sẵn (Visual Editor, CMS, dịch thuật AI, máy chủ MCP).
|
|
373
|
+
- **Chọn `@intlayer/next-intl`** nếu bạn đã dùng `next-intl` và muốn tối ưu dung lượng bundle mà không cần viết lại mã nguồn.
|
|
374
|
+
|
|
375
|
+
## So sánh liên quan
|
|
376
|
+
|
|
377
|
+
- [i18next vs Intlayer](https://intlayer.org/vi/blog/i18next-vs-intlayer) (cùng bài kiểm tra)
|
|
378
|
+
- [Lingui vs Intlayer](https://intlayer.org/vi/blog/lingui-vs-intlayer) (cùng bài kiểm tra)
|
|
379
|
+
- [Điểm chuẩn vue-i18n vs Intlayer](https://intlayer.org/vi/blog/vue-i18n-vs-intlayer-benchmark) (cùng bài kiểm tra)
|
|
380
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/vi/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
381
|
+
- [next-intl có lỗi thời không?](https://intlayer.org/vi/blog/is-next-intl-outdated)
|
|
382
|
+
|
|
383
|
+
## Ngôi sao GitHub
|
|
384
|
+
|
|
385
|
+
Số sao GitHub là một thước đo rõ ràng về mức độ phổ biến, sự tin cậy của cộng đồng và tính bền vững lâu dài của dự án.
|
|
386
|
+
|
|
387
|
+
[](https://star-history.com/#amannn/next-intl&aymericzip/intlayer)
|
|
388
|
+
|
|
389
|
+
## Kết luận
|
|
390
|
+
|
|
391
|
+
`next-intl` là một thư viện ổn định và được duy trì tốt trên Next.js. Tuy nhiên, mô hình danh mục tập trung đặt toàn bộ gánh nặng tối ưu hóa lên vai lập trình viên: cấu hình thông thường làm rò rỉ khoảng 90% nội dung của các trang khác, và bản thân runtime đã tốn thêm +12.6 KB gzip trên mỗi trang.
|
|
392
|
+
|
|
393
|
+
Intlayer chuyển toàn bộ công việc đó sang trình biên dịch. Từ điển theo component, tải lười theo ngôn ngữ và loại bỏ nội dung không sử dụng trở thành kết quả build tự động. Kết quả trên cùng ứng dụng: **+0.3 KB mỗi trang**, **0% rò rỉ**, component **nhỏ hơn gấp 3 lần**, và chuyển đổi ngôn ngữ **nhanh hơn 2 đến 4 lần** trên TanStack Start.
|
|
394
|
+
|
|
395
|
+
Toàn bộ dữ liệu thô, ứng dụng thử nghiệm và mã script đều có sẵn tại [kho lưu trữ Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom).
|
|
396
|
+
|
|
397
|
+
Xem thêm tài liệu ['Tại sao chọn Intlayer?'](https://intlayer.org/vi/doc/why) để biết thêm chi tiết.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-09-10
|
|
3
|
-
updatedAt:
|
|
3
|
+
updatedAt: 2026-09-16
|
|
4
4
|
title: "i18n theo thành phần so với i18n tập trung: Một cách tiếp cận mới với Intlayer"
|
|
5
5
|
description: Phân tích sâu các chiến lược quốc tế hóa trong React, so sánh các phương pháp tập trung, theo khóa và theo thành phần, và giới thiệu Intlayer.
|
|
6
6
|
keywords:
|
|
@@ -63,6 +63,7 @@ Tuy nhiên, trong thế giới React, chúng ta chủ yếu thấy các cách ti
|
|
|
63
63
|
- phân nhỏ việc truy xuất nội dung theo key, hoặc theo component.
|
|
64
64
|
|
|
65
65
|
</Column>
|
|
66
|
+
|
|
66
67
|
</Columns>
|
|
67
68
|
|
|
68
69
|
> Trong blog này, tôi sẽ không tập trung vào các giải pháp dựa trên compiler, những cái tôi đã đề cập ở đây: [Compiler vs Declarative i18n](https://github.com/aymericzip/intlayer/blob/main/docs/blog/vi/compiler_vs_declarative_i18n.md).
|
|
@@ -79,6 +80,10 @@ So, broadly speaking, the decision breaks down like this:
|
|
|
79
80
|
|
|
80
81
|
Tất nhiên, các tác giả thư viện nhận thức được những giới hạn này và cung cấp các cách khắc phục. Trong số đó: tách thành namespaces, tải động các file JSON (`await import()`), hoặc loại bỏ (purge) nội dung trong quá trình build.
|
|
81
82
|
|
|
83
|
+
Biểu đồ dưới đây ước tính dung lượng nội dung cho một ứng dụng giả định gồm 1 đến 10 trang, được dịch sang 1 đến 10 ngôn ngữ, với khoảng 30 KB văn bản mỗi trang. Tải nội dung động theo locale loại bỏ trục ngôn ngữ, giới hạn nội dung theo component hoặc route loại bỏ trục trang, và chỉ khi kết hợp cả hai thì dung lượng mới giữ nguyên.
|
|
84
|
+
|
|
85
|
+

|
|
86
|
+
|
|
82
87
|
Đồng thời, bạn cần biết rằng khi bạn tải nội dung một cách động, bạn sẽ tạo thêm các yêu cầu tới server. Mỗi `useState` bổ sung hoặc hook đồng nghĩa với một yêu cầu server thêm.
|
|
83
88
|
|
|
84
89
|
> Để khắc phục vấn đề này, Intlayer đề xuất gom nhiều định nghĩa nội dung dưới cùng một khóa; Intlayer sau đó sẽ hợp nhất những nội dung đó.
|
|
@@ -111,9 +116,9 @@ Chắc chắn, và đó là một bước tiến lớn. Hãy xem so sánh kích
|
|
|
111
116
|
|
|
112
117
|
Ví dụ đầu tiên không bao gồm việc lazy-load các bản dịch theo locale và không tách namespace. Ví dụ thứ hai bao gồm content purging + tải động các bản dịch.
|
|
113
118
|
|
|
114
|
-
| Bundle tối ưu hóa
|
|
115
|
-
|
|
|
116
|
-
|  |  |
|
|
117
122
|
|
|
118
123
|
Nhờ có namespaces, chúng ta đã chuyển từ cấu trúc này:
|
|
119
124
|
|
|
@@ -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: Tích hợp react-i18next với next-intl và Intlayer cho việc quốc tế hóa (i18n) của ứng dụng React
|
|
6
6
|
keywords:
|
|
@@ -106,6 +106,10 @@ Chúng tôi đánh giá:
|
|
|
106
106
|
|
|
107
107
|
**Tại sao điều này quan trọng:** Gói nhỏ hơn và ít chuỗi không sử dụng giúp cải thiện hiệu suất khởi động và điều hướng.
|
|
108
108
|
|
|
109
|
+
Biểu đồ dưới đây ước tính dung lượng nội dung cho một ứng dụng giả định gồm 1 đến 10 trang, được dịch sang 1 đến 10 ngôn ngữ, với khoảng 30 KB văn bản mỗi trang. Tải nội dung động theo locale loại bỏ trục ngôn ngữ, giới hạn nội dung theo component hoặc route loại bỏ trục trang, và chỉ khi kết hợp cả hai thì dung lượng mới giữ nguyên.
|
|
110
|
+
|
|
111
|
+

|
|
112
|
+
|
|
109
113
|
### 6) DX, công cụ & bảo trì
|
|
110
114
|
|
|
111
115
|
- **react-intl / react-i18next**: Hệ sinh thái cộng đồng rộng lớn; đối với quy trình biên tập, bạn thường sử dụng các nền tảng nội địa hóa bên ngoài.
|
|
@@ -129,7 +133,7 @@ Sử dụng `intlayer`, bạn có thể khai báo nội dung theo định dạng
|
|
|
129
133
|
|
|
130
134
|
Các ngôi sao trên GitHub là một chỉ số mạnh mẽ về độ phổ biến của dự án, sự tin tưởng của cộng đồng và tính liên quan lâu dài. Mặc dù không phải là thước đo trực tiếp về chất lượng kỹ thuật, chúng phản ánh số lượng nhà phát triển thấy dự án hữu ích, theo dõi tiến trình của nó và có khả năng áp dụng nó. Để ước tính giá trị của một dự án, các ngôi sao giúp so sánh mức độ thu hút giữa các lựa chọn thay thế và cung cấp cái nhìn sâu sắc về sự phát triển của hệ sinh thái.
|
|
131
135
|
|
|
132
|
-
[](https://
|
|
136
|
+
[](https://star-history.com/#formatjs/formatjs&i18next/react-i18next&aymericzip/intlayer)
|
|
133
137
|
|
|
134
138
|
## Kết luận
|
|
135
139
|
|