@intlayer/docs 9.5.6 → 9.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ar/i18next_vs_intlayer.md +130 -16
- package/blog/ar/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ar/lingui_vs_intlayer.md +122 -15
- package/blog/ar/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ar/next-intl_vs_intlayer.md +136 -20
- package/blog/ar/vue-i18n_vs_intlayer-vue-i18n.md +119 -17
- package/blog/ar/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ar/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/de/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/de/i18next_vs_intlayer.md +128 -14
- package/blog/de/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/de/lingui_vs_intlayer.md +122 -15
- package/blog/de/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/de/next-intl_vs_intlayer.md +125 -15
- package/blog/de/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/de/vue-i18n_vs_intlayer.md +193 -31
- package/blog/en/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en/i18next_vs_intlayer.md +128 -14
- package/blog/en/is_intlayer_lighter_than_paraglide.md +288 -0
- package/blog/en/lingui_vs_intlayer.md +124 -15
- package/blog/en/next-intl_vs_intlayer-next-intl.md +123 -14
- package/blog/en/next-intl_vs_intlayer.md +125 -13
- package/blog/en/vue-i18n_vs_intlayer-vue-i18n.md +115 -15
- package/blog/en/vue-i18n_vs_intlayer.md +188 -27
- package/blog/en-GB/i18next_vs_intlayer-i18next.md +121 -14
- package/blog/en-GB/i18next_vs_intlayer.md +128 -14
- package/blog/en-GB/is_intlayer_lighter_than_paraglide.md +285 -0
- package/blog/en-GB/lingui_vs_intlayer.md +122 -15
- package/blog/en-GB/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/en-GB/next-intl_vs_intlayer.md +125 -15
- package/blog/en-GB/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/en-GB/vue-i18n_vs_intlayer.md +187 -25
- package/blog/en-GB/vue-i18n_vs_intlayer_benchmark.md +116 -0
- package/blog/es/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/es/i18next_vs_intlayer.md +128 -14
- package/blog/es/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/es/lingui_vs_intlayer.md +122 -15
- package/blog/es/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/es/next-intl_vs_intlayer.md +125 -15
- package/blog/es/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/es/vue-i18n_vs_intlayer.md +193 -31
- package/blog/fr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/fr/i18next_vs_intlayer.md +128 -14
- package/blog/fr/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/fr/lingui_vs_intlayer.md +122 -15
- package/blog/fr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/fr/next-intl_vs_intlayer.md +127 -15
- package/blog/fr/vue-i18n_vs_intlayer-vue-i18n.md +118 -17
- package/blog/fr/vue-i18n_vs_intlayer.md +192 -31
- package/blog/fr/vue-i18n_vs_intlayer_benchmark.md +329 -7
- package/blog/hi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/hi/i18next_vs_intlayer.md +130 -16
- package/blog/hi/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/hi/lingui_vs_intlayer.md +122 -15
- package/blog/hi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/hi/next-intl_vs_intlayer.md +135 -19
- package/blog/hi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/hi/vue-i18n_vs_intlayer.md +193 -31
- package/blog/hi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/id/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/id/i18next_vs_intlayer.md +128 -14
- package/blog/id/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/id/lingui_vs_intlayer.md +122 -15
- package/blog/id/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/id/next-intl_vs_intlayer.md +135 -19
- package/blog/id/vue-i18n_vs_intlayer-vue-i18n.md +354 -2
- package/blog/id/vue-i18n_vs_intlayer.md +188 -26
- package/blog/id/vue-i18n_vs_intlayer_benchmark.md +327 -7
- package/blog/it/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/it/i18next_vs_intlayer.md +128 -14
- package/blog/it/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/it/lingui_vs_intlayer.md +122 -15
- package/blog/it/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/it/next-intl_vs_intlayer.md +125 -15
- package/blog/it/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/it/vue-i18n_vs_intlayer.md +191 -31
- package/blog/it/vue-i18n_vs_intlayer_benchmark.md +332 -5
- package/blog/ja/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ja/i18next_vs_intlayer.md +129 -17
- package/blog/ja/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ja/lingui_vs_intlayer.md +122 -15
- package/blog/ja/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ja/next-intl_vs_intlayer.md +124 -14
- package/blog/ja/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ja/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ja/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ko/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ko/i18next_vs_intlayer.md +129 -17
- package/blog/ko/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ko/lingui_vs_intlayer.md +122 -15
- package/blog/ko/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/ko/next-intl_vs_intlayer.md +134 -18
- package/blog/ko/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/ko/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pl/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pl/i18next_vs_intlayer.md +128 -14
- package/blog/pl/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/pl/lingui_vs_intlayer.md +122 -15
- package/blog/pl/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pl/next-intl_vs_intlayer.md +134 -18
- package/blog/pl/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pl/vue-i18n_vs_intlayer.md +188 -26
- package/blog/pl/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/pt/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/pt/i18next_vs_intlayer.md +128 -14
- package/blog/pt/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/pt/lingui_vs_intlayer.md +122 -15
- package/blog/pt/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/pt/next-intl_vs_intlayer.md +131 -15
- package/blog/pt/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/pt/vue-i18n_vs_intlayer.md +193 -31
- package/blog/pt/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/ru/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/ru/i18next_vs_intlayer.md +130 -16
- package/blog/ru/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/ru/lingui_vs_intlayer.md +122 -15
- package/blog/ru/next-intl_vs_intlayer-next-intl.md +125 -16
- package/blog/ru/next-intl_vs_intlayer.md +123 -13
- package/blog/ru/vue-i18n_vs_intlayer-vue-i18n.md +127 -27
- package/blog/ru/vue-i18n_vs_intlayer.md +193 -31
- package/blog/ru/vue-i18n_vs_intlayer_benchmark.md +326 -19
- package/blog/tr/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/tr/i18next_vs_intlayer.md +128 -14
- package/blog/tr/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/tr/lingui_vs_intlayer.md +122 -15
- package/blog/tr/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/tr/next-intl_vs_intlayer.md +136 -20
- package/blog/tr/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/tr/vue-i18n_vs_intlayer.md +188 -26
- package/blog/tr/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/uk/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/uk/i18next_vs_intlayer.md +130 -16
- package/blog/uk/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/uk/lingui_vs_intlayer.md +122 -15
- package/blog/uk/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/uk/next-intl_vs_intlayer.md +135 -19
- package/blog/uk/vue-i18n_vs_intlayer-vue-i18n.md +135 -17
- package/blog/uk/vue-i18n_vs_intlayer.md +188 -27
- package/blog/uk/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/vi/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/vi/i18next_vs_intlayer.md +128 -14
- package/blog/vi/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/vi/lingui_vs_intlayer.md +122 -15
- package/blog/vi/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/vi/next-intl_vs_intlayer.md +135 -19
- package/blog/vi/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/vi/vue-i18n_vs_intlayer.md +188 -26
- package/blog/vi/vue-i18n_vs_intlayer_benchmark.md +361 -0
- package/blog/zh/i18next_vs_intlayer-i18next.md +122 -15
- package/blog/zh/i18next_vs_intlayer.md +128 -14
- package/blog/zh/is_intlayer_lighter_than_paraglide.md +284 -0
- package/blog/zh/lingui_vs_intlayer.md +122 -15
- package/blog/zh/next-intl_vs_intlayer-next-intl.md +124 -15
- package/blog/zh/next-intl_vs_intlayer.md +125 -15
- package/blog/zh/vue-i18n_vs_intlayer-vue-i18n.md +117 -17
- package/blog/zh/vue-i18n_vs_intlayer.md +192 -31
- package/blog/zh/vue-i18n_vs_intlayer_benchmark.md +340 -9
- package/dist/cjs/generated/blog.entry.cjs +20 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +60 -40
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +20 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +60 -40
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +3 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/nextjs.md +19 -16
- package/docs/ar/benchmark/solid.md +26 -9
- package/docs/ar/benchmark/svelte.md +22 -7
- package/docs/ar/benchmark/tanstack.md +20 -16
- package/docs/ar/benchmark/vue.md +19 -10
- package/docs/ar/chrome_extension.md +130 -0
- package/docs/ar/cli/index.md +11 -1
- package/docs/ar/cli/infra.md +162 -0
- package/docs/ar/cli/init.md +24 -1
- package/docs/ar/cli/upgrade.md +125 -0
- package/docs/ar/dictionary/html.md +173 -5
- package/docs/ar/dictionary/markdown.md +263 -1
- package/docs/ar/intlayer_with_analog.md +23 -1
- package/docs/ar/intlayer_with_angular_19.md +24 -1
- package/docs/ar/intlayer_with_angular_21.md +24 -1
- package/docs/ar/intlayer_with_astro.md +24 -1
- package/docs/ar/intlayer_with_astro_lit.md +25 -1
- package/docs/ar/intlayer_with_astro_preact.md +26 -1
- package/docs/ar/intlayer_with_astro_react.md +26 -1
- package/docs/ar/intlayer_with_astro_solid.md +26 -1
- package/docs/ar/intlayer_with_astro_svelte.md +25 -1
- package/docs/ar/intlayer_with_astro_vue.md +25 -1
- package/docs/ar/intlayer_with_remix_3.md +22 -1
- package/docs/ar/self_hosting.md +406 -231
- package/docs/de/benchmark/nextjs.md +19 -16
- package/docs/de/benchmark/solid.md +26 -9
- package/docs/de/benchmark/svelte.md +22 -7
- package/docs/de/benchmark/tanstack.md +20 -16
- package/docs/de/benchmark/vue.md +19 -10
- package/docs/de/chrome_extension.md +130 -0
- package/docs/de/cli/index.md +11 -1
- package/docs/de/cli/infra.md +162 -0
- package/docs/de/cli/init.md +24 -1
- package/docs/de/cli/upgrade.md +125 -0
- package/docs/de/dictionary/html.md +173 -5
- package/docs/de/dictionary/markdown.md +263 -1
- package/docs/de/intlayer_with_analog.md +23 -1
- package/docs/de/intlayer_with_angular_19.md +24 -1
- package/docs/de/intlayer_with_angular_21.md +24 -1
- package/docs/de/intlayer_with_astro.md +24 -1
- package/docs/de/intlayer_with_astro_lit.md +25 -1
- package/docs/de/intlayer_with_astro_preact.md +26 -1
- package/docs/de/intlayer_with_astro_react.md +26 -1
- package/docs/de/intlayer_with_astro_solid.md +26 -1
- package/docs/de/intlayer_with_astro_svelte.md +25 -1
- package/docs/de/intlayer_with_astro_vue.md +25 -1
- package/docs/de/intlayer_with_remix_3.md +22 -1
- package/docs/de/self_hosting.md +404 -227
- package/docs/en/agent_skills.md +29 -1
- package/docs/en/benchmark/nextjs.md +19 -16
- package/docs/en/benchmark/solid.md +26 -9
- package/docs/en/benchmark/svelte.md +22 -7
- package/docs/en/benchmark/tanstack.md +21 -17
- package/docs/en/benchmark/vue.md +20 -11
- package/docs/en/chrome_extension.md +130 -0
- package/docs/en/cli/index.md +11 -1
- package/docs/en/cli/infra.md +175 -0
- package/docs/en/cli/init.md +25 -1
- package/docs/en/cli/upgrade.md +125 -0
- package/docs/en/dictionary/html.md +173 -5
- package/docs/en/dictionary/markdown.md +263 -1
- package/docs/en/intlayer_with_analog.md +23 -1
- package/docs/en/intlayer_with_angular_19.md +24 -1
- package/docs/en/intlayer_with_angular_21.md +24 -1
- package/docs/en/intlayer_with_astro.md +24 -1
- package/docs/en/intlayer_with_astro_lit.md +25 -1
- package/docs/en/intlayer_with_astro_preact.md +26 -1
- package/docs/en/intlayer_with_astro_react.md +26 -1
- package/docs/en/intlayer_with_astro_solid.md +26 -1
- package/docs/en/intlayer_with_astro_svelte.md +25 -1
- package/docs/en/intlayer_with_astro_vue.md +25 -1
- package/docs/en/intlayer_with_remix_3.md +22 -1
- package/docs/en/self_hosting.md +418 -176
- package/docs/en-GB/benchmark/nextjs.md +19 -16
- package/docs/en-GB/benchmark/solid.md +26 -9
- package/docs/en-GB/benchmark/svelte.md +22 -7
- package/docs/en-GB/benchmark/tanstack.md +20 -16
- package/docs/en-GB/benchmark/vue.md +20 -11
- package/docs/en-GB/chrome_extension.md +130 -0
- package/docs/en-GB/cli/index.md +11 -1
- package/docs/en-GB/cli/infra.md +162 -0
- package/docs/en-GB/cli/init.md +24 -1
- package/docs/en-GB/cli/upgrade.md +125 -0
- package/docs/en-GB/dictionary/html.md +173 -5
- package/docs/en-GB/dictionary/markdown.md +263 -1
- package/docs/en-GB/intlayer_with_analog.md +23 -1
- package/docs/en-GB/intlayer_with_angular_19.md +24 -1
- package/docs/en-GB/intlayer_with_angular_21.md +24 -1
- package/docs/en-GB/intlayer_with_astro.md +24 -1
- package/docs/en-GB/intlayer_with_astro_lit.md +25 -1
- package/docs/en-GB/intlayer_with_astro_preact.md +26 -1
- package/docs/en-GB/intlayer_with_astro_react.md +26 -1
- package/docs/en-GB/intlayer_with_astro_solid.md +26 -1
- package/docs/en-GB/intlayer_with_astro_svelte.md +25 -1
- package/docs/en-GB/intlayer_with_astro_vue.md +25 -1
- package/docs/en-GB/intlayer_with_remix_3.md +22 -1
- package/docs/en-GB/self_hosting.md +381 -206
- package/docs/es/benchmark/nextjs.md +19 -16
- package/docs/es/benchmark/solid.md +26 -9
- package/docs/es/benchmark/svelte.md +22 -7
- package/docs/es/benchmark/tanstack.md +20 -16
- package/docs/es/benchmark/vue.md +19 -10
- package/docs/es/chrome_extension.md +130 -0
- package/docs/es/cli/index.md +11 -1
- package/docs/es/cli/infra.md +162 -0
- package/docs/es/cli/init.md +24 -1
- package/docs/es/cli/upgrade.md +125 -0
- package/docs/es/dictionary/html.md +173 -5
- package/docs/es/dictionary/markdown.md +263 -1
- package/docs/es/intlayer_with_analog.md +23 -1
- package/docs/es/intlayer_with_angular_19.md +24 -1
- package/docs/es/intlayer_with_angular_21.md +24 -1
- package/docs/es/intlayer_with_astro.md +24 -1
- package/docs/es/intlayer_with_astro_lit.md +25 -1
- package/docs/es/intlayer_with_astro_preact.md +26 -1
- package/docs/es/intlayer_with_astro_react.md +26 -1
- package/docs/es/intlayer_with_astro_solid.md +26 -1
- package/docs/es/intlayer_with_astro_svelte.md +25 -1
- package/docs/es/intlayer_with_astro_vue.md +25 -1
- package/docs/es/intlayer_with_remix_3.md +22 -1
- package/docs/es/self_hosting.md +400 -223
- package/docs/fr/benchmark/nextjs.md +19 -16
- package/docs/fr/benchmark/solid.md +26 -9
- package/docs/fr/benchmark/svelte.md +22 -7
- package/docs/fr/benchmark/tanstack.md +20 -16
- package/docs/fr/benchmark/vue.md +20 -11
- package/docs/fr/chrome_extension.md +130 -0
- package/docs/fr/cli/index.md +11 -1
- package/docs/fr/cli/infra.md +162 -0
- package/docs/fr/cli/init.md +24 -1
- package/docs/fr/cli/upgrade.md +125 -0
- package/docs/fr/dictionary/html.md +173 -5
- package/docs/fr/dictionary/markdown.md +265 -4
- package/docs/fr/intlayer_with_analog.md +23 -1
- package/docs/fr/intlayer_with_angular_19.md +24 -1
- package/docs/fr/intlayer_with_angular_21.md +24 -1
- package/docs/fr/intlayer_with_astro.md +24 -1
- package/docs/fr/intlayer_with_astro_lit.md +25 -1
- package/docs/fr/intlayer_with_astro_preact.md +26 -1
- package/docs/fr/intlayer_with_astro_react.md +26 -1
- package/docs/fr/intlayer_with_astro_solid.md +26 -1
- package/docs/fr/intlayer_with_astro_svelte.md +25 -1
- package/docs/fr/intlayer_with_astro_vue.md +25 -1
- package/docs/fr/intlayer_with_remix_3.md +22 -1
- package/docs/fr/self_hosting.md +401 -224
- package/docs/hi/benchmark/nextjs.md +19 -16
- package/docs/hi/benchmark/solid.md +26 -9
- package/docs/hi/benchmark/svelte.md +22 -7
- package/docs/hi/benchmark/tanstack.md +20 -16
- package/docs/hi/benchmark/vue.md +20 -11
- package/docs/hi/chrome_extension.md +130 -0
- package/docs/hi/cli/index.md +11 -1
- package/docs/hi/cli/infra.md +162 -0
- package/docs/hi/cli/init.md +24 -1
- package/docs/hi/cli/upgrade.md +125 -0
- package/docs/hi/dictionary/html.md +173 -5
- package/docs/hi/dictionary/markdown.md +263 -1
- package/docs/hi/intlayer_with_analog.md +23 -1
- package/docs/hi/intlayer_with_angular_19.md +24 -1
- package/docs/hi/intlayer_with_angular_21.md +24 -1
- package/docs/hi/intlayer_with_astro.md +24 -1
- package/docs/hi/intlayer_with_astro_lit.md +25 -1
- package/docs/hi/intlayer_with_astro_preact.md +26 -1
- package/docs/hi/intlayer_with_astro_react.md +26 -1
- package/docs/hi/intlayer_with_astro_solid.md +26 -1
- package/docs/hi/intlayer_with_astro_svelte.md +25 -1
- package/docs/hi/intlayer_with_astro_vue.md +25 -1
- package/docs/hi/intlayer_with_remix_3.md +22 -1
- package/docs/hi/self_hosting.md +409 -235
- package/docs/id/benchmark/nextjs.md +19 -16
- package/docs/id/benchmark/solid.md +26 -9
- package/docs/id/benchmark/svelte.md +22 -7
- package/docs/id/benchmark/tanstack.md +20 -16
- package/docs/id/benchmark/vue.md +20 -11
- package/docs/id/chrome_extension.md +130 -0
- package/docs/id/cli/index.md +11 -1
- package/docs/id/cli/infra.md +162 -0
- package/docs/id/cli/init.md +24 -1
- package/docs/id/cli/upgrade.md +125 -0
- package/docs/id/dictionary/html.md +173 -5
- package/docs/id/dictionary/markdown.md +263 -1
- package/docs/id/intlayer_with_analog.md +23 -1
- package/docs/id/intlayer_with_angular_19.md +24 -1
- package/docs/id/intlayer_with_angular_21.md +24 -1
- package/docs/id/intlayer_with_astro.md +24 -1
- package/docs/id/intlayer_with_astro_lit.md +25 -1
- package/docs/id/intlayer_with_astro_preact.md +26 -1
- package/docs/id/intlayer_with_astro_react.md +26 -1
- package/docs/id/intlayer_with_astro_solid.md +26 -1
- package/docs/id/intlayer_with_astro_svelte.md +25 -1
- package/docs/id/intlayer_with_astro_vue.md +25 -1
- package/docs/id/intlayer_with_remix_3.md +22 -1
- package/docs/id/self_hosting.md +416 -243
- package/docs/it/benchmark/nextjs.md +19 -16
- package/docs/it/benchmark/solid.md +26 -9
- package/docs/it/benchmark/svelte.md +22 -7
- package/docs/it/benchmark/tanstack.md +20 -16
- package/docs/it/benchmark/vue.md +19 -10
- package/docs/it/chrome_extension.md +130 -0
- package/docs/it/cli/index.md +11 -1
- package/docs/it/cli/infra.md +162 -0
- package/docs/it/cli/init.md +24 -1
- package/docs/it/cli/upgrade.md +125 -0
- package/docs/it/dictionary/html.md +173 -5
- package/docs/it/dictionary/markdown.md +263 -1
- package/docs/it/intlayer_with_analog.md +23 -1
- package/docs/it/intlayer_with_angular_19.md +24 -1
- package/docs/it/intlayer_with_angular_21.md +24 -1
- package/docs/it/intlayer_with_astro.md +24 -1
- package/docs/it/intlayer_with_astro_lit.md +25 -1
- package/docs/it/intlayer_with_astro_preact.md +26 -1
- package/docs/it/intlayer_with_astro_react.md +26 -1
- package/docs/it/intlayer_with_astro_solid.md +26 -1
- package/docs/it/intlayer_with_astro_svelte.md +25 -1
- package/docs/it/intlayer_with_astro_vue.md +25 -1
- package/docs/it/intlayer_with_remix_3.md +22 -1
- package/docs/it/self_hosting.md +412 -237
- package/docs/ja/benchmark/nextjs.md +19 -16
- package/docs/ja/benchmark/solid.md +26 -9
- package/docs/ja/benchmark/svelte.md +22 -7
- package/docs/ja/benchmark/tanstack.md +18 -14
- package/docs/ja/benchmark/vue.md +19 -10
- package/docs/ja/chrome_extension.md +130 -0
- package/docs/ja/cli/index.md +11 -1
- package/docs/ja/cli/infra.md +162 -0
- package/docs/ja/cli/init.md +24 -1
- package/docs/ja/cli/upgrade.md +125 -0
- package/docs/ja/dictionary/html.md +173 -5
- package/docs/ja/dictionary/markdown.md +263 -1
- package/docs/ja/intlayer_with_analog.md +23 -1
- package/docs/ja/intlayer_with_angular_19.md +24 -1
- package/docs/ja/intlayer_with_angular_21.md +24 -1
- package/docs/ja/intlayer_with_astro.md +24 -1
- package/docs/ja/intlayer_with_astro_lit.md +25 -1
- package/docs/ja/intlayer_with_astro_preact.md +26 -1
- package/docs/ja/intlayer_with_astro_react.md +26 -1
- package/docs/ja/intlayer_with_astro_solid.md +26 -1
- package/docs/ja/intlayer_with_astro_svelte.md +25 -1
- package/docs/ja/intlayer_with_astro_vue.md +25 -1
- package/docs/ja/intlayer_with_remix_3.md +22 -1
- package/docs/ja/self_hosting.md +398 -223
- package/docs/ko/benchmark/nextjs.md +19 -16
- package/docs/ko/benchmark/solid.md +26 -9
- package/docs/ko/benchmark/svelte.md +22 -7
- package/docs/ko/benchmark/tanstack.md +20 -16
- package/docs/ko/benchmark/vue.md +20 -11
- package/docs/ko/chrome_extension.md +130 -0
- package/docs/ko/cli/index.md +11 -1
- package/docs/ko/cli/infra.md +162 -0
- package/docs/ko/cli/init.md +24 -1
- package/docs/ko/cli/upgrade.md +126 -0
- package/docs/ko/dictionary/html.md +173 -5
- package/docs/ko/dictionary/markdown.md +263 -1
- package/docs/ko/intlayer_with_analog.md +23 -1
- package/docs/ko/intlayer_with_angular_19.md +24 -1
- package/docs/ko/intlayer_with_angular_21.md +24 -1
- package/docs/ko/intlayer_with_astro.md +24 -1
- package/docs/ko/intlayer_with_astro_lit.md +25 -1
- package/docs/ko/intlayer_with_astro_preact.md +26 -1
- package/docs/ko/intlayer_with_astro_react.md +26 -1
- package/docs/ko/intlayer_with_astro_solid.md +26 -1
- package/docs/ko/intlayer_with_astro_svelte.md +25 -1
- package/docs/ko/intlayer_with_astro_vue.md +25 -1
- package/docs/ko/intlayer_with_remix_3.md +22 -1
- package/docs/ko/self_hosting.md +411 -238
- package/docs/pl/benchmark/nextjs.md +19 -16
- package/docs/pl/benchmark/solid.md +26 -9
- package/docs/pl/benchmark/svelte.md +22 -7
- package/docs/pl/benchmark/tanstack.md +20 -16
- package/docs/pl/benchmark/vue.md +20 -11
- package/docs/pl/chrome_extension.md +130 -0
- package/docs/pl/cli/index.md +11 -1
- package/docs/pl/cli/infra.md +162 -0
- package/docs/pl/cli/init.md +24 -1
- package/docs/pl/cli/upgrade.md +125 -0
- package/docs/pl/dictionary/html.md +173 -5
- package/docs/pl/dictionary/markdown.md +263 -1
- package/docs/pl/intlayer_with_analog.md +23 -1
- package/docs/pl/intlayer_with_angular_19.md +24 -1
- package/docs/pl/intlayer_with_angular_21.md +24 -1
- package/docs/pl/intlayer_with_astro.md +24 -1
- package/docs/pl/intlayer_with_astro_lit.md +25 -1
- package/docs/pl/intlayer_with_astro_preact.md +26 -1
- package/docs/pl/intlayer_with_astro_react.md +26 -1
- package/docs/pl/intlayer_with_astro_solid.md +26 -1
- package/docs/pl/intlayer_with_astro_svelte.md +25 -1
- package/docs/pl/intlayer_with_astro_vue.md +25 -1
- package/docs/pl/intlayer_with_remix_3.md +22 -1
- package/docs/pl/self_hosting.md +408 -233
- package/docs/pt/benchmark/nextjs.md +19 -16
- package/docs/pt/benchmark/solid.md +26 -9
- package/docs/pt/benchmark/svelte.md +22 -7
- package/docs/pt/benchmark/tanstack.md +20 -16
- package/docs/pt/benchmark/vue.md +19 -10
- package/docs/pt/chrome_extension.md +130 -0
- package/docs/pt/cli/index.md +11 -1
- package/docs/pt/cli/infra.md +162 -0
- package/docs/pt/cli/init.md +24 -1
- package/docs/pt/cli/upgrade.md +125 -0
- package/docs/pt/dictionary/html.md +173 -5
- package/docs/pt/dictionary/markdown.md +263 -1
- package/docs/pt/intlayer_with_analog.md +23 -1
- package/docs/pt/intlayer_with_angular_19.md +24 -1
- package/docs/pt/intlayer_with_angular_21.md +24 -1
- package/docs/pt/intlayer_with_astro.md +24 -1
- package/docs/pt/intlayer_with_astro_lit.md +25 -1
- package/docs/pt/intlayer_with_astro_preact.md +26 -1
- package/docs/pt/intlayer_with_astro_react.md +26 -1
- package/docs/pt/intlayer_with_astro_solid.md +26 -1
- package/docs/pt/intlayer_with_astro_svelte.md +25 -1
- package/docs/pt/intlayer_with_astro_vue.md +25 -1
- package/docs/pt/intlayer_with_remix_3.md +22 -1
- package/docs/pt/self_hosting.md +399 -224
- package/docs/ru/benchmark/nextjs.md +19 -16
- package/docs/ru/benchmark/solid.md +26 -9
- package/docs/ru/benchmark/svelte.md +22 -7
- package/docs/ru/benchmark/tanstack.md +20 -16
- package/docs/ru/benchmark/vue.md +20 -11
- package/docs/ru/chrome_extension.md +130 -0
- package/docs/ru/cli/index.md +11 -1
- package/docs/ru/cli/infra.md +162 -0
- package/docs/ru/cli/init.md +24 -1
- package/docs/ru/cli/upgrade.md +125 -0
- package/docs/ru/dictionary/html.md +173 -5
- package/docs/ru/dictionary/markdown.md +263 -1
- package/docs/ru/intlayer_with_analog.md +23 -1
- package/docs/ru/intlayer_with_angular_19.md +24 -1
- package/docs/ru/intlayer_with_angular_21.md +24 -1
- package/docs/ru/intlayer_with_astro.md +24 -1
- package/docs/ru/intlayer_with_astro_lit.md +25 -1
- package/docs/ru/intlayer_with_astro_preact.md +26 -1
- package/docs/ru/intlayer_with_astro_react.md +26 -1
- package/docs/ru/intlayer_with_astro_solid.md +26 -1
- package/docs/ru/intlayer_with_astro_svelte.md +25 -1
- package/docs/ru/intlayer_with_astro_vue.md +25 -1
- package/docs/ru/intlayer_with_remix_3.md +22 -1
- package/docs/ru/self_hosting.md +403 -228
- package/docs/tr/benchmark/nextjs.md +19 -16
- package/docs/tr/benchmark/solid.md +26 -9
- package/docs/tr/benchmark/svelte.md +22 -7
- package/docs/tr/benchmark/tanstack.md +20 -16
- package/docs/tr/benchmark/vue.md +20 -11
- package/docs/tr/chrome_extension.md +130 -0
- package/docs/tr/cli/index.md +11 -1
- package/docs/tr/cli/infra.md +162 -0
- package/docs/tr/cli/init.md +24 -1
- package/docs/tr/cli/upgrade.md +125 -0
- package/docs/tr/dictionary/html.md +173 -5
- package/docs/tr/dictionary/markdown.md +263 -1
- package/docs/tr/intlayer_with_analog.md +23 -1
- package/docs/tr/intlayer_with_angular_19.md +24 -1
- package/docs/tr/intlayer_with_angular_21.md +24 -1
- package/docs/tr/intlayer_with_astro.md +24 -1
- package/docs/tr/intlayer_with_astro_lit.md +25 -1
- package/docs/tr/intlayer_with_astro_preact.md +26 -1
- package/docs/tr/intlayer_with_astro_react.md +26 -1
- package/docs/tr/intlayer_with_astro_solid.md +26 -1
- package/docs/tr/intlayer_with_astro_svelte.md +25 -1
- package/docs/tr/intlayer_with_astro_vue.md +25 -1
- package/docs/tr/intlayer_with_remix_3.md +22 -1
- package/docs/tr/self_hosting.md +410 -234
- package/docs/uk/benchmark/nextjs.md +19 -16
- package/docs/uk/benchmark/solid.md +26 -9
- package/docs/uk/benchmark/svelte.md +22 -7
- package/docs/uk/benchmark/tanstack.md +20 -16
- package/docs/uk/benchmark/vue.md +20 -11
- package/docs/uk/chrome_extension.md +130 -0
- package/docs/uk/cli/index.md +11 -1
- package/docs/uk/cli/infra.md +162 -0
- package/docs/uk/cli/init.md +24 -1
- package/docs/uk/cli/upgrade.md +125 -0
- package/docs/uk/dictionary/html.md +173 -5
- package/docs/uk/dictionary/markdown.md +263 -1
- package/docs/uk/intlayer_with_analog.md +23 -1
- package/docs/uk/intlayer_with_angular_19.md +24 -1
- package/docs/uk/intlayer_with_angular_21.md +24 -1
- package/docs/uk/intlayer_with_astro.md +24 -1
- package/docs/uk/intlayer_with_astro_lit.md +25 -1
- package/docs/uk/intlayer_with_astro_preact.md +26 -1
- package/docs/uk/intlayer_with_astro_react.md +26 -1
- package/docs/uk/intlayer_with_astro_solid.md +26 -1
- package/docs/uk/intlayer_with_astro_svelte.md +25 -1
- package/docs/uk/intlayer_with_astro_vue.md +25 -1
- package/docs/uk/intlayer_with_remix_3.md +22 -1
- package/docs/uk/self_hosting.md +413 -238
- package/docs/vi/benchmark/nextjs.md +19 -16
- package/docs/vi/benchmark/solid.md +26 -9
- package/docs/vi/benchmark/svelte.md +22 -7
- package/docs/vi/benchmark/tanstack.md +20 -16
- package/docs/vi/benchmark/vue.md +20 -11
- package/docs/vi/chrome_extension.md +130 -0
- package/docs/vi/cli/index.md +11 -1
- package/docs/vi/cli/infra.md +162 -0
- package/docs/vi/cli/init.md +24 -1
- package/docs/vi/cli/upgrade.md +125 -0
- package/docs/vi/dictionary/html.md +173 -5
- package/docs/vi/dictionary/markdown.md +263 -1
- package/docs/vi/intlayer_with_analog.md +23 -1
- package/docs/vi/intlayer_with_angular_19.md +24 -1
- package/docs/vi/intlayer_with_angular_21.md +24 -1
- package/docs/vi/intlayer_with_astro.md +24 -1
- package/docs/vi/intlayer_with_astro_lit.md +25 -1
- package/docs/vi/intlayer_with_astro_preact.md +26 -1
- package/docs/vi/intlayer_with_astro_react.md +26 -1
- package/docs/vi/intlayer_with_astro_solid.md +26 -1
- package/docs/vi/intlayer_with_astro_svelte.md +25 -1
- package/docs/vi/intlayer_with_astro_vue.md +25 -1
- package/docs/vi/intlayer_with_remix_3.md +22 -1
- package/docs/vi/self_hosting.md +408 -234
- package/docs/zh/benchmark/nextjs.md +19 -16
- package/docs/zh/benchmark/solid.md +26 -9
- package/docs/zh/benchmark/svelte.md +22 -7
- package/docs/zh/benchmark/tanstack.md +19 -15
- package/docs/zh/benchmark/vue.md +20 -11
- package/docs/zh/chrome_extension.md +130 -0
- package/docs/zh/cli/index.md +11 -1
- package/docs/zh/cli/infra.md +162 -0
- package/docs/zh/cli/init.md +24 -1
- package/docs/zh/cli/upgrade.md +125 -0
- package/docs/zh/dictionary/html.md +172 -5
- package/docs/zh/dictionary/markdown.md +262 -1
- package/docs/zh/intlayer_with_analog.md +23 -1
- package/docs/zh/intlayer_with_angular_19.md +24 -1
- package/docs/zh/intlayer_with_angular_21.md +24 -1
- package/docs/zh/intlayer_with_astro.md +24 -1
- package/docs/zh/intlayer_with_astro_lit.md +25 -1
- package/docs/zh/intlayer_with_astro_preact.md +26 -1
- package/docs/zh/intlayer_with_astro_react.md +26 -1
- package/docs/zh/intlayer_with_astro_solid.md +26 -1
- package/docs/zh/intlayer_with_astro_svelte.md +25 -1
- package/docs/zh/intlayer_with_astro_vue.md +25 -1
- package/docs/zh/intlayer_with_remix_3.md +22 -1
- package/docs/zh/self_hosting.md +410 -237
- package/legal/ar/privacy_notice.md +9 -3
- package/legal/de/privacy_notice.md +9 -3
- package/legal/en/privacy_notice.md +10 -3
- package/legal/en-GB/privacy_notice.md +9 -3
- package/legal/es/privacy_notice.md +9 -3
- package/legal/fr/privacy_notice.md +9 -3
- package/legal/hi/privacy_notice.md +9 -3
- package/legal/id/privacy_notice.md +9 -3
- package/legal/it/privacy_notice.md +9 -3
- package/legal/ja/privacy_notice.md +9 -3
- package/legal/ko/privacy_notice.md +9 -3
- package/legal/pl/privacy_notice.md +9 -3
- package/legal/pt/privacy_notice.md +9 -3
- package/legal/ru/privacy_notice.md +9 -3
- package/legal/tr/privacy_notice.md +9 -3
- package/legal/uk/privacy_notice.md +9 -3
- package/legal/vi/privacy_notice.md +9 -3
- package/legal/zh/privacy_notice.md +9 -3
- package/package.json +6 -6
- package/src/generated/blog.entry.ts +20 -0
- package/src/generated/docs.entry.ts +60 -40
- package/docs/ar/roadmap.md +0 -321
- package/docs/de/roadmap.md +0 -322
- package/docs/en/intlayer_with_astro_vanilla.md +0 -713
- package/docs/en/roadmap.md +0 -325
- package/docs/en-GB/roadmap.md +0 -322
- package/docs/es/roadmap.md +0 -322
- package/docs/fr/roadmap.md +0 -322
- package/docs/hi/roadmap.md +0 -322
- package/docs/id/roadmap.md +0 -325
- package/docs/it/roadmap.md +0 -322
- package/docs/ja/roadmap.md +0 -322
- package/docs/ko/roadmap.md +0 -322
- package/docs/pl/roadmap.md +0 -325
- package/docs/pt/roadmap.md +0 -322
- package/docs/ru/roadmap.md +0 -322
- package/docs/tr/roadmap.md +0 -325
- package/docs/uk/roadmap.md +0 -325
- package/docs/vi/roadmap.md +0 -325
- package/docs/zh/roadmap.md +0 -322
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-09-23
|
|
3
|
+
updatedAt: 2026-09-23
|
|
4
|
+
title: هل Intlayer أخف من Paraglide؟
|
|
5
|
+
description: يبدو Paraglide شبه مجاني في اختبارات أداء التدويل (i18n) لأن كوده يتم توليده مباشرة في مستودع مشروعك. نوضح هنا إلى أين يذهب ذلك الحجم فعلياً، ولماذا يكلفك فحص اللغة لكل عقدة أداءً إضافياً، وكيف يشحن التحميل الديناميكي في Intlayer لغة واحدة بدلاً من جميع اللغات.
|
|
6
|
+
keywords:
|
|
7
|
+
- Paraglide
|
|
8
|
+
- Intlayer
|
|
9
|
+
- تدويل
|
|
10
|
+
- i18n
|
|
11
|
+
- Bundle size
|
|
12
|
+
- Tree shaking
|
|
13
|
+
- Benchmark
|
|
14
|
+
- Blog
|
|
15
|
+
slugs:
|
|
16
|
+
- blog
|
|
17
|
+
- is-intlayer-lighter-than-paraglide
|
|
18
|
+
author: aymericzip
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# هل Intlayer أخف من Paraglide؟
|
|
22
|
+
|
|
23
|
+
نعم.
|
|
24
|
+
|
|
25
|
+
يحظى `Paraglide` بسمعة جيدة باعتباره أخف حلول التدويل المتاحة، وللوهلة الأولى يتفق [اختبار الأداء](https://intlayer.org/ar/doc/benchmark/tanstack) مع ذلك: فحجم مكتبته يقارب الصفر. لكن حجم مكتبة يقارب الصفر لا يعني إرسال صفر بايت إلى المتصفح. هذا يعني ببساطة أن البايتات تستقر في مكان لا ترصده تلك المعايير.
|
|
26
|
+
|
|
27
|
+
<TOC/>
|
|
28
|
+
|
|
29
|
+
## النقاط الرئيسية
|
|
30
|
+
|
|
31
|
+
**حجم المكتبة مخفي، وليس محذوفاً:**
|
|
32
|
+
|
|
33
|
+
يولد Paraglide وقت التشغيل (runtime) ودوال الرسائل الخاصة به مباشرة في قاعدة الكود (codebase) لديك. يتم شحن هذا الكود إلى المتصفح، لكنه يُحسب ككود _خاص بك_، وليس ككود للمكتبة.
|
|
34
|
+
|
|
35
|
+
**غياب الـ Provider ليس مكسباً مجانياً:**
|
|
36
|
+
|
|
37
|
+
كل استدعاء للدالة `m.my_key()` يحدد اللغة بنفسه، حيث يقرأ ملف تعريف الارتباط (cookie) أو التخزين المحلي لكل عقدة يتم تصييرها (render)، بدلاً من قراءتها مرة واحدة فقط من السياق (context).
|
|
38
|
+
|
|
39
|
+
**لا يوجد تحميل ديناميكي (Dynamic Loading):**
|
|
40
|
+
|
|
41
|
+
يستورد Paraglide كل لغات الرسالة في حزمة العميل (client bundle). بينما يقوم Intlayer مع خيار `importMode: 'dynamic'` أو `'fetch'` بتحميل اللغة التي يتم عرضها حالياً فقط.
|
|
42
|
+
|
|
43
|
+
**الـ Tree Shaking ليس مضموناً دائماً:**
|
|
44
|
+
|
|
45
|
+
في بعض اختبارات الأداء لدينا، لم تعمل ميزة Tree Shaking المعلن عنها في Paraglide بالشكل المطلوب. نوصي بفحص الحزمة الخاصة بك.
|
|
46
|
+
|
|
47
|
+
## أين يذهب حجم Paraglide الفعلي؟
|
|
48
|
+
|
|
49
|
+
في تقارير المقارنة المعيارية، يقيس مقياس "حجم المكتبة" الـ provider والـ hooks لكل مكتبة i18n في مكون فارغ، قبل إضافة أي محتوى.
|
|
50
|
+
|
|
51
|
+
| المكتبة (TanStack Start) | حجم المكتبة (gz) | حجم المكتبة (min) |
|
|
52
|
+
| ----------------------------- | ---------------- | ----------------- |
|
|
53
|
+
| `@inlang/paraglide-js@2.15.1` | 1.8 KB | 4.5 KB |
|
|
54
|
+
| `react-intlayer@9.5.1` | 5.0 KB | 15.2 KB |
|
|
55
|
+
|
|
56
|
+
إذا قرأت هذه الأرقام بمعزل عن السياق، يبدو أن Paraglide هو الفائز. لكن Paraglide عبارة عن مترجم (compiler): فهو يقرأ ملفات `messages/*.json` الخاصة بك وينشئ مجلد `paraglide/` داخل مستودع مشروعك، ويحتوي على ملف `runtime.js` (اكتشاف اللغة، استراتيجيات الكوكيز والتخزين، وتوطين الروابط) ودالة جافاسكريبت واحدة لكل رسالة.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
src/paraglide/
|
|
60
|
+
├── runtime.js # اكتشاف اللغة، الاستراتيجيات، مساعدات الروابط
|
|
61
|
+
├── server.js
|
|
62
|
+
├── messages.js # إعادة تصدير كافة الرسائل
|
|
63
|
+
└── messages/
|
|
64
|
+
├── _index.js
|
|
65
|
+
├── en.js
|
|
66
|
+
└── fr.js
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
نظراً لأن هذا الكود يستقر داخل مجلد `src/` الخاص بك وتقوم باستيراده بمسار نسبي، فإن أداة الحزم (bundler) تنسبه إلى تطبيقك، وليس إلى حزمة خارجية في `node_modules`. لذلك يُظهر عمود حجم المكتبة رقماً يقارب الصفر، في حين أن نفس المنطق البرمجي يُشحن فعلياً ضمن حزمة صفحتك.
|
|
70
|
+
|
|
71
|
+
توليد الكود ليس فكرة سيئة بحد ذاته: فوقت التشغيل المولد لا يتضمن سوى المنطق الذي تتطلبه إعداداتك (استراتيجية البادئة، الكوكيز مقابل التخزين المحلي، إلخ). ويحقق Intlayer نفس النتيجة بأسلوب مختلف، عن طريق حقن متغيرات البيئة أثناء مرحلة البناء، مما يسمح لأداة الحزم بحذف الفروع البرمجية التي لا تستخدمها إعداداتك. كلا الأسلوبين ينتهي بهما الأمر أخف بما يتراوح بين 3 إلى 10 مرات مقارنة بـ `i18next` أو `next-intl`.
|
|
72
|
+
|
|
73
|
+
لذا، فإن المقارنة العادلة ليست حجم المكتبة المجرد. بل هي **كمية الجافاسكريبت المرسلة فعلياً لكل صفحة**.
|
|
74
|
+
|
|
75
|
+
## وزن الصفحة المقاس فعلياً
|
|
76
|
+
|
|
77
|
+
تطبيق TanStack Start، يتكون من 10 صفحات، تم القياس على مساري `en` و `fr`، بضغط gzip:
|
|
78
|
+
|
|
79
|
+
| الإعداد | متوسط JS للصفحة (gz) | الزيادة عن الأساس | تسريب اللغات | تسريب الصفحات الأخرى |
|
|
80
|
+
| ---------------------------------- | -------------------- | ----------------- | ------------ | -------------------- |
|
|
81
|
+
| الأساس (بدون i18n) | 111.0 KB | - | 0.0% | 0.0% |
|
|
82
|
+
| `paraglide` (أي استراتيجية) | 125.1 KB | +14.1 KB | 49.7% | 0.0% |
|
|
83
|
+
| `intlayer` (`importMode: static`) | 125.8 KB | +14.8 KB | 50.0% | 0.0% |
|
|
84
|
+
| `intlayer` (`importMode: dynamic`) | **118.6 KB** | **+7.6 KB** | **0.0%** | **0.0%** |
|
|
85
|
+
|
|
86
|
+
تطبيق Next.js 16 App Router، نفس التطبيق:
|
|
87
|
+
|
|
88
|
+
| الإعداد | متوسط JS للصفحة (gz) | الزيادة عن الأساس |
|
|
89
|
+
| ------------------ | -------------------- | ----------------- |
|
|
90
|
+
| الأساس (بدون i18n) | 141.0 KB | - |
|
|
91
|
+
| `paraglide-next` | 155.3 KB | +14.3 KB |
|
|
92
|
+
| `next-intlayer` | **141.3 KB** | **+0.3 KB** |
|
|
93
|
+
|
|
94
|
+
<I18nBenchmark framework="tanstack" vertical/>
|
|
95
|
+
|
|
96
|
+
> البيانات الكاملة متوفرة في [تقرير مقارنة TanStack Start](https://intlayer.org/ar/doc/benchmark/tanstack) و[تقرير مقارنة Next.js](https://intlayer.org/ar/doc/benchmark/nextjs). يمكن فحص كل حزمة في [مستودع اختبارات الأداء](https://github.com/intlayer-org/benchmark-i18n).
|
|
97
|
+
|
|
98
|
+
هناك نقطتان واضحتان:
|
|
99
|
+
|
|
100
|
+
- في الوضع الثابت (`static`)، يرسل Intlayer نفس المحتوى تقريباً مقارنة بـ Paraglide (125.8 KB مقابل 125.1 KB). وهذا أمر متوقع: فكلاهما يضم جميع لغات الرسائل التي تستخدمها الصفحة.
|
|
101
|
+
- يظل Paraglide عند 125.1 KB مهما كانت الاستراتيجية المستخدمة، لأنه لا يحتوي على وضع ديناميكي. كل سطر في الجدول أعلاه يمثل النمط الثابت.
|
|
102
|
+
|
|
103
|
+
## غياب الـ Provider: فكرة تبدو جذابة ولكنها ليست كذلك
|
|
104
|
+
|
|
105
|
+
لا يتطلب Paraglide استخدام Provider. كل ما تفعله هو استيراد الرسالة واستدعاؤها:
|
|
106
|
+
|
|
107
|
+
```tsx fileName="Hero.tsx"
|
|
108
|
+
import { m } from "../paraglide/messages.js";
|
|
109
|
+
|
|
110
|
+
export const Hero = () => (
|
|
111
|
+
<section>
|
|
112
|
+
<h1>{m.hero_title()}</h1>
|
|
113
|
+
<p>{m.hero_description()}</p>
|
|
114
|
+
<button>{m.hero_cta()}</button>
|
|
115
|
+
</section>
|
|
116
|
+
);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
لا سياق، لا غلاف، ولا خطافات (hooks). يبدو الأمر أبسط. لكن اللغة لا تزال بحاجة إلى تحديد مصدرها. تبدو كل دالة رسالة مولدة تقريباً على هذا النحو (بشكل مبسط):
|
|
120
|
+
|
|
121
|
+
```js fileName="paraglide/messages/_index.js"
|
|
122
|
+
export const hero_title = (inputs = {}, options = {}) => {
|
|
123
|
+
const locale = options.locale ?? getLocale(); // يتم تحديدها عند كل استدعاء
|
|
124
|
+
|
|
125
|
+
if (locale === "en") return en.hero_title(inputs);
|
|
126
|
+
if (locale === "fr") return fr.hero_title(inputs);
|
|
127
|
+
// ...فرع برمجي لكل لغة
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
وتقوم `getLocale()` بفحص الاستراتيجيات المحددة (الكوكيز، التخزين المحلي، الرابط، اللغة الأساسية) لمعرفة اللغة الحالية. هذا يعني أن كل عقدة نصية تصيّرها (`<>{m.my_key()}</>`) تقوم بتشغيل عملية تحديد لغة مستقلة، بما في ذلك قراءة `document.cookie` في المتصفح. صفحة تحتوي على 200 نص مترجم تقوم بتحديد اللغة 200 مرة في كل عملية تصيير، وتتكرر العملية مع كل إعادة تصيير.
|
|
132
|
+
|
|
133
|
+
في المقابل، فإن المكتبة التي تعتمد على Provider تقرأ اللغة **مرة واحدة فقط**، وتخزنها في سياق (أو signal، أو store)، وتقرأ كل عقدة قيمة مخزنة مسبقاً في الذاكرة. يكلف الـ Provider بضع مئات من البايتات فقط. وتخطي استخدامه يستهلك دورات المعالج مع كل تصيير، وهو ما يتضح جلياً في اختبار الأداء: فأوقات تحميل الصفحة وسرعة تبديل اللغة في Paraglide تتأخر باستمرار مقارنة بـ Intlayer على TanStack Start (22.1 مللي ثانية مقابل 14.6 مللي ثانية في تحميل الصفحة، و 4.3 مللي ثانية مقابل 3.2 مللي ثانية في الاستجابة E2E).
|
|
134
|
+
|
|
135
|
+
## تجربة المطور (DX)
|
|
136
|
+
|
|
137
|
+
مصدر الحقيقة في Paraglide هو ملفات JSON، لكنك لا تستورد ملف الـ JSON مطلقاً، بل تستورد ملف الـ `.js` المولد:
|
|
138
|
+
|
|
139
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
140
|
+
<Tab label="Paraglide" value="paraglide">
|
|
141
|
+
|
|
142
|
+
```json fileName="messages/en.json"
|
|
143
|
+
{
|
|
144
|
+
"hero_title": "Ship your app in every language"
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```json fileName="messages/ar.json"
|
|
149
|
+
{
|
|
150
|
+
"hero_title": "انشر تطبيقك بكل اللغات"
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```tsx fileName="Hero.tsx"
|
|
155
|
+
// لا يوجد هذا الملف إلا بعد أن يعيد المترجم توليده من ملف الـ JSON
|
|
156
|
+
import { m } from "../paraglide/messages.js";
|
|
157
|
+
|
|
158
|
+
export const Hero = () => <h1>{m.hero_title()}</h1>;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
</Tab>
|
|
162
|
+
<Tab label="Intlayer" value="intlayer">
|
|
163
|
+
|
|
164
|
+
```ts fileName="Hero.content.ts"
|
|
165
|
+
import { t, type Dictionary } from "intlayer";
|
|
166
|
+
|
|
167
|
+
export default {
|
|
168
|
+
key: "hero",
|
|
169
|
+
content: {
|
|
170
|
+
title: t({
|
|
171
|
+
ar: "انشر تطبيقك بكل اللغات",
|
|
172
|
+
en: "Ship your app in every language",
|
|
173
|
+
}),
|
|
174
|
+
},
|
|
175
|
+
} satisfies Dictionary;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```tsx fileName="Hero.tsx"
|
|
179
|
+
import { useIntlayer } from "react-intlayer";
|
|
180
|
+
|
|
181
|
+
export const Hero = () => {
|
|
182
|
+
const { title } = useIntlayer("hero");
|
|
183
|
+
|
|
184
|
+
return <h1>{title}</h1>;
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
</Tab>
|
|
189
|
+
</Tabs>
|
|
190
|
+
|
|
191
|
+
هذا النمط في العمل له ثمن:
|
|
192
|
+
|
|
193
|
+
- كل تعديل على ملف JSON يتطلب إعادة توليد قبل أن يتم التعرف على الاستيراد أو تتحدث الأنواع (types).
|
|
194
|
+
- مجلد `paraglide/` المولد إما أن يتم إدراجه في git (مما يؤدي لتعارضات دمج في الملفات المولدة مع كل طلب سحب PR يمس النصوص)، أو يتم تجاهله (مما يتطلب خطوة توليد إلزامية قبل كل فحص للأنواع أو اختبار أو مهمة CI).
|
|
195
|
+
- كل نص يتحول إلى استدعاء دالة. وتتحول الثوابت إلى `m.key()` في كل مكان، حتى في الأماكن التي تكفي فيها قيمة ثابتة بسيطة.
|
|
196
|
+
|
|
197
|
+
## Tree Shaking: افحص الحزمة الخاصة بك
|
|
198
|
+
|
|
199
|
+
الوعد الأساسي لـ Paraglide هو أن الرسائل غير المستخدمة يتم التخلص منها عبر الـ Tree Shaking لأن كل رسالة تصدر كعنصر مستقل. وفي اختبار Svelte + Vite، عملت هذه الميزة كما هو متوقع.
|
|
200
|
+
|
|
201
|
+
لكن في بيئات أخرى، لم يتحقق ذلك. ففي اختبارنا على [Next.js](https://intlayer.org/ar/doc/benchmark/nextjs)، زادت صفحات Paraglide بمقدار 14 KB مقارنة بالتطبيق الأساسي، بينما أضاف `next-intlayer` فقط 0.3 KB. كما أظهرت اختبارات سابقة على TanStack Start تسرب رسائل من صفحات أخرى إلى حزمة المسار الحالي.
|
|
202
|
+
|
|
203
|
+
يعتمد الـ Tree Shaking على أداة الحزم لديك (Turbopack، Rolldown، Rollup)، وعلى طريقة استيراد الرسائل (`import { m }` مقابل `import * as m`)، وعلى تحليل الآثار الجانبية (side-effects). إذا اخترت Paraglide لصغر حجمه، افتح أداة فحص الحزم وتأكد من تحقق ذلك في تطبيقك الفعلي.
|
|
204
|
+
|
|
205
|
+
## غياب التحميل الديناميكي
|
|
206
|
+
|
|
207
|
+
هذا هو العائق البنيوي الأبرز. لا يمتلك Paraglide وسيلة لتحميل لغة واحدة في كل مرة: فكل دالة رسالة تستورد تنفيذ كل اللغات بشكل ثابت، مما يجعل جميع اللغات تنتهي داخل حزمة العميل الخاصة بك.
|
|
208
|
+
|
|
209
|
+
عند دعم لغتين، يتم هدر نصف بيانات الترجمة المنقولة، وهو ما يطابق نسبة تسريب اللغات المقدرة بـ ~50% أعلاه. ومع 10 لغات، يرتفع الهدر إلى 90%. ومع 30 لغة، يصل إلى 97%.
|
|
210
|
+
|
|
211
|
+
والانتقال إلى التحميل الديناميكي لن يحل المشكلة أيضاً: فمع وجود دالة مستقلة لكل رسالة، فإن تحميل كل دالة بشكل كسول سيعني إطلاق آلاف الطلبات عبر الشبكة.
|
|
212
|
+
|
|
213
|
+
يتيح لك Intlayer حرية الاختيار، سواء على المستوى العام للتطبيق أو لكل قاموس على حدة:
|
|
214
|
+
|
|
215
|
+
```ts fileName="intlayer.config.ts"
|
|
216
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
217
|
+
|
|
218
|
+
const config: IntlayerConfig = {
|
|
219
|
+
internationalization: {
|
|
220
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
221
|
+
defaultLocale: Locales.ENGLISH,
|
|
222
|
+
},
|
|
223
|
+
dictionary: {
|
|
224
|
+
importMode: "dynamic", // 'static' | 'dynamic' | 'fetch'
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default config;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
| `importMode` | ما يتم إرساله إلى العميل | مقارنة بـ Paraglide |
|
|
232
|
+
| ------------ | --------------------------------------------------- | ------------------------------ |
|
|
233
|
+
| `static` | جميع لغات القواميس التي تستخدمها الصفحة | نفس المحتوى نظرياً |
|
|
234
|
+
| `dynamic` | اللغة الحالية فقط، محملة بكسل لكل قاموس | **أخف بـ N مرة** مع وجود N لغة |
|
|
235
|
+
| `fetch` | اللغة الحالية فقط، مجلوبة عبر واجهة برمجة Live Sync | **أخف بـ N مرة** مع وجود N لغة |
|
|
236
|
+
|
|
237
|
+
بفضل [التحويل أثناء البناء](https://intlayer.org/ar/doc/concept/bundle-optimization) وخيار `importMode: 'static'`، يحمّل Intlayer نظرياً نفس المحتوى تماماً مثل Paraglide. ومع استخدام `'dynamic'` أو `'fetch'`، فإنه يحمّل فقط ما تتطلبه اللغة الحالية: لتطبيق يدعم N لغة، تصبح حمولة الترجمة أصغر بـ N مرة مقارنة بـ Paraglide.
|
|
238
|
+
|
|
239
|
+
## متى يظل Paraglide خياراً مناسباً؟
|
|
240
|
+
|
|
241
|
+
<AccordionGroup>
|
|
242
|
+
<Accordion header="تطبيقات Svelte + Vite مع عدد قليل من اللغات">
|
|
243
|
+
|
|
244
|
+
إذا كانت بيئة تطويرك تعتمد على Svelte مع Vite وتدعم لغتين أو ثلاث، فإن الـ Tree Shaking يعمل كما ينبغي ويبقى العبء الإضافي للغات محدوداً.
|
|
245
|
+
|
|
246
|
+
</Accordion>
|
|
247
|
+
<Accordion header="سير العمل القائم حالياً على inlang">
|
|
248
|
+
|
|
249
|
+
إذا كان فريقك يستخدم بالفعل منظومة inlang (مثل Fink و Sherlock وإضافات صيغ الرسائل)، فإن Paraglide يتكامل معها بشكل أصيل وسلس.
|
|
250
|
+
|
|
251
|
+
</Accordion>
|
|
252
|
+
</AccordionGroup>
|
|
253
|
+
|
|
254
|
+
## جربه على تطبيقك
|
|
255
|
+
|
|
256
|
+
تحقق من حجم تطبيقك الحي ومستوى تسريب اللغات باستخدام أداة [i18n SEO Scanner](https://intlayer.org/i18n-seo-scanner) المجانية:
|
|
257
|
+
|
|
258
|
+
<ClickToOpenIframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
259
|
+
|
|
260
|
+
لتثبيت Intlayer:
|
|
261
|
+
|
|
262
|
+
```bash packageManager="npm"
|
|
263
|
+
npx intlayer init --interactive
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```bash packageManager="pnpm"
|
|
267
|
+
pnpm dlx intlayer init --interactive
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
```bash packageManager="yarn"
|
|
271
|
+
yarn dlx intlayer init --interactive
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```bash packageManager="bun"
|
|
275
|
+
bunx intlayer init --interactive
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## قراءات إضافية
|
|
279
|
+
|
|
280
|
+
- [اختبار أداء i18n في TanStack Start](https://intlayer.org/ar/doc/benchmark/tanstack)
|
|
281
|
+
- [اختبار أداء i18n في Next.js](https://intlayer.org/ar/doc/benchmark/nextjs)
|
|
282
|
+
- [تحسين الحزم و `importMode`](https://intlayer.org/ar/doc/concept/bundle-optimization)
|
|
283
|
+
- [كيفية اختيار مكتبة i18n المناسبة لـ React](https://intlayer.org/ar/blog/how-to-pick-react-i18n-library)
|
|
284
|
+
- [دواعي ومبررات التدويل المعتمد على المترجم](https://intlayer.org/ar/blog/compiler-vs-declarative-i18n)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-09-13
|
|
3
|
-
updatedAt: 2026-09-
|
|
3
|
+
updatedAt: 2026-09-22
|
|
4
4
|
title: "Lingui مقابل Intlayer: اختبار الأداء والمقارنة لعام 2026"
|
|
5
5
|
description: "مقارنة بين مكتبتي تدويل (i18n) تعتمدان على المترجم تم قياسهما على Next.js وTanStack Start. حجم الحزمة، تسرب المحتوى، حجم المكونات، الترطيب، سرعة تبديل اللغة وتجربة المطور."
|
|
6
6
|
keywords:
|
|
@@ -24,6 +24,8 @@ author: aymericzip
|
|
|
24
24
|
|
|
25
25
|
# Lingui مقابل Intlayer | مقارنة أداء التدويل (i18n) في React وNext.js
|
|
26
26
|
|
|
27
|
+

|
|
28
|
+
|
|
27
29
|
تعد Lingui وIntlayer المكتبتين الوحيدتين في هذا الاختبار اللتين تعتمدان على **مترجم (Compiler)** بدلاً من بيئة تشغيل بحتة (Pure Runtime). تستخرج Lingui الرسائل من وحدات الماكرو في وقت البناء وتقوم بتجميع الكتالوجات لكل لغة. بينما يقوم Intlayer بتجميع القواميس لكل مكون مع تقليم الشجرة (Tree-shaking) لكل لغة. نظرياً، يجب أن تكون النتائج متقاربة، لكن الأرقام توضح أين يختلفان.
|
|
28
30
|
|
|
29
31
|
البيانات مأخوذة من [Benchmark Bloom](https://github.com/intlayer-org/benchmark-bloom)، وهي مجموعة اختبارات مفتوحة المصدر تبني التطبيق نفسه مع كل مكتبة وتسجل ما يقوم المتصفح بتنزيله وتنفيذه فعلياً.
|
|
@@ -96,6 +98,10 @@ author: aymericzip
|
|
|
96
98
|
|
|
97
99
|
### النتائج على Next.js
|
|
98
100
|
|
|
101
|
+
اختر المقاييس والمكتبات التي تهمك:
|
|
102
|
+
|
|
103
|
+
<I18nBenchmark framework="nextjs" vertical/>
|
|
104
|
+
|
|
99
105
|
| المكتبة | الاستراتيجية | حجم المكتبة (gz) | متوسط JS للصفحة (gz) | تسرب اللغة | تسرب الصفحة | متوسط المكون (gz) | تفاعلية E2E | الترطيب |
|
|
100
106
|
| -------------------- | -------------- | ---------------: | -------------------: | ---------: | ----------: | ----------------: | ----------: | ------: |
|
|
101
107
|
| **base** (بدون i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
|
|
@@ -114,6 +120,15 @@ author: aymericzip
|
|
|
114
120
|
- **تسرب اللغة المصدرية.** حتى في التهيئات المحسنة، **تتسرب 3-15% من نصوص `en` داخل صفحات `fr`**. تحتفظ وحدات ماكرو Lingui بالرسالة المصدرية كخيار احتياطي، مما يجعلها تستقر في الحزمة بجوار الترجمة. بينما يقوم Intlayer بحل الخيارات الاحتياطية أثناء البناء ويرسل اللغة النشطة فقط.
|
|
115
121
|
- **تضخم حجم المكون في `scoped-dynamic`.** يبلغ متوسط حجم المكون المجمع بمعزل **152.6 كيلوبايت**، لأن كتالوج كل مسار يصبح قابلاً للوصول من المكون الذي يستورده. في المقابل يبلغ متوسط المكون نفسه مع `useIntlayer()` حوالي **6.9 كيلوبايت**.
|
|
116
122
|
|
|
123
|
+
<ClickToOpenIframe
|
|
124
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-nextjs.md"
|
|
125
|
+
width="100%"
|
|
126
|
+
height="600px"
|
|
127
|
+
style="border:none;"
|
|
128
|
+
/>
|
|
129
|
+
|
|
130
|
+
> الجدول الكامل، لكل مكتبة واستراتيجية، في [تقرير قياس أداء Next.js](https://intlayer.org/ar/doc/benchmark/nextjs).
|
|
131
|
+
|
|
117
132
|
### النتائج على TanStack Start
|
|
118
133
|
|
|
119
134
|
| المكتبة | الاستراتيجية | حجم المكتبة (gz) | متوسط JS للصفحة (gz) | تسرب اللغة | تسرب الصفحة | متوسط المكون (gz) | تفاعلية E2E | الترطيب |
|
|
@@ -135,8 +150,19 @@ author: aymericzip
|
|
|
135
150
|
- **يمتلك صف `static` في Intlayer نسبة تسرب 0% للصفحة تلقائياً** لأنه لا يتم تضمين سوى القواميس التي تستوردها مكونات الصفحة المعنية. سطر إعداد واحد (`importMode: 'dynamic'`) يزيل تسرب اللغة أيضاً.
|
|
136
151
|
- **مكتبة `@intlayer/lingui`** تحافظ على صياغة ماكرو Lingui وتخدمها من قواميس Intlayer، مما يوفر مكونات أصغر حجماً (12.8 كيلوبايت) وترطيباً أسرع بكثير من Lingui الأصلي. إنها خطوة انتقال ممتازة وليست الوجهة النهائية.
|
|
137
152
|
|
|
153
|
+
<ClickToOpenIframe
|
|
154
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-tanstack.md"
|
|
155
|
+
width="100%"
|
|
156
|
+
height="600px"
|
|
157
|
+
style="border:none;"
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
> الجدول الكامل في [تقرير قياس أداء TanStack Start](https://intlayer.org/ar/doc/benchmark/tanstack).
|
|
161
|
+
|
|
138
162
|
## لماذا هذا الفارق؟ مترجمان بوحدتي عمل مختلفتين
|
|
139
163
|
|
|
164
|
+

|
|
165
|
+
|
|
140
166
|
تعتمد كلتا المكتبتين على الترجمة البرمجية (Compilation)، لكن الفارق يكمن في **ما** تقومان بترجمته.
|
|
141
167
|
|
|
142
168
|
**يقوم Lingui بتجميع الكتالوجات.** يتم استخراج الماكرو في الكود المصدري إلى ملف `.po` لكل لغة، ثم تجميعه في وحدة JS لكل لغة. وحدة العمل هنا هي **اللغة**. ولتقسيمها بشكل أدق، حسب المسار أو المكون، يلزم إنشاء كتالوجات متعددة وتعديل `lingui.config.ts` والتحميل اليدوي لكل مسار. كائن `I18n` عام، وكل استدعاء لـ `useLingui()` يربط المكون به.
|
|
@@ -176,7 +202,9 @@ author: aymericzip
|
|
|
176
202
|
└── about.content.ts
|
|
177
203
|
```
|
|
178
204
|
|
|
179
|
-
لذلك فإن نمط `scoped-dynamic` هو نتاج بناء تلقائي لـ Intlayer، ومشروع تهيئة يدوي معقد لـ Lingui.
|
|
205
|
+
لذلك فإن نمط `scoped-dynamic` هو نتاج بناء تلقائي لـ Intlayer، ومشروع تهيئة يدوي معقد لـ Lingui. وتتسع الفجوة على محورين في وقت واحد، الصفحات واللغات:
|
|
206
|
+
|
|
207
|
+

|
|
180
208
|
|
|
181
209
|
> للحصول على أرقام صف `dynamic`، قم بضبط `dictionary.importMode: 'dynamic'` في ملف `intlayer.config.ts`. راجع [دليل تحسين الحزمة](https://intlayer.org/ar/doc/concept/bundle-optimization).
|
|
182
210
|
|
|
@@ -184,7 +212,8 @@ author: aymericzip
|
|
|
184
212
|
|
|
185
213
|
### الإعداد
|
|
186
214
|
|
|
187
|
-
|
|
215
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
216
|
+
<Tab label="Lingui" value="lingui">
|
|
188
217
|
|
|
189
218
|
```ts fileName="lingui.config.ts"
|
|
190
219
|
import { defineConfig } from "@lingui/cli";
|
|
@@ -215,7 +244,8 @@ export const loadCatalog = async (locale: string) => {
|
|
|
215
244
|
|
|
216
245
|
ثم إضافة `@lingui/babel-plugin-lingui-macro` (أو `@lingui/swc-plugin`) لأداة التحزيم، وتشغيل `lingui extract` بعد التعديل، و`lingui compile` قبل البناء، وتغليف الشجرة بـ `<I18nProvider i18n={i18n}>`.
|
|
217
246
|
|
|
218
|
-
|
|
247
|
+
</Tab>
|
|
248
|
+
<Tab label="Intlayer" value="intlayer">
|
|
219
249
|
|
|
220
250
|
```ts fileName="intlayer.config.ts"
|
|
221
251
|
import { type IntlayerConfig, Locales } from "intlayer";
|
|
@@ -232,9 +262,12 @@ export default config;
|
|
|
232
262
|
|
|
233
263
|
أضف `intlayer()` في `vite.config.ts` (أو `withIntlayer()` في `next.config.ts`) وغلف التطبيق بـ `<IntlayerProvider>`. لا حاجة لأي خطوة استخراج أو تجميع: تُبنى القواميس تلقائياً أثناء عمل أداة التحزيم.
|
|
234
264
|
|
|
265
|
+
</Tab>
|
|
266
|
+
</Tabs>
|
|
235
267
|
### المكونات
|
|
236
268
|
|
|
237
|
-
|
|
269
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
270
|
+
<Tab label="Lingui" value="lingui">
|
|
238
271
|
|
|
239
272
|
```tsx fileName="src/components/Counter.tsx"
|
|
240
273
|
import { useState } from "react";
|
|
@@ -258,7 +291,8 @@ export const Counter = () => {
|
|
|
258
291
|
|
|
259
292
|
يعيش النص الإنجليزي في المكون؛ ويعيش الفرنسي في `src/locales/fr/messages.po` تحت معرف مجزأ بعد تشغيل `lingui extract`. نسيان تشغيله أو نسيان `compile` يعيد النص بصمت إلى الإنجليزية.
|
|
260
293
|
|
|
261
|
-
|
|
294
|
+
</Tab>
|
|
295
|
+
<Tab label="Intlayer" value="intlayer">
|
|
262
296
|
|
|
263
297
|
```ts fileName="src/components/Counter/index.content.ts"
|
|
264
298
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -297,11 +331,14 @@ export const Counter = () => {
|
|
|
297
331
|
|
|
298
332
|
توجد كلتا اللغتين في ملف واحد بجوار المكون. غياب ترجمة `fr` يسبب خطأ في البناء، والمفتاح الخاطئ يسبب خطأ في TypeScript.
|
|
299
333
|
|
|
334
|
+
</Tab>
|
|
335
|
+
</Tabs>
|
|
300
336
|
### خارج المكونات
|
|
301
337
|
|
|
302
338
|
البيانات الوصفية (Metadata)، والـ loaders، ودوال الخادم: أي مكان خارج شجرة React.
|
|
303
339
|
|
|
304
|
-
|
|
340
|
+
<Tabs defaultTab="intlayer" group="techno">
|
|
341
|
+
<Tab label="Lingui" value="lingui">
|
|
305
342
|
|
|
306
343
|
```ts fileName="src/routes/$locale/about.tsx"
|
|
307
344
|
import { setupI18n } from "@lingui/core";
|
|
@@ -324,7 +361,8 @@ export const loader = async ({ params }: { params: { locale: string } }) => {
|
|
|
324
361
|
|
|
325
362
|
إنشاء كائن `I18n` جديد لكل استدعاء، وتحميل الكتالوج يدوياً، واستخدام `msg` + `i18n._()` بدلاً من `t`. كما تشير [ملاحظات الاختبار](https://github.com/intlayer-org/benchmark-bloom/blob/main/report/NOTE.md)، معرفة متى تستخدم `t` أو `` t` ` `` أو `i18n.t()` أو `msg` أو `<Trans>` "ليس بالأمر البديهي".
|
|
326
363
|
|
|
327
|
-
|
|
364
|
+
</Tab>
|
|
365
|
+
<Tab label="Intlayer" value="intlayer">
|
|
328
366
|
|
|
329
367
|
```ts fileName="src/routes/$locale/about.tsx"
|
|
330
368
|
import { getIntlayer } from "intlayer";
|
|
@@ -336,6 +374,9 @@ export const loader = async ({ params }: { params: { locale: string } }) => {
|
|
|
336
374
|
};
|
|
337
375
|
```
|
|
338
376
|
|
|
377
|
+
</Tab>
|
|
378
|
+
</Tabs>
|
|
379
|
+
|
|
339
380
|
## الاحتفاظ بماكرو Lingui مع قواميس Intlayer
|
|
340
381
|
|
|
341
382
|
تعد حزمة `@intlayer/lingui` محولاً مباشراً لـ `@lingui/core` و`@lingui/react`. تواصل وحدات الماكرو التجميع كالمعتاد، بينما يتم توفير تنفيذ `i18n._()` من قواميس Intlayer، مع مزامنة ملفات `.po` للاحتفاظ بكتالوجاتك الحالية. تعمل خيارات وصيغ الجمع في ICU بالطريقة نفسها.
|
|
@@ -353,16 +394,82 @@ export default defineConfig({
|
|
|
353
394
|
|
|
354
395
|
## متى تختار أياً منهما؟
|
|
355
396
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
397
|
+
<AccordionGroup>
|
|
398
|
+
<Accordion header="اختر Lingui">
|
|
399
|
+
|
|
400
|
+
أنت تريد **ICU MessageFormat** مع وحدات الماكرو المكتوبة، ومترجموك يعملون على ملفات **`.po`** مع مسار TMS حالي، وتفضل السلاسل المصدرية مضمنة داخل JSX، وفريقك مرتاح في إدارة تدفق الاستخراج والترجمة وتقسيم الكتالوجات. وحجم JS لكل صفحة تنافسي للغاية بمجرد إعداد التحميل الكسول.
|
|
401
|
+
|
|
402
|
+
</Accordion>
|
|
403
|
+
<Accordion header="اختر Intlayer">
|
|
404
|
+
|
|
405
|
+
أنت تريد **محتوى بنطاق محدد على مستوى المكونات**، و**TypeScript صارماً**، و**أخطاء المفاتيح المفقودة وقت البناء**، و**tree-shaking وتحميلاً كسولاً دون جهد**، ومكونات خفيفة، وتفعيل hydration سريعاً، وتبديلاً فورياً للغة، وأدوات تحرير مدمجة ([المحرر المرئي](https://intlayer.org/ar/doc/concept/editor)، [نظام إدارة المحتوى CMS](https://intlayer.org/ar/doc/concept/cms)، [الترجمة بالذكاء الاصطناعي](https://intlayer.org/ar/doc/concept/auto-fill)، [خادم MCP](https://intlayer.org/ar/doc/mcp-server)). ملائم للغاية لقواعد الكود الكبيرة والمعيارية وأنظمة التصميم.
|
|
406
|
+
|
|
407
|
+
</Accordion>
|
|
408
|
+
<Accordion header="اختر @intlayer/lingui">
|
|
409
|
+
|
|
410
|
+
أنت تستخدم Lingui حالياً وتريد الانتقال إلى قواميس Intlayer تدريجياً دون المساس بوحدات الماكرو. تظل كتالوجات `.po` الخاصة بك المصدر الوحيد للحقيقة عبر [إضافة مزامنة PO](https://intlayer.org/ar/doc/compatibility/lingui). تم قياسه جنباً إلى جنب في [Lingui مقابل @intlayer/lingui](https://intlayer.org/ar/blog/lingui-vs-intlayer-lingui).
|
|
411
|
+
|
|
412
|
+
</Accordion>
|
|
413
|
+
</AccordionGroup>
|
|
414
|
+
|
|
415
|
+
## الأسئلة الشائعة
|
|
416
|
+
|
|
417
|
+
<FAQ>
|
|
418
|
+
|
|
419
|
+
<Question title="Lingui تقوم بالترجمة والتجميع أيضاً، فلماذا تختلف النتائج إلى هذا الحد؟">
|
|
420
|
+
|
|
421
|
+
لأن وحدة التجميع والترجمة تختلف تماماً. تجمع Lingui **كتالوجاً واحداً لكل لغة**: وكل ما هو دون ذلك (كتالوجات لكل مسار، التحميل الكسول، استبعاد النصوص الاحتياطية من الحزمة) يتطلب تكويناً يدوياً. بينما تجمع Intlayer **قاموساً واحداً لكل مكون**، مما يجعل تحديد نطاق المسار مخرجاً طبيعياً للبناء. لهذا السبب يزن مكون Lingui المترجم بشكل منفصل 58-153 كيلوبايت مقابل 6-8 كيلوبايت فقط في Intlayer.
|
|
422
|
+
|
|
423
|
+
</Question>
|
|
424
|
+
|
|
425
|
+
<Question title="لماذا لا يصل تسريب اللغات أبداً إلى 0% مع Lingui؟">
|
|
426
|
+
|
|
427
|
+
تحتفظ وحدات الماكرو بالرسالة المصدرية كخيار احتياطي (fallback) في وقت التشغيل، مما يؤدي إلى شحن السلسلة الإنجليزية جنباً إلى جنب مع ترجمتها. يسجل الاختبار **3-15% من سلاسل `en` داخل صفحات `fr`** في كل إعداد مُحسَّن. بينما تعالج Intlayer الخيارات الاحتياطية أثناء البناء ولا ترسل سوى اللغة النشطة فقط.
|
|
428
|
+
|
|
429
|
+
</Question>
|
|
430
|
+
|
|
431
|
+
<Question title="هل كود JavaScript لكل صفحة في Lingui تنافسي حقاً؟">
|
|
432
|
+
|
|
433
|
+
نعم، بل إنه يتفوق بفارق ضئيل على TanStack Start: 115.2 كيلوبايت في وضع `dynamic` مقابل 118.6 كيلوبايت لـ Intlayer. فالكتالوجات المجمعة ذات المعرفات المجزأة مدمجة وصغيرة. لكن التكلفة تظهر في جوانب أخرى: الـ Hydration يستغرق 28-34 مللي ثانية مقابل 11-14 مللي ثانية، وتبديل اللغة يستغرق **42 مللي ثانية** في إعداد `scoped-dynamic`.
|
|
434
|
+
|
|
435
|
+
</Question>
|
|
436
|
+
|
|
437
|
+
<Question title="هل يجب علي التخلي عن الماكرو للانتقال؟">
|
|
438
|
+
|
|
439
|
+
لا. يحافظ `@intlayer/lingui` على ترجمة `` t`...` `` و `<Trans>` و `msg` و `plural` و `select` و `selectOrdinal` كما كانت تماماً؛ فقط ما يحلله `i18n._()` هو ما يتغير. احتفظ بـ `@lingui/babel-plugin-lingui-macro` أو `@lingui/swc-plugin` في البناء. راجع [وثائق توافق Lingui](https://intlayer.org/ar/doc/compatibility/lingui).
|
|
440
|
+
|
|
441
|
+
</Question>
|
|
442
|
+
|
|
443
|
+
<Question title="ماذا عن خطوات الاستخراج والتجميع؟">
|
|
444
|
+
|
|
445
|
+
تظل موجودة لوحدات الماكرو، وتختفي تماماً لمحتوى Intlayer الخاص. يتم بناء قواميس `.content.ts` تلقائياً عند تشغيل أداة الحزم، دون الحاجة إلى تشغيل أوامر CLI منفصلة، ويوقف أمر [`intlayer test`](https://intlayer.org/ar/doc/concept/cli) خط أنابيب CI عند وجود أي مفتاح مفقود بدلاً من الرجوع الصامت إلى السلسلة المصدرية.
|
|
446
|
+
|
|
447
|
+
</Question>
|
|
448
|
+
|
|
449
|
+
</FAQ>
|
|
359
450
|
|
|
360
451
|
## مقارنات ذات صلة
|
|
361
452
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
- [
|
|
365
|
-
- [
|
|
453
|
+
نفس الاختبار المرجعي، مكتبات أخرى:
|
|
454
|
+
|
|
455
|
+
- [next-intl vs Intlayer](https://intlayer.org/ar/blog/next-intl-vs-intlayer)
|
|
456
|
+
- [i18next vs Intlayer](https://intlayer.org/ar/blog/i18next-vs-intlayer)
|
|
457
|
+
- [vue-i18n vs Intlayer benchmark](https://intlayer.org/ar/blog/vue-i18n-vs-intlayer-benchmark)
|
|
458
|
+
- [next-i18next vs next-intl vs Intlayer](https://intlayer.org/ar/blog/next-i18next-vs-next-intl-vs-intlayer)
|
|
459
|
+
- [react-i18next vs react-intl vs Intlayer](https://intlayer.org/ar/blog/react-i18next-vs-react-intl-vs-intlayer)
|
|
460
|
+
|
|
461
|
+
للمزيد من التفاصيل:
|
|
462
|
+
|
|
463
|
+
- [Lingui vs @intlayer/lingui](https://intlayer.org/ar/blog/lingui-vs-intlayer-lingui), المحول المقاس على نفس التطبيق
|
|
464
|
+
- [Compiler-driven vs declarative i18n](https://intlayer.org/ar/blog/compiler-vs-declarative-i18n)
|
|
465
|
+
- [Per-component vs centralized i18n](https://intlayer.org/ar/blog/per-component-vs-centralized-i18n)
|
|
466
|
+
- [ICU message format explained](https://intlayer.org/ar/blog/icu-message-format)
|
|
467
|
+
|
|
468
|
+
وثائق مرجعية:
|
|
469
|
+
|
|
470
|
+
- [تقرير قياس أداء Next.js](https://intlayer.org/ar/doc/benchmark/nextjs) و [تقرير قياس أداء TanStack Start](https://intlayer.org/ar/doc/benchmark/tanstack)
|
|
471
|
+
- [Compat adapter: Lingui](https://intlayer.org/ar/doc/compatibility/lingui)
|
|
472
|
+
- [تحسين الحزمة](https://intlayer.org/ar/doc/concept/bundle-optimization) و [مترجم Intlayer](https://intlayer.org/ar/doc/compiler)
|
|
366
473
|
|
|
367
474
|
## نجوم GitHub
|
|
368
475
|
|