@intlayer/docs 9.5.2 → 9.5.3
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 +1 -1
- 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 +1 -1
- package/blog/ar/is_next-intl_outdated.md +1 -1
- package/blog/ar/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/de/i18next_vs_intlayer.md +445 -0
- package/blog/de/is_i18next_outdated.md +1 -1
- package/blog/de/is_next-intl_outdated.md +1 -1
- package/blog/de/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/de/vue-i18n_vs_intlayer_benchmark.md +355 -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 +1 -1
- package/blog/en/is_next-intl_outdated.md +1 -1
- package/blog/en/is_vue-i18n_outdated.md +1 -1
- package/blog/en/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/en/lingui_vs_intlayer.md +381 -0
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/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 +1 -1
- package/blog/en-GB/is_next-intl_outdated.md +1 -1
- package/blog/en-GB/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/es/i18next_vs_intlayer.md +445 -0
- package/blog/es/is_i18next_outdated.md +1 -1
- package/blog/es/is_next-intl_outdated.md +1 -1
- package/blog/es/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/es/vue-i18n_vs_intlayer_benchmark.md +363 -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 +1 -1
- package/blog/fr/is_next-intl_outdated.md +1 -1
- package/blog/fr/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +287 -0
- package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +39 -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 +1 -1
- package/blog/hi/is_next-intl_outdated.md +1 -1
- package/blog/hi/is_vue-i18n_outdated.md +1 -1
- package/blog/hi/lingui_vs_intlayer-lingui.md +304 -0
- package/blog/hi/lingui_vs_intlayer.md +381 -0
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/id/i18next_vs_intlayer.md +445 -0
- package/blog/id/is_i18next_outdated.md +1 -1
- package/blog/id/is_next-intl_outdated.md +1 -1
- package/blog/id/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/it/i18next_vs_intlayer.md +445 -0
- package/blog/it/is_i18next_outdated.md +1 -1
- package/blog/it/is_next-intl_outdated.md +1 -1
- package/blog/it/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/it/vue-i18n_vs_intlayer_benchmark.md +34 -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 +1 -1
- package/blog/ja/is_next-intl_outdated.md +1 -1
- package/blog/ja/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/ko/i18next_vs_intlayer.md +447 -0
- package/blog/ko/is_i18next_outdated.md +1 -1
- package/blog/ko/is_next-intl_outdated.md +1 -1
- package/blog/ko/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/pl/i18next_vs_intlayer.md +445 -0
- package/blog/pl/is_i18next_outdated.md +1 -1
- package/blog/pl/is_next-intl_outdated.md +1 -1
- package/blog/pl/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/pt/i18next_vs_intlayer.md +445 -0
- package/blog/pt/is_i18next_outdated.md +1 -1
- package/blog/pt/is_next-intl_outdated.md +1 -1
- package/blog/pt/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +0 -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 +1 -1
- package/blog/ru/is_next-intl_outdated.md +1 -1
- package/blog/ru/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/vue-i18n_vs_intlayer-vue-i18n.md +288 -0
- package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +54 -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 +1 -1
- package/blog/tr/is_next-intl_outdated.md +1 -1
- package/blog/tr/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/uk/i18next_vs_intlayer.md +445 -0
- package/blog/uk/is_i18next_outdated.md +1 -1
- package/blog/uk/is_next-intl_outdated.md +1 -1
- package/blog/uk/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/vi/i18next_vs_intlayer.md +445 -0
- package/blog/vi/is_i18next_outdated.md +1 -1
- package/blog/vi/is_next-intl_outdated.md +1 -1
- package/blog/vi/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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/i18next_vs_intlayer-i18next.md +327 -0
- package/blog/zh/i18next_vs_intlayer.md +445 -0
- package/blog/zh/is_i18next_outdated.md +1 -1
- package/blog/zh/is_next-intl_outdated.md +1 -1
- package/blog/zh/is_vue-i18n_outdated.md +1 -1
- 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 +1 -1
- 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/react-i18next_vs_react-intl_vs_intlayer.md +1 -1
- 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 +160 -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/esm/generated/blog.entry.mjs +160 -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/types/generated/blog.entry.d.ts +8 -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/interest_of_intlayer.md +1 -1
- package/docs/bn/interest_of_intlayer.md +1 -1
- package/docs/cs/interest_of_intlayer.md +1 -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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- package/docs/nl/interest_of_intlayer.md +1 -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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- package/docs/ur/interest_of_intlayer.md +1 -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/interest_of_intlayer.md +1 -1
- 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/interest_of_intlayer.md +1 -1
- package/docs/zh-TW/interest_of_intlayer.md +1 -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 +6 -6
- package/src/generated/blog.entry.ts +160 -0
- package/src/generated/frequentQuestions.entry.ts +20 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-13
|
|
3
|
+
updatedAt: 2026-09-13
|
|
4
|
+
title: "next-intl vs Intlayer: Benchmark i Porównanie 2026"
|
|
5
|
+
description: "Szczegółowe porównanie next-intl i Intlayer w Next.js App Router i TanStack Start. Rozmiar paczki, wyciek treści, rozmiar komponentu, hydratacja i doświadczenie programisty."
|
|
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 | Benchmark internacjonalizacji (i18n) w React i Next.js
|
|
24
|
+
|
|
25
|
+
`next-intl` to obecnie domyślny wybór w zakresie i18n dla Next.js App Router: ścisła integracja z routingiem, pełna obsługa ICU MessageFormat i środowisko pracy znane każdemu, kto korzystał z klasycznych bibliotek i18n.
|
|
26
|
+
|
|
27
|
+
`Intlayer` podchodzi do tematu od nowa: brak scentralizowanych słowników, brak konieczności ręcznego dopasowywania przestrzeni nazw (namespaces) do tras. Treści deklarowane są bezpośrednio przy komponentach, a kompilator w czasie budowania pakuje wyłącznie to, czego wymaga dana strona.
|
|
28
|
+
|
|
29
|
+
Poniższy artykuł porównuje obie biblioteki na podstawie danych z [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom), otwartoźródłowego zestawu testów, który buduje tę samą aplikację z każdą biblioteką i rejestruje realny kod pobierany oraz wykonywany przez przeglądarkę.
|
|
30
|
+
|
|
31
|
+
<TOC/>
|
|
32
|
+
|
|
33
|
+
> **W skrócie (tl;dr)**: `next-intl` dodaje co najmniej **+12.6 KB gzip** na każdej stronie wyłącznie ze względu na swój runtime i powoduje wyciek **~90% ciągów z innych stron** w standardowych konfiguracjach (`static` i `dynamic`). Wyeliminowanie tego wycieku wymaga podziału katalogów na przestrzenie nazw i ręcznego ich wybierania per strona. Z kolei kompilator `Intlayer` zapewnia **0% wycieku**, **3x mniejsze komponenty** i narzut rzędu zaledwie **+0.3 KB** ponad bazową aplikację bez żadnej konfiguracji.
|
|
34
|
+
|
|
35
|
+
## Podsumowanie
|
|
36
|
+
|
|
37
|
+
- **next-intl** - Standard społeczności Next.js. Scentralizowane pliki JSON per język, pełna obsługa ICU MessageFormat i głęboka integracja z obsługą żądań i routingiem Next.js.
|
|
38
|
+
- **Intlayer** - Model zorientowany na komponenty. Słowniki `.content.ts` umieszczane są tuż obok komponentów, kompilator automatycznie wykonuje tree-shaking oraz leniwe ładowanie per komponent i per język, a także generuje ścisłe typy TypeScript.
|
|
39
|
+
|
|
40
|
+
| Biblioteka | Gwiazdki na GitHub | Łączna liczba commitów | Ostatni commit | Pierwsza wersja | Wersja NPM | Pobrania NPM |
|
|
41
|
+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
42
|
+
| `aymericzip/intlayer` | [](https://github.com/aymericzip/intlayer/stargazers) | [](https://github.com/aymericzip/intlayer/commits) | [](https://github.com/aymericzip/intlayer/commits) | Kwiecień 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) | Marzec 2021 | [](https://www.npmjs.com/package/next-intl) | [](https://www.npmjs.com/package/next-intl) |
|
|
44
|
+
|
|
45
|
+
> Odznaki aktualizują się automatycznie.
|
|
46
|
+
|
|
47
|
+
## Porównanie funkcji
|
|
48
|
+
|
|
49
|
+
| Funkcja | Intlayer (`react-intlayer` / `next-intlayer`) | next-intl (`next-intl` / `use-intl`) |
|
|
50
|
+
| ---------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
51
|
+
| **Tłumaczenia przy komponentach** | ✅ Tak, `.content.ts` umieszczony przy każdym komponencie | ❌ Scentralizowane pliki JSON w katalogu `messages/` |
|
|
52
|
+
| **Integracja z TypeScriptem** | ✅ Ścisłe typy generowane automatycznie z treści | ⚠️ Wspierane przez ręczną konfigurację `global.d.ts` |
|
|
53
|
+
| **Wykrywanie brakujących tłumaczeń** | ✅ Błąd TypeScriptu + błąd/ostrzeżenie podczas budowania | ⚠️ W runtime zwracany jest klucz lub zgłaszany błąd w zależności od opcji |
|
|
54
|
+
| **Bogata treść (JSX / Markdown / komponenty)** | ✅ Bezpośrednie wsparcie | ⚠️ Poprzez `t.rich()` z przekazywaniem komponentów mapujących |
|
|
55
|
+
| **Obsługa ICU MessageFormat** | ⚠️ W trakcie prac | ✅ Tak, pełna obsługa standardu ICU |
|
|
56
|
+
| **Synchroniczne komponenty serwerowe** | ✅ `useIntlayer` z `next-intlayer/server` działa w każdym podrzędnym komponencie serwera | ❌ Wymaga przekazywania tłumaczeń przez propsy z asynchronicznego rodzica |
|
|
57
|
+
| **Tree-shaking** | ✅ Automatyczny dla każdego komponentu i języka | ⚠️ Wymaga ręcznego podziału na przestrzenie nazw i użycia funkcji `pick()` |
|
|
58
|
+
| **Leniwe ładowanie (Lazy loading)** | ✅ Jedna linijka konfiguracji (`importMode: 'dynamic'`) | ⚠️ Wymaga ręcznego importu dynamicznego w `getRequestConfig` |
|
|
59
|
+
| **Wizualny Edytor / CMS** | ✅ Darmowy Wizualny Edytor + opcjonalny CMS | ❌ Brak |
|
|
60
|
+
| **Tłumaczenia wspomagane przez AI** | ✅ Wbudowane, korzysta z Twoich własnych kluczy API dostawców | ❌ Brak |
|
|
61
|
+
| **Serwer MCP i Agent Skills** | ✅ Tak | ❌ Brak |
|
|
62
|
+
|
|
63
|
+
## Benchmark
|
|
64
|
+
|
|
65
|
+
### Co było mierzone
|
|
66
|
+
|
|
67
|
+
Zestaw testów [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom) buduje **tę samą aplikację** z każdą biblioteką: **10 stron** (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), **10 lokalizacji** (`en`, `fr`, `es`, `de`, `it`, `pt`, `zh`, `ja`, `ko`, `ru`), identyczne komponenty i identyczną zawartość. Pomiary przeprowadzono na stronach w językach `en` i `fr`. Każda biblioteka została przetestowana w maksymalnie czterech **strategiach ładowania**:
|
|
68
|
+
|
|
69
|
+
| Strategia | Opis | Kto to stosuje |
|
|
70
|
+
| ------------------ | -------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
71
|
+
| **static** | Wszystkie języki i strony spakowane razem na starcie | Szybkie prototypy, kod wygenerowany przez AI |
|
|
72
|
+
| **dynamic** | Ładowany jest tylko aktywny język, ale od razu dla wszystkich stron | Większość projektów |
|
|
73
|
+
| **scoped-static** | Przestrzenie nazw per trasa, brak leniwego ładowania | Rzadkość |
|
|
74
|
+
| **scoped-dynamic** | Przestrzenie nazw per trasa + leniwe ładowanie. Tylko bieżąca strona w bieżącym języku | Aplikacje z rygorystycznym budżetem wydajnościowym |
|
|
75
|
+
|
|
76
|
+
Intlayer nie wymaga wariantu "scoped": kompilator automatycznie ogranicza zakres treści **per komponent**, więc wiersze `static` i `dynamic` są już zoptymalizowane pod tym kątem.
|
|
77
|
+
|
|
78
|
+
Dla każdego wariantu rejestrowano:
|
|
79
|
+
|
|
80
|
+
- **Rozmiar biblioteki (Lib size)**: rozmiar gzip pustego komponentu importującego wyłącznie bibliotekę i18n.
|
|
81
|
+
- **JS strony (Page JS)**: ilość JavaScript gzip pobieranego na stronę.
|
|
82
|
+
- **% wycieku języka (Locale leak %)**: odsetek ciągów należących do języka, którego użytkownik nie przegląda.
|
|
83
|
+
- **% wycieku strony (Page leak %)**: odsetek ciągów należących do innej podstrony.
|
|
84
|
+
- **Średnia komponentu (Component avg)**: średni rozmiar gzip każdego komponentu skompilowanego w izolacji.
|
|
85
|
+
- **Reaktywność E2E**: czas od wyboru nowego języka do zaktualizowania `html[lang]` w DOM.
|
|
86
|
+
- **Hydratacja**: czas trwania fazy hydratacji w React.
|
|
87
|
+
|
|
88
|
+
> Dane poniżej pochodzą z testu z dnia **2026-09-12** z użyciem bibliotek `next-intl` 4.14.2 i `intlayer` 9.5.1.
|
|
89
|
+
|
|
90
|
+
### Wyniki w Next.js (App Router)
|
|
91
|
+
|
|
92
|
+
| Biblioteka | Strategia | Rozmiar Lib (gz) | Śr. JS strony (gz) | Wyciek języka | Wyciek strony | Śr. komponentu (gz) | Reaktywność E2E | Hydratacja |
|
|
93
|
+
| ------------------------------ | -------------- | ---------------: | -----------------: | ------------: | ------------: | ------------------: | --------------: | ---------: |
|
|
94
|
+
| **Baza** (bez 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` (kompat) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
|
|
102
|
+
| `@intlayer/next-intl` (kompat) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
|
|
103
|
+
|
|
104
|
+
**Jak interpretować wyniki**
|
|
105
|
+
|
|
106
|
+
- **Koszt środowiska uruchomieniowego.** Aplikacja bazowa to 141.0 KB na stronę. `next-intl` zwiększa tę wartość do 153.6 KB (**+12.6 KB gzip na każdej stronie**), podczas gdy Intlayer narzuca zaledwie 141.3 KB (**+0.3 KB**).
|
|
107
|
+
- **Wyciek treści.** W najczęstszych konfiguracjach (`static` i `dynamic`) `next-intl` wysyła na każdej stronie **~90% ciągów z innych stron**, ponieważ cały plik `en.json` trafia do dostawcy klienta. Osiągnięcie 0% wymaga ręcznego dzielenia katalogów, podczas gdy Intlayer robi to automatycznie.
|
|
108
|
+
- **Rozmiar komponentu.** Komponent wywołujący `useTranslations()` waży średnio 21.8 KB; ten sam komponent z `useIntlayer()` waży jedynie 6.9 KB.
|
|
109
|
+
|
|
110
|
+
### Wyniki w TanStack Start (`use-intl`)
|
|
111
|
+
|
|
112
|
+
| Biblioteka | Strategia | Rozmiar Lib (gz) | Śr. JS strony (gz) | Wyciek języka | Wyciek strony | Śr. komponentu (gz) | Reaktywność E2E |
|
|
113
|
+
| ----------------------------- | -------------- | ---------------: | -----------------: | ------------: | ------------: | ------------------: | --------------: |
|
|
114
|
+
| **Baza** (bez 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` (kompat) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
|
|
122
|
+
|
|
123
|
+
**Jak interpretować wyniki**
|
|
124
|
+
|
|
125
|
+
- Naiwna konfiguracja `use-intl` wysyła **o 68.8 KB więcej kodu JS na stronę** niż aplikacja bazowa.
|
|
126
|
+
- W trybie `dynamic` `use-intl` osiąga 119.4 KB, ale nadal generuje **89.8% wycieku stron**.
|
|
127
|
+
- Różnica architektoniczna jest widoczna w **rozmiarze komponentów**: 76-87 KB w `use-intl` w porównaniu do 6-8 KB w Intlayerze.
|
|
128
|
+
- **Przełączanie języka** jest 2-4x szybsze w Intlayerze (3 ms vs 7-21 ms).
|
|
129
|
+
|
|
130
|
+
## Dlaczego jest taka różnica? Scentralizowane katalogi vs kompilowane słowniki
|
|
131
|
+
|
|
132
|
+
`next-intl` podąża za klasycznym wzorcem: jeden plik JSON per język, ładowany w `getRequestConfig`, przekazywany do `NextIntlClientProvider` i odczytywany przez `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 nie może wiedzieć, jakich kluczy użyje dana strona, dlatego domyślnie wysyła cały katalog.
|
|
152
|
+
|
|
153
|
+
Intlayer odwraca tę relację. Treść deklarowana jest tuż obok komponentu:
|
|
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
|
+
Podczas budowania kompilator analizuje, które komponenty importują poszczególne słowniki i dołącza do paczki tylko to, co jest niezbędne dla aktywnego języka.
|
|
173
|
+
|
|
174
|
+
> Aby uzyskać wyniki z wiersza `dynamic`, ustaw `dictionary.importMode: 'dynamic'` w `intlayer.config.ts`. Zobacz [dokumentację optymalizacji paczki](https://intlayer.org/pl/doc/concept/bundle-optimization).
|
|
175
|
+
|
|
176
|
+
## Doświadczenie programisty
|
|
177
|
+
|
|
178
|
+
### Komponent klienta
|
|
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
|
+
### Synchroniczne komponenty serwerowe
|
|
253
|
+
|
|
254
|
+
Wspólne elementy interfejsu (pasek nawigacji, stopka, karty) są często komponentami serwerowymi renderowanymi wewnątrz komponentów klienckich, więc nie mogą być asynchroniczne (`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
|
+
### Metadane
|
|
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
|
+
## Zachowaj API next-intl, zyskaj lekki bundle z Intlayer
|
|
351
|
+
|
|
352
|
+
Nie musisz przepisywać komponentów, aby zyskać powyższe wyniki wydajnościowe. `@intlayer/next-intl` to adapter typu drop-in: zachowuje `useTranslations`, `getTranslations`, `useFormatter`, `t.rich()` i formaty ICU, serwując je ze słowników skompilowanych przez Intlayera.
|
|
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
|
+
W testach wersja kompatybilna tej samej aplikacji zmniejszyła rozmiar z **153.6 KB do 147.5 KB** na stronę, rozmiar komponentów z **21.8 KB do 8.1 KB**, a wyciek strony spadł z **~90% do 0%**, bez ingerencji w kod źródłowy aplikacji. Dotychczasowe pliki `messages/{locale}.json` mogą pozostać źródłem prawdy dzięki [wtyczce synchronizacji JSON](https://intlayer.org/pl/doc/compatibility/next-intl).
|
|
366
|
+
|
|
367
|
+
Zobacz [przewodnik migracji z next-intl](https://intlayer.org/pl/doc/migration/next-intl), aby poznać szczegóły krok po kroku.
|
|
368
|
+
|
|
369
|
+
## Kiedy wybrać którą bibliotekę?
|
|
370
|
+
|
|
371
|
+
- **Wybierz next-intl**, jeśli zależy Ci na standardzie społeczności Next.js, intensywnie korzystasz z ICU MessageFormat, Twoja aplikacja jest mała lub średnia, albo integrujesz się ze scentralizowanymi platformami TMS (Crowdin, Phrase, Lokalise...).
|
|
372
|
+
- **Wybierz Intlayer**, jeśli zależy Ci na **treści powiązanej z komponentami**, **ścisłym TypeScripcie**, **wykrywaniu brakujących kluczy w czasie budowania**, **automatycznym tree-shakingu i leniwym ładowaniu**, synchronicznych komponentach serwerowych oraz wbudowanych narzędziach edycyjnych (Wizualny Edytor, CMS, tłumaczenia AI, serwer MCP).
|
|
373
|
+
- **Wybierz `@intlayer/next-intl`**, jeśli używasz już `next-intl` i chcesz zredukować rozmiar paczki bez konieczności przepisywania kodu.
|
|
374
|
+
|
|
375
|
+
## Powiązane porównania
|
|
376
|
+
|
|
377
|
+
- [i18next vs Intlayer](https://intlayer.org/pl/blog/i18next-vs-intlayer) (ten sam benchmark)
|
|
378
|
+
- [Lingui vs Intlayer](https://intlayer.org/pl/blog/lingui-vs-intlayer) (ten sam benchmark)
|
|
379
|
+
- [Benchmark vue-i18n vs Intlayer](https://intlayer.org/pl/blog/vue-i18n-vs-intlayer-benchmark) (ten sam benchmark)
|
|
380
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/pl/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
381
|
+
- [Czy next-intl jest przestarzałe?](https://intlayer.org/pl/blog/is-next-intl-outdated)
|
|
382
|
+
|
|
383
|
+
## Gwiazdki na GitHub
|
|
384
|
+
|
|
385
|
+
Gwiazdki na GitHub to silny wskaźnik popularności projektu, zaufania społeczności i długoterminowej perspektywy rozwoju.
|
|
386
|
+
|
|
387
|
+
[](https://star-history.com/#amannn/next-intl&aymericzip/intlayer)
|
|
388
|
+
|
|
389
|
+
## Podsumowanie
|
|
390
|
+
|
|
391
|
+
`next-intl` to solidna, dobrze utrzymywana biblioteka, a testy potwierdzają, że jest rozsądnym wyborem w świecie Next.js. Jednak scentralizowany model katalogów przerzuca całą odpowiedzialność za optymalizację na programistę: podstawowa konfiguracja powoduje wyciek około 90% treści z innych podstron, a sam runtime kosztuje +12.6 KB gzip na każdej stronie.
|
|
392
|
+
|
|
393
|
+
Intlayer przenosi tę pracę do kompilatora. Słowniki per komponent, leniwe ładowanie per język i usuwanie nieużywanych tłumaczeń to efekty procesu budowania. Rezultat w tej samej aplikacji: **+0.3 KB na stronę**, **0% wycieku**, komponenty **3x mniejsze** i przełączanie języka **2-4x szybsze** w TanStack Start.
|
|
394
|
+
|
|
395
|
+
Wszystkie surowe dane, aplikacje testowe i skrypty znajdują się w [repozytorium Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom).
|
|
396
|
+
|
|
397
|
+
Więcej szczegółów znajdziesz w dokumencie ['Dlaczego Intlayer?'](https://intlayer.org/pl/doc/why).
|
|
@@ -129,7 +129,7 @@ Korzystając z `intlayer`, możesz deklarować swoją zawartość w formacie ulu
|
|
|
129
129
|
|
|
130
130
|
Gwiazdy na GitHubie są silnym wskaźnikiem popularności projektu, zaufania społeczności oraz jego długoterminowej istotności. Choć nie są bezpośrednią miarą jakości technicznej, odzwierciedlają, ilu programistów uważa projekt za użyteczny, śledzi jego rozwój i prawdopodobnie go zaadaptuje. Przy szacowaniu wartości projektu, gwiazdy pomagają porównać zainteresowanie różnymi alternatywami oraz dostarczają wglądu w rozwój ekosystemu.
|
|
131
131
|
|
|
132
|
-
[](https://
|
|
132
|
+
[](https://star-history.com/#formatjs/formatjs&i18next/react-i18next&aymericzip/intlayer)
|
|
133
133
|
|
|
134
134
|
## Podsumowanie
|
|
135
135
|
|