@intlayer/docs 8.9.4-canary.0 → 8.9.5
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/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/benchmark/index.md +0 -3
- package/docs/ar/benchmark/nextjs.md +15 -6
- package/docs/ar/benchmark/solid.md +155 -0
- package/docs/ar/benchmark/svelte.md +148 -0
- package/docs/ar/benchmark/tanstack.md +12 -3
- package/docs/ar/benchmark/vue.md +160 -0
- package/docs/ar/configuration.md +16 -12
- package/docs/ar/dictionary/content_file.md +51 -1
- package/docs/ar/mcp_server.md +30 -17
- package/docs/ar/plugins/sync-po.md +333 -0
- package/docs/bn/configuration.md +16 -12
- package/docs/cs/configuration.md +16 -12
- package/docs/de/benchmark/index.md +0 -3
- package/docs/de/benchmark/nextjs.md +15 -6
- package/docs/de/benchmark/solid.md +155 -0
- package/docs/de/benchmark/svelte.md +148 -0
- package/docs/de/benchmark/tanstack.md +12 -3
- package/docs/de/benchmark/vue.md +160 -0
- package/docs/de/configuration.md +16 -12
- package/docs/de/dictionary/content_file.md +52 -2
- package/docs/de/mcp_server.md +29 -16
- package/docs/de/plugins/sync-po.md +332 -0
- package/docs/en/benchmark/nextjs.md +11 -2
- package/docs/en/benchmark/solid.md +22 -4
- package/docs/en/benchmark/svelte.md +17 -5
- package/docs/en/benchmark/tanstack.md +18 -3
- package/docs/en/benchmark/vue.md +17 -11
- package/docs/en/configuration.md +16 -13
- package/docs/en/dictionary/content_file.md +51 -1
- package/docs/en/mcp_server.md +31 -18
- package/docs/en/plugins/sync-po.md +333 -0
- package/docs/en-GB/benchmark/index.md +0 -3
- package/docs/en-GB/benchmark/nextjs.md +15 -6
- package/docs/en-GB/benchmark/solid.md +155 -0
- package/docs/en-GB/benchmark/svelte.md +148 -0
- package/docs/en-GB/benchmark/tanstack.md +12 -3
- package/docs/en-GB/benchmark/vue.md +160 -0
- package/docs/en-GB/configuration.md +15 -11
- package/docs/en-GB/dictionary/content_file.md +51 -1
- package/docs/en-GB/mcp_server.md +31 -18
- package/docs/en-GB/plugins/sync-po.md +333 -0
- package/docs/es/benchmark/index.md +0 -3
- package/docs/es/benchmark/nextjs.md +15 -6
- package/docs/es/benchmark/solid.md +155 -0
- package/docs/es/benchmark/svelte.md +148 -0
- package/docs/es/benchmark/tanstack.md +12 -3
- package/docs/es/benchmark/vue.md +160 -0
- package/docs/es/configuration.md +16 -12
- package/docs/es/dictionary/content_file.md +51 -1
- package/docs/es/mcp_server.md +30 -17
- package/docs/es/plugins/sync-po.md +333 -0
- package/docs/fr/benchmark/index.md +0 -3
- package/docs/fr/benchmark/nextjs.md +15 -6
- package/docs/fr/benchmark/solid.md +155 -0
- package/docs/fr/benchmark/svelte.md +148 -0
- package/docs/fr/benchmark/tanstack.md +12 -3
- package/docs/fr/benchmark/vue.md +160 -0
- package/docs/fr/configuration.md +16 -12
- package/docs/fr/dictionary/content_file.md +51 -1
- package/docs/fr/mcp_server.md +30 -17
- package/docs/fr/plugins/sync-po.md +333 -0
- package/docs/hi/benchmark/nextjs.md +15 -6
- package/docs/hi/benchmark/solid.md +155 -0
- package/docs/hi/benchmark/svelte.md +148 -0
- package/docs/hi/benchmark/tanstack.md +12 -3
- package/docs/hi/benchmark/vue.md +160 -0
- package/docs/hi/configuration.md +16 -12
- package/docs/hi/dictionary/content_file.md +51 -1
- package/docs/hi/mcp_server.md +31 -18
- package/docs/hi/plugins/sync-po.md +333 -0
- package/docs/id/benchmark/index.md +0 -3
- package/docs/id/benchmark/nextjs.md +15 -6
- package/docs/id/benchmark/solid.md +155 -0
- package/docs/id/benchmark/svelte.md +148 -0
- package/docs/id/benchmark/tanstack.md +12 -3
- package/docs/id/benchmark/vue.md +160 -0
- package/docs/id/configuration.md +16 -12
- package/docs/id/dictionary/content_file.md +51 -1
- package/docs/id/mcp_server.md +30 -17
- package/docs/id/plugins/sync-po.md +333 -0
- package/docs/it/benchmark/index.md +1 -4
- package/docs/it/benchmark/nextjs.md +15 -6
- package/docs/it/benchmark/solid.md +155 -0
- package/docs/it/benchmark/svelte.md +148 -0
- package/docs/it/benchmark/tanstack.md +12 -3
- package/docs/it/benchmark/vue.md +160 -0
- package/docs/it/configuration.md +16 -12
- package/docs/it/dictionary/content_file.md +51 -1
- package/docs/it/mcp_server.md +30 -17
- package/docs/it/plugins/sync-po.md +333 -0
- package/docs/ja/benchmark/index.md +5 -5
- package/docs/ja/benchmark/nextjs.md +15 -6
- package/docs/ja/benchmark/solid.md +155 -0
- package/docs/ja/benchmark/svelte.md +148 -0
- package/docs/ja/benchmark/tanstack.md +12 -3
- package/docs/ja/benchmark/vue.md +160 -0
- package/docs/ja/configuration.md +16 -12
- package/docs/ja/dictionary/content_file.md +50 -2
- package/docs/ja/intlayer_with_nextjs_no_locale_path.md +4 -3
- package/docs/ja/mcp_server.md +29 -16
- package/docs/ja/plugins/sync-po.md +333 -0
- package/docs/ko/benchmark/nextjs.md +15 -6
- package/docs/ko/benchmark/solid.md +155 -0
- package/docs/ko/benchmark/svelte.md +148 -0
- package/docs/ko/benchmark/tanstack.md +12 -3
- package/docs/ko/benchmark/vue.md +160 -0
- package/docs/ko/configuration.md +16 -12
- package/docs/ko/dictionary/content_file.md +51 -1
- package/docs/ko/intlayer_with_nextjs_no_locale_path.md +3 -2
- package/docs/ko/mcp_server.md +31 -18
- package/docs/ko/plugins/sync-po.md +333 -0
- package/docs/nl/configuration.md +16 -12
- package/docs/pl/benchmark/index.md +0 -3
- package/docs/pl/benchmark/nextjs.md +15 -6
- package/docs/pl/benchmark/solid.md +155 -0
- package/docs/pl/benchmark/svelte.md +148 -0
- package/docs/pl/benchmark/tanstack.md +12 -3
- package/docs/pl/benchmark/vue.md +160 -0
- package/docs/pl/configuration.md +16 -12
- package/docs/pl/dictionary/content_file.md +51 -1
- package/docs/pl/mcp_server.md +30 -17
- package/docs/pl/plugins/sync-po.md +333 -0
- package/docs/pt/benchmark/index.md +0 -3
- package/docs/pt/benchmark/nextjs.md +16 -7
- package/docs/pt/benchmark/solid.md +155 -0
- package/docs/pt/benchmark/svelte.md +148 -0
- package/docs/pt/benchmark/tanstack.md +13 -4
- package/docs/pt/benchmark/vue.md +160 -0
- package/docs/pt/configuration.md +16 -12
- package/docs/pt/dictionary/content_file.md +51 -1
- package/docs/pt/mcp_server.md +30 -17
- package/docs/pt/plugins/sync-po.md +333 -0
- package/docs/ru/benchmark/nextjs.md +15 -6
- package/docs/ru/benchmark/solid.md +155 -0
- package/docs/ru/benchmark/svelte.md +148 -0
- package/docs/ru/benchmark/tanstack.md +12 -3
- package/docs/ru/benchmark/vue.md +160 -0
- package/docs/ru/configuration.md +16 -12
- package/docs/ru/dictionary/content_file.md +52 -2
- package/docs/ru/mcp_server.md +30 -17
- package/docs/ru/plugins/sync-po.md +333 -0
- package/docs/tr/benchmark/index.md +0 -3
- package/docs/tr/benchmark/nextjs.md +15 -6
- package/docs/tr/benchmark/solid.md +155 -0
- package/docs/tr/benchmark/svelte.md +148 -0
- package/docs/tr/benchmark/tanstack.md +12 -3
- package/docs/tr/benchmark/vue.md +160 -0
- package/docs/tr/configuration.md +16 -12
- package/docs/tr/dictionary/content_file.md +51 -1
- package/docs/tr/mcp_server.md +31 -18
- package/docs/tr/plugins/sync-po.md +333 -0
- package/docs/uk/benchmark/nextjs.md +15 -6
- package/docs/uk/benchmark/solid.md +155 -0
- package/docs/uk/benchmark/svelte.md +148 -0
- package/docs/uk/benchmark/tanstack.md +12 -3
- package/docs/uk/benchmark/vue.md +160 -0
- package/docs/uk/configuration.md +16 -12
- package/docs/uk/dictionary/content_file.md +51 -1
- package/docs/uk/mcp_server.md +29 -16
- package/docs/uk/plugins/sync-po.md +333 -0
- package/docs/ur/configuration.md +16 -12
- package/docs/vi/benchmark/index.md +0 -3
- package/docs/vi/benchmark/nextjs.md +15 -6
- package/docs/vi/benchmark/solid.md +155 -0
- package/docs/vi/benchmark/svelte.md +148 -0
- package/docs/vi/benchmark/tanstack.md +12 -3
- package/docs/vi/benchmark/vue.md +160 -0
- package/docs/vi/configuration.md +16 -12
- package/docs/vi/dictionary/content_file.md +51 -1
- package/docs/vi/intlayer_with_nextjs_15.md +10 -57
- package/docs/vi/mcp_server.md +30 -17
- package/docs/vi/plugins/sync-po.md +333 -0
- package/docs/zh/benchmark/nextjs.md +15 -6
- package/docs/zh/benchmark/solid.md +155 -0
- package/docs/zh/benchmark/svelte.md +148 -0
- package/docs/zh/benchmark/tanstack.md +12 -3
- package/docs/zh/benchmark/vue.md +160 -0
- package/docs/zh/configuration.md +16 -12
- package/docs/zh/dictionary/content_file.md +51 -3
- package/docs/zh/mcp_server.md +31 -18
- package/docs/zh/plugins/sync-po.md +333 -0
- package/frequent_questions/ar/intlayerNode.md +3 -3
- package/frequent_questions/de/intlayerNode.md +3 -3
- package/frequent_questions/en/intlayerNode.md +3 -3
- package/frequent_questions/en-GB/intlayerNode.md +3 -3
- package/frequent_questions/es/intlayerNode.md +3 -3
- package/frequent_questions/fr/intlayerNode.md +3 -3
- package/frequent_questions/hi/intlayerNode.md +3 -3
- package/frequent_questions/id/intlayerNode.md +3 -3
- package/frequent_questions/it/intlayerNode.md +3 -3
- package/frequent_questions/ja/intlayerNode.md +3 -3
- package/frequent_questions/ko/intlayerNode.md +3 -3
- package/frequent_questions/pl/intlayerNode.md +3 -3
- package/frequent_questions/pt/intlayerNode.md +3 -3
- package/frequent_questions/ru/intlayerNode.md +3 -3
- package/frequent_questions/tr/intlayerNode.md +3 -3
- package/frequent_questions/uk/intlayerNode.md +3 -3
- package/frequent_questions/vi/intlayerNode.md +3 -3
- package/frequent_questions/zh/intlayerNode.md +3 -3
- package/package.json +8 -8
- package/src/generated/docs.entry.ts +20 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-05-10
|
|
3
|
+
updatedAt: 2026-05-10
|
|
4
|
+
title: Sync PO प्लगइन
|
|
5
|
+
description: Intlayer शब्दकोशों को Gettext PO फ़ाइलों के साथ सिंक करें। अपने संदेशों को प्रबंधित करने, अनुवाद करने और परीक्षण करने के लिए Intlayer का उपयोग करते हुए अपने मौजूदा i18n को बनाए रखें।
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- Sync PO
|
|
9
|
+
- Gettext
|
|
10
|
+
- i18n
|
|
11
|
+
- अनुवाद
|
|
12
|
+
slugs:
|
|
13
|
+
- doc
|
|
14
|
+
- plugin
|
|
15
|
+
- sync-po
|
|
16
|
+
youtubeVideo: https://www.youtube.com/watch?v=MpGMxniDHNg
|
|
17
|
+
history:
|
|
18
|
+
- version: 8.9.4
|
|
19
|
+
date: 2026-05-10
|
|
20
|
+
changes: "Sync PO प्लगइन का प्रारंभिक दस्तावेज़ीकरण"
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Sync PO (i18n ब्रिज) - ICU / i18next समर्थन के साथ Sync PO
|
|
24
|
+
|
|
25
|
+
अपने मौजूदा i18n स्टैक के ऐड-ऑन के रूप में Intlayer का उपयोग करें। यह प्लगइन आपके Gettext PO संदेशों को Intlayer शब्दकोशों के साथ सिंक में रखता है ताकि आप:
|
|
26
|
+
|
|
27
|
+
- अपने मौजूदा PO-आधारित अनुवाद वर्कफ़्लो को बनाए रख सकें।
|
|
28
|
+
- अपने ऐप को रिफैक्टर किए बिना Intlayer (CLI, CI, प्रदाता, CMS) के साथ अपने संदेशों को प्रबंधित और अनुवाद कर सकें।
|
|
29
|
+
- प्रत्येक पारिस्थितिकी तंत्र को लक्षित करते हुए ट्यूटोरियल और SEO सामग्री भेज सकें, जबकि Intlayer को PO प्रबंधन परत के रूप में सुझा सकें।
|
|
30
|
+
|
|
31
|
+
नोट्स और वर्तमान दायरा:
|
|
32
|
+
|
|
33
|
+
- CMS के लिए बाहरीकरण अनुवादों और क्लासिक टेक्स्ट के लिए काम करता है।
|
|
34
|
+
- PO प्रविष्टियों के भीतर प्रविष्टि, बहुवचन/ICU, या अन्य पुस्तकालयों की उन्नत रनटाइम सुविधाओं के लिए अभी तक कोई समर्थन नहीं है।
|
|
35
|
+
- विज़ुअल एडिटर अभी तक तृतीय-पक्ष i18n आउटपुट के लिए समर्थित नहीं है।
|
|
36
|
+
|
|
37
|
+
### इस प्लगइन का उपयोग कब करें
|
|
38
|
+
|
|
39
|
+
- आप पहले से ही अपने अनुवादों के लिए Gettext PO फ़ाइलों का उपयोग करते हैं।
|
|
40
|
+
- आप अपने रेंडरिंग रनटाइम को बदले बिना AI-सहायता प्राप्त फिल, CI में टेस्ट और कंटेंट ऑप्स चाहते हैं।
|
|
41
|
+
|
|
42
|
+
## इंस्टॉलेशन
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add -D @intlayer/sync-po-plugin
|
|
46
|
+
# या
|
|
47
|
+
npm i -D @intlayer/sync-po-plugin
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## प्लगइन्स
|
|
51
|
+
|
|
52
|
+
यह पैकेज दो प्लगइन्स प्रदान करता है:
|
|
53
|
+
|
|
54
|
+
- `loadPO`: Intlayer शब्दकोशों में PO फ़ाइलें लोड करें।
|
|
55
|
+
- इस प्लगइन का उपयोग स्रोत से PO फ़ाइलों को लोड करने के लिए किया जाता है और इसे Intlayer शब्दकोशों में लोड किया जाएगा। यह पूरे कोडबेस को स्कैन कर सकता है और विशिष्ट PO फ़ाइलों को खोज सकता है।
|
|
56
|
+
इस प्लगइन का उपयोग किया जा सकता है:
|
|
57
|
+
- यदि आप एक i18n लाइब्रेरी का उपयोग करते हैं जो आपकी PO फ़ाइलों को लोड करने के लिए एक विशिष्ट स्थान लागू करती है, लेकिन आप अपनी सामग्री घोषणा को अपने कोड बेस में जहां चाहें वहां रखना चाहते हैं।
|
|
58
|
+
- इसका उपयोग तब भी किया जा सकता है जब आप रिमोट स्रोत (जैसे: CMS, एक API, आदि) से अपने संदेश प्राप्त करना चाहते हैं और अपने संदेशों को PO फ़ाइलों में संग्रहीत करना चाहते हैं।
|
|
59
|
+
|
|
60
|
+
> हुड के तहत, यह प्लगइन पूरे कोडबेस को स्कैन करेगा और विशिष्ट PO फ़ाइलों को खोजेगा और उन्हें Intlayer शब्दकोशों में लोड करेगा।
|
|
61
|
+
> ध्यान दें कि यह प्लगइन आउटपुट और अनुवादों को वापस PO फ़ाइलों में नहीं लिखेगा।
|
|
62
|
+
|
|
63
|
+
- `syncPO`: Intlayer शब्दकोशों के साथ PO फ़ाइलों को सिंक्रनाइज़ करें।
|
|
64
|
+
- इस प्लगइन का उपयोग Intlayer शब्दकोशों के साथ PO फ़ाइलों को सिंक्रनाइज़ करने के लिए किया जाता है। यह दिए गए स्थान को स्कैन कर सकता है और विशिष्ट PO फ़ाइलों के पैटर्न से मेल खाने वाले PO को लोड कर सकता है। यदि आप दूसरी i18n लाइब्रेरी का उपयोग करते हुए Intlayer के लाभ प्राप्त करना चाहते हैं तो यह प्लगइन उपयोगी है।
|
|
65
|
+
|
|
66
|
+
## दोनों प्लगइन्स का उपयोग करना
|
|
67
|
+
|
|
68
|
+
```ts fileName="intlayer.config.ts"
|
|
69
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
70
|
+
import { loadPO, syncPO } from "@intlayer/sync-po-plugin";
|
|
71
|
+
|
|
72
|
+
const config: IntlayerConfig = {
|
|
73
|
+
internationalization: {
|
|
74
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
75
|
+
defaultLocale: Locales.ENGLISH,
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// अपनी वर्तमान PO फ़ाइलों को Intlayer शब्दकोशों के साथ सिंक में रखें
|
|
79
|
+
plugins: [
|
|
80
|
+
/**
|
|
81
|
+
* src में उन सभी PO फ़ाइलों को लोड करेगा जो {key}.i18n.po पैटर्न से मेल खाती हैं
|
|
82
|
+
*/
|
|
83
|
+
loadPO({
|
|
84
|
+
source: ({ key }) => `./src/**/${key}.i18n.po`,
|
|
85
|
+
locale: Locales.ENGLISH,
|
|
86
|
+
priority: 1, // यह सुनिश्चित करता है कि ये PO फ़ाइलें `./locales/en/${key}.po` की फ़ाइलों पर प्राथमिकता लें
|
|
87
|
+
}),
|
|
88
|
+
/**
|
|
89
|
+
* लोड करेगा, और आउटपुट और अनुवादों को वापस locales निर्देशिका में PO फ़ाइलों में लिखेगा
|
|
90
|
+
*/
|
|
91
|
+
syncPO({
|
|
92
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
93
|
+
priority: 0,
|
|
94
|
+
}),
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default config;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## `syncPO` प्लगइन
|
|
102
|
+
|
|
103
|
+
### त्वरित शुरुआत
|
|
104
|
+
|
|
105
|
+
प्लगइन को अपने `intlayer.config.ts` में जोड़ें और इसे अपनी मौजूदा PO संरचना पर इंगित करें।
|
|
106
|
+
|
|
107
|
+
```ts fileName="intlayer.config.ts"
|
|
108
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
109
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
110
|
+
|
|
111
|
+
const config: IntlayerConfig = {
|
|
112
|
+
internationalization: {
|
|
113
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
114
|
+
defaultLocale: Locales.ENGLISH,
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// अपनी वर्तमान PO फ़ाइलों को Intlayer शब्दकोशों के साथ सिंक में रखें
|
|
118
|
+
plugins: [
|
|
119
|
+
syncPO({
|
|
120
|
+
// प्रति-लोकेल, प्रति-नेमस्पेस लेआउट
|
|
121
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export default config;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
वैकल्पिक: प्रति लोकेल एकल फ़ाइल:
|
|
130
|
+
|
|
131
|
+
```ts fileName="intlayer.config.ts"
|
|
132
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
133
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
134
|
+
|
|
135
|
+
const config: IntlayerConfig = {
|
|
136
|
+
internationalization: {
|
|
137
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
138
|
+
defaultLocale: Locales.ENGLISH,
|
|
139
|
+
},
|
|
140
|
+
plugins: [
|
|
141
|
+
syncPO({
|
|
142
|
+
source: ({ locale }) => `./locales/${locale}.po`,
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export default config;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### यह कैसे काम करता है
|
|
151
|
+
|
|
152
|
+
- पढ़ें: प्लगइन आपके `source` बिल्डर से PO फ़ाइलों की खोज करता है और उन्हें Intlayer शब्दकोशों के रूप में लोड करता है।
|
|
153
|
+
- लिखें: बिल्ड और फिल के बाद, यह स्थानीयकृत PO को वापस उन्हीं पथों पर लिखता है (उचित Gettext हेडर के साथ)।
|
|
154
|
+
- ऑटो-फिल: प्लगइन प्रत्येक शब्दकोश के लिए एक `autoFill` पथ घोषित करता है। `intlayer fill` चलाने से डिफ़ॉल्ट रूप से आपकी PO फ़ाइलों में केवल गायब अनुवाद अपडेट होते हैं।
|
|
155
|
+
|
|
156
|
+
API:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
syncPO({
|
|
160
|
+
source: ({ key, locale }) => string, // आवश्यक
|
|
161
|
+
location?: string, // वैकल्पिक लेबल, डिफ़ॉल्ट: "sync-po::path/to/source"
|
|
162
|
+
priority?: number, // संघर्ष समाधान के लिए वैकल्पिक प्राथमिकता, डिफ़ॉल्ट: 0
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### एकाधिक PO स्रोत और प्राथमिकता
|
|
167
|
+
|
|
168
|
+
आप विभिन्न PO स्रोतों को सिंक्रनाइज़ करने के लिए एकाधिक `syncPO` प्लगइन्स जोड़ सकते हैं। यह तब उपयोगी होता है जब आपके प्रोजेक्ट में कई अनुवाद स्रोत या अलग-अलग PO संरचनाएं हों।
|
|
169
|
+
|
|
170
|
+
#### प्राथमिकता प्रणाली
|
|
171
|
+
|
|
172
|
+
जब कई प्लगइन्स एक ही शब्दकोश कुंजी को लक्षित करते हैं, तो `priority` पैरामीटर यह निर्धारित करता है कि कौन सा प्लगइन प्राथमिकता लेता है:
|
|
173
|
+
|
|
174
|
+
- उच्च प्राथमिकता संख्याएँ कम प्राथमिकता वाली संख्याओं पर जीतती हैं
|
|
175
|
+
- `.content` फ़ाइलों की डिफ़ॉल्ट प्राथमिकता `0` है
|
|
176
|
+
- प्लगइन्स की डिफ़ॉल्ट प्राथमिकता `0` है
|
|
177
|
+
- समान प्राथमिकता वाले प्लगइन्स को कॉन्फ़िगरेशन में दिखाई देने वाले क्रम में संसाधित किया जाता है
|
|
178
|
+
|
|
179
|
+
```ts fileName="intlayer.config.ts"
|
|
180
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
181
|
+
import { syncPO } from "@intlayer/sync-po-plugin";
|
|
182
|
+
|
|
183
|
+
const config: IntlayerConfig = {
|
|
184
|
+
internationalization: {
|
|
185
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
186
|
+
defaultLocale: Locales.ENGLISH,
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
plugins: [
|
|
190
|
+
// प्राथमिक PO स्रोत (उच्चतम प्राथमिकता)
|
|
191
|
+
syncPO({
|
|
192
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
193
|
+
location: "main-translations",
|
|
194
|
+
priority: 10,
|
|
195
|
+
}),
|
|
196
|
+
|
|
197
|
+
// फॉलबैक PO स्रोत (कम प्राथमिकता)
|
|
198
|
+
syncPO({
|
|
199
|
+
source: ({ locale }) => `./fallback-locales/${locale}.po`,
|
|
200
|
+
location: "fallback-translations",
|
|
201
|
+
priority: 5,
|
|
202
|
+
}),
|
|
203
|
+
|
|
204
|
+
// लीगेसी PO स्रोत (सबसे कम प्राथमिकता)
|
|
205
|
+
syncPO({
|
|
206
|
+
source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.po`,
|
|
207
|
+
location: "legacy-translations",
|
|
208
|
+
priority: 1,
|
|
209
|
+
}),
|
|
210
|
+
],
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export default config;
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Load PO प्लगइन
|
|
217
|
+
|
|
218
|
+
### त्वरित शुरुआत
|
|
219
|
+
|
|
220
|
+
मौजूदा PO फ़ाइलों को Intlayer शब्दकोशों के रूप में प्राप्त करने के लिए प्लगइन को अपने `intlayer.config.ts` में जोड़ें। यह प्लगइन केवल पढ़ने के लिए है (डिस्क पर कोई लेखन नहीं):
|
|
221
|
+
|
|
222
|
+
```ts fileName="intlayer.config.ts"
|
|
223
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
224
|
+
import { loadPO } from "@intlayer/sync-po-plugin";
|
|
225
|
+
|
|
226
|
+
const config: IntlayerConfig = {
|
|
227
|
+
internationalization: {
|
|
228
|
+
locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
|
|
229
|
+
defaultLocale: Locales.ENGLISH,
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
plugins: [
|
|
233
|
+
// अपने स्रोत ट्री में कहीं भी स्थित PO संदेशों को प्राप्त करें
|
|
234
|
+
loadPO({
|
|
235
|
+
source: ({ key }) => `./src/**/${key}.i18n.po`,
|
|
236
|
+
// प्रति प्लगइन इंस्टेंस एक एकल लोकेल लोड करें (कॉन्फ़िगरेशन defaultLocale के लिए डिफ़ॉल्ट)
|
|
237
|
+
locale: Locales.ENGLISH,
|
|
238
|
+
priority: 0,
|
|
239
|
+
}),
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export default config;
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
वैकल्पिक: प्रति-लोकेल लेआउट, अभी भी केवल-पढ़ने के लिए (केवल चयनित लोकेल लोड किया गया है):
|
|
247
|
+
|
|
248
|
+
```ts fileName="intlayer.config.ts"
|
|
249
|
+
import { Locales, type IntlayerConfig } from "intlayer";
|
|
250
|
+
import { loadPO } from "@intlayer/sync-po-plugin";
|
|
251
|
+
|
|
252
|
+
const config: IntlayerConfig = {
|
|
253
|
+
internationalization: {
|
|
254
|
+
locales: [Locales.ENGLISH, Locales.FRENCH],
|
|
255
|
+
defaultLocale: Locales.ENGLISH,
|
|
256
|
+
},
|
|
257
|
+
plugins: [
|
|
258
|
+
loadPO({
|
|
259
|
+
// इस पैटर्न से केवल Locales.FRENCH के लिए फ़ाइलें प्राप्त की जाएंगी
|
|
260
|
+
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
261
|
+
locale: Locales.FRENCH,
|
|
262
|
+
}),
|
|
263
|
+
],
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
export default config;
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### यह कैसे काम करता है
|
|
270
|
+
|
|
271
|
+
- खोज: आपके `source` बिल्डर से एक ग्लब बनाता है और मिलान करने वाली PO फ़ाइलें एकत्र करता है।
|
|
272
|
+
- प्राप्ति: प्रत्येक PO फ़ाइल को प्रदान किए गए `locale` के साथ Intlayer शब्दकोश के रूप में लोड करता है।
|
|
273
|
+
- केवल-पढ़ने के लिए: आउटपुट फ़ाइलों को लिखता या प्रारूपित नहीं करता है; यदि आपको राउंड-ट्रिप सिंक की आवश्यकता है तो `syncPO` का उपयोग करें।
|
|
274
|
+
- ऑटो-फिल तैयार: एक `fill` पथ परिभाषित करता है ताकि `intlayer content fill` गायब कुंजियों को पॉप्युलेट कर सके।
|
|
275
|
+
|
|
276
|
+
### API
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
loadPO({
|
|
280
|
+
// आपके PO के पथ बनाएं। `locale` वैकल्पिक है यदि आपकी संरचना में कोई लोकेल सेगमेंट नहीं है
|
|
281
|
+
source: ({ key, locale }) => string,
|
|
282
|
+
|
|
283
|
+
// इस प्लगइन इंस्टेंस द्वारा लोड किए गए शब्दकोशों के लिए लक्षित लोकेल
|
|
284
|
+
// कॉन्फ़िगरेशन configuration.internationalization.defaultLocale के लिए डिफ़ॉल्ट
|
|
285
|
+
locale?: Locale,
|
|
286
|
+
|
|
287
|
+
// स्रोत की पहचान करने के लिए वैकल्पिक लेबल
|
|
288
|
+
location?: string, // डिफ़ॉल्ट: "plugin"
|
|
289
|
+
|
|
290
|
+
// अन्य स्रोतों के खिलाफ संघर्ष समाधान के लिए उपयोग की जाने वाली प्राथमिकता
|
|
291
|
+
priority?: number, // डिफ़ॉल्ट: 0
|
|
292
|
+
});
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### व्यवहार और परंपराएं
|
|
296
|
+
|
|
297
|
+
- यदि आपके `source` मास्क में लोकेल प्लेसहोल्डर शामिल है, तो केवल चयनित `locale` की फ़ाइलें प्राप्त की जाती हैं।
|
|
298
|
+
- यदि आपके मास्क में कोई `{key}` सेगमेंट नहीं है, तो डिक्शनरी कुंजी "index" है।
|
|
299
|
+
- कुंजियाँ आपके `source` बिल्डर में `{key}` प्लेसहोल्डर को प्रतिस्थापित करके फ़ाइल पथों से ली गई हैं।
|
|
300
|
+
- प्लगइन केवल खोजी गई फ़ाइलों का उपयोग करता है और गायब लोकेल या कुंजियों का निर्माण नहीं करता है।
|
|
301
|
+
- `fill` पथ आपके `source` से अनुमानित है और जब आप ऑप्ट-इन करते हैं तो CLI के माध्यम से गायब मानों को अपडेट करने के लिए उपयोग किया जाता है।
|
|
302
|
+
|
|
303
|
+
## संघर्ष समाधान
|
|
304
|
+
|
|
305
|
+
जब एक ही अनुवाद कुंजी कई PO स्रोतों में मौजूद होती है:
|
|
306
|
+
|
|
307
|
+
1. उच्चतम प्राथमिकता वाला प्लगइन अंतिम मान निर्धारित करता है
|
|
308
|
+
2. गायब कुंजियों के लिए निम्न प्राथमिकता स्रोतों का उपयोग फॉलबैक के रूप में किया जाता है
|
|
309
|
+
3. यह आपको नई संरचनाओं में धीरे-धीरे माइग्रेट करते हुए लीगेसी अनुवादों को बनाए रखने की अनुमति देता है
|
|
310
|
+
|
|
311
|
+
## CLI
|
|
312
|
+
|
|
313
|
+
सिंक्रनाइज़ की गई PO फ़ाइलों को अन्य `.content` फ़ाइलों की तरह माना जाएगा। इसका मतलब है, सिंक्रनाइज़ की गई PO फ़ाइलों के लिए सभी intlayer कमांड उपलब्ध होंगे। इसमें शामिल हैं:
|
|
314
|
+
|
|
315
|
+
- गायब अनुवाद हैं या नहीं, यह परीक्षण करने के लिए `intlayer content test`
|
|
316
|
+
- सिंक्रनाइज़ की गई PO फ़ाइलों को सूचीबद्ध करने के लिए `intlayer content list`
|
|
317
|
+
- गायब अनुवादों को भरने के लिए `intlayer content fill`
|
|
318
|
+
- सिंक्रनाइज़ की गई PO फ़ाइलों को पुश करने के लिए `intlayer content push`
|
|
319
|
+
- सिंक्रनाइज़ की गई PO फ़ाइलों को पुल करने के लिए `intlayer content pull`
|
|
320
|
+
|
|
321
|
+
अधिक जानकारी के लिए [Intlayer CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/cli/index.md) देखें।
|
|
322
|
+
|
|
323
|
+
## सीमाएँ (वर्तमान)
|
|
324
|
+
|
|
325
|
+
- तृतीय-पक्ष पुस्तकालयों को लक्षित करते समय कोई प्रविष्टि या बहुवचन/ICU समर्थन नहीं।
|
|
326
|
+
- विज़ुअल एडिटर अभी तक गैर-Intlayer रनटाइम के लिए उपलब्ध नहीं है।
|
|
327
|
+
- केवल PO सिंक्रनाइज़ेशन; गैर-PO कैटलॉग प्रारूप समर्थित नहीं हैं।
|
|
328
|
+
|
|
329
|
+
## यह क्यों मायने रखता है
|
|
330
|
+
|
|
331
|
+
- हम स्थापित i18n समाधानों की सिफारिश कर सकते हैं और Intlayer को ऐड-ऑन के रूप में स्थान दे सकते हैं।
|
|
332
|
+
- हम उनके SEO/कीवर्ड्स का लाभ उठाते हैं ट्यूटोरियल्स के साथ जो PO को प्रबंधित करने के लिए Intlayer का सुझाव देते हुए समाप्त होते हैं।
|
|
333
|
+
- लक्षित दर्शकों को "नए प्रोजेक्ट" से "i18n का उपयोग करने वाली किसी भी टीम" तक विस्तारित करता है।
|
|
@@ -30,6 +30,3 @@ Laporan terperinci dan dokumentasi teknis untuk setiap framework tersedia di baw
|
|
|
30
30
|
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
31
31
|
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
32
32
|
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
33
|
-
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
34
|
-
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
35
|
-
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
@@ -61,6 +61,13 @@ Karena masalah ini sulit, banyak solusi tersedia—beberapa berfokus pada DX (De
|
|
|
61
61
|
|
|
62
62
|
Intlayer mencoba mengoptimalkan di semua dimensi ini.
|
|
63
63
|
|
|
64
|
+
## TL;DR
|
|
65
|
+
|
|
66
|
+
- **Intlayer** & **next-translate**: Pilihan terbaik untuk performa Next.js, menawarkan footprint terkecil dan dukungan render statis terbaik.
|
|
67
|
+
- **next-intl**: Opsi paling tren, tetapi berat dan kompleks untuk dioptimalkan bagi aplikasi besar.
|
|
68
|
+
- **next-i18next**: Populer dan kaya plugin, tetapi membawa beban bundle yang signifikan (~3× Intlayer).
|
|
69
|
+
- **Hindari**: **gt-next** dan **lingo.dev** karena masalah performa yang parah, ketergantungan pada vendor (vendor lock-in), dan bug yang merusak build.
|
|
70
|
+
|
|
64
71
|
## Uji aplikasi Anda
|
|
65
72
|
|
|
66
73
|
Untuk mengungkap masalah ini, saya membangun pemindai gratis yang dapat Anda coba [di sini](https://intlayer.org/i18n-seo-scanner).
|
|
@@ -99,14 +106,14 @@ Terakhir, `Intlayer` menerapkan optimisasi waktu build sehingga `useIntlayer('ku
|
|
|
99
106
|
Untuk benchmark ini, kami membandingkan library berikut:
|
|
100
107
|
|
|
101
108
|
- `Base App` (Tanpa library i18n)
|
|
102
|
-
- `next-intlayer` (v8.7.
|
|
109
|
+
- `next-intlayer` (v8.7.12)
|
|
103
110
|
- `next-i18next` (v16.0.5)
|
|
104
111
|
- `next-intl` (v4.9.1)
|
|
105
112
|
- `@lingui/core` (v5.3.0)
|
|
106
113
|
- `next-translate` (v3.1.2)
|
|
107
114
|
- `next-international` (v1.3.1)
|
|
108
115
|
- `@inlang/paraglide-js` (v2.15.1)
|
|
109
|
-
-
|
|
116
|
+
- `@tolgee/react` (v7.0.0)
|
|
110
117
|
- `@lingo.dev/compiler` (v0.4.0)
|
|
111
118
|
- `wuchale` (v0.22.11)
|
|
112
119
|
- `gt-next` (v6.16.5)
|
|
@@ -161,10 +168,10 @@ Masalah yang ditemui:
|
|
|
161
168
|
|
|
162
169
|
**(General Translation)** (`gt-next@6.16.5`):
|
|
163
170
|
|
|
164
|
-
- Untuk aplikasi 110kb, `gt-
|
|
171
|
+
- Untuk aplikasi 110kb, `gt-next` menambahkan lebih dari 440kb ekstra.
|
|
165
172
|
- `Quota Exceeded, please upgrade your plan` pada build pertama dengan General Translation.
|
|
166
173
|
- Terjemahan tidak dirender; saya mendapatkan error `Error: <T> used on the client-side outside of <GTProvider>`, yang tampaknya merupakan bug pada library.
|
|
167
|
-
- Saat menerapkan **gt-
|
|
174
|
+
- Saat menerapkan **gt-next**, saya juga menemukan [masalah](https://github.com/generaltranslation/gt/issues/1210#event-24510646961) dengan library tersebut: `does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser`, yang membuat aplikasi rusak. Setelah melaporkan masalah ini, pengelola memperbaikinya dalam waktu 24 jam.
|
|
168
175
|
- Library ini memblokir rendering statis halaman Next.js.
|
|
169
176
|
|
|
170
177
|
**(Lingo.dev)** (`@lingo.dev/compiler@0.4.0`):
|
|
@@ -186,9 +193,11 @@ Ide di balik `Wuchale` menarik tetapi belum layak. Saya menemui masalah reaktivi
|
|
|
186
193
|
Secara pribadi saya tidak suka harus membuat ulang file JS sebelum setiap push, yang menciptakan risiko konflik merge konstan melalui PR. Alat ini juga tampak lebih fokus pada Vite daripada Next.js.
|
|
187
194
|
Terakhir, dibandingkan dengan solusi lain, Paraglide tidak menggunakan store (misalnya React context) untuk mengambil lokal saat ini untuk merender konten. Untuk setiap node yang di-parsing, ia akan meminta lokal dari localStorage / cookie dst. Ini mengarah pada eksekusi logika yang tidak perlu yang berdampak pada reaktivitas komponen.
|
|
188
195
|
|
|
196
|
+
> Catatan tentang paraglide: solusi ini menyuntikkan kode ke dalam basis kode Anda untuk impor, akibatnya metrik 'ukuran lib' dalam laporan benchmark hampir 0. Pembuatan kode (code generation) adalah hal yang baik, karena fungsi yang digunakan hanya akan mencakup logika yang diperlukan (semua awalan vs tanpa awalan, cookie vs penyimpanan, dll.). Sebagai perbandingan, Intlayer melakukan pemfilteran ini melalui injeksi variabel lingkungan dalam build untuk memaksa bundler melakukan tree-shake pada konten tergantung pada logikanya. Berkat ini, paraglide dan intlayer berakhir menjadi solusi yang 6 hingga 10 kali lebih ringan daripada i18next atau next-intl.
|
|
197
|
+
|
|
189
198
|
### 3 — Solusi yang dapat diterima
|
|
190
199
|
|
|
191
|
-
**(Tolgee)** (
|
|
200
|
+
**(Tolgee)** (`@tolgee/react@7.0.0`):
|
|
192
201
|
|
|
193
202
|
`Tolgee` mengatasi banyak masalah yang disebutkan sebelumnya. Saya merasa lebih sulit untuk mengadopsinya daripada alat serupa. Ia tidak memberikan type safety, yang juga membuat pendeteksian kunci yang hilang saat compile time lebih sulit. Saya harus membungkus fungsi Tolgee dengan fungsi saya sendiri untuk menambahkan deteksi kunci yang hilang.
|
|
194
203
|
|
|
@@ -216,7 +225,7 @@ Format pesan juga berbeda: `next-intl` menggunakan ICU MessageFormat, sementara
|
|
|
216
225
|
|
|
217
226
|
`next-translate` adalah rekomendasi utama saya jika Anda menyukai API bergaya `t()`. Ini elegan melalui `next-translate-plugin`, memuat namespace melalui `getStaticProps` dengan loader Webpack / Turbopack. Ini juga merupakan opsi teringan di sini (~2,5kb). Untuk namespacing, mendefinisikan namespace per halaman atau rute di config dipikirkan dengan matang dan lebih mudah dipelihara daripada alternatif utama seperti **next-intl** atau **next-i18next**. Di versi `3.1.2`, saya mencatat bahwa rendering statis tidak berfungsi; Next.js kembali ke rendering dinamis.
|
|
218
227
|
|
|
219
|
-
**(Intlayer)** (`next-intlayer@8.7.
|
|
228
|
+
**(Intlayer)** (`next-intlayer@8.7.12`):
|
|
220
229
|
|
|
221
230
|
Saya tidak akan secara pribadi menilai `next-intlayer` demi objektivitas, karena itu adalah solusi saya sendiri.
|
|
222
231
|
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: Solusi i18n Terbaik untuk Solid di Tahun 2026 - Laporan Benchmark
|
|
5
|
+
description: Bandingkan pustaka internasionalisasi (i18n) Solid seperti solid-primitives, solid-i18next, dan Intlayer. Laporan performa mendetail tentang ukuran bundle, kebocoran, dan reaktivitas.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- solid
|
|
11
|
+
- performa
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- solid
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-solid-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.12
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "Inisialisasi benchmark"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Pustaka i18n Solid — Laporan Benchmark 2026
|
|
26
|
+
|
|
27
|
+
Halaman ini adalah laporan benchmark untuk solusi i18n pada Solid.
|
|
28
|
+
|
|
29
|
+
## Daftar Isi
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## Benchmark Interaktif
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="vite-solid" vertical/>
|
|
36
|
+
|
|
37
|
+
## Referensi hasil:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md"
|
|
41
|
+
width="100%"
|
|
42
|
+
height="600px"
|
|
43
|
+
style="border:none;">
|
|
44
|
+
</iframe>
|
|
45
|
+
|
|
46
|
+
> https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md
|
|
47
|
+
|
|
48
|
+
Lihat repositori benchmark lengkap [di sini](https://github.com/intlayer-org/benchmark-i18n/tree/main).
|
|
49
|
+
|
|
50
|
+
## Pendahuluan
|
|
51
|
+
|
|
52
|
+
Solusi internasionalisasi adalah salah satu dependensi terberat dalam aplikasi Solid. Risiko utamanya adalah mengirimkan konten yang tidak perlu: terjemahan untuk halaman lain dan bahasa lain dalam satu bundle rute.
|
|
53
|
+
|
|
54
|
+
Seiring berkembangnya aplikasi Anda, masalah tersebut dapat dengan cepat membengkak JavaScript yang dikirim ke klien dan memperlambat navigasi.
|
|
55
|
+
|
|
56
|
+
Dalam praktiknya, untuk implementasi yang paling tidak dioptimalkan, halaman yang diinternasionalisasi bisa berakhir beberapa kali lebih berat daripada versi tanpa i18n.
|
|
57
|
+
|
|
58
|
+
Dampak lainnya adalah pada pengalaman pengembang (DX): bagaimana Anda mendeklarasikan konten, tipe data, organisasi namespace, pemuatan dinamis, dan reaktivitas saat bahasa berubah.
|
|
59
|
+
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: Pilihan yang direkomendasikan untuk aplikasi Solid profesional yang membutuhkan fitur canggih dan optimasi (v8.7.12).
|
|
63
|
+
- **@solid-primitives/i18n**: Alternatif ringan yang sangat baik untuk proyek sederhana, meskipun tidak memiliki fitur canggih seperti lazy loading.
|
|
64
|
+
- **solid-i18next**: Opsi standar tetapi berat (~4.7× Intlayer) dengan kelemahan yang sama seperti React i18next.
|
|
65
|
+
- **Paraglide**: Pendekatan inovatif tetapi DX yang kompleks dan masalah tree-shaking di beberapa pengaturan.
|
|
66
|
+
|
|
67
|
+
## Uji aplikasi Anda
|
|
68
|
+
|
|
69
|
+
Untuk mendeteksi masalah kebocoran i18n dengan cepat, saya menyiapkan pemindai gratis yang tersedia [di sini](https://intlayer.org/i18n-seo-scanner).
|
|
70
|
+
|
|
71
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
72
|
+
|
|
73
|
+
## Masalahnya
|
|
74
|
+
|
|
75
|
+
Dua tuas sangat penting untuk membatasi biaya aplikasi multibahasa:
|
|
76
|
+
|
|
77
|
+
- Pisahkan konten berdasarkan halaman / namespace agar Anda tidak memuat seluruh kamus saat tidak dibutuhkan.
|
|
78
|
+
- Muat bahasa yang tepat secara dinamis, hanya saat dibutuhkan.
|
|
79
|
+
|
|
80
|
+
Memahami batasan teknis dari pendekatan ini:
|
|
81
|
+
|
|
82
|
+
**Pemuatan dinamis**
|
|
83
|
+
|
|
84
|
+
Tanpa pemuatan dinamis, sebagian besar solusi menyimpan pesan dalam memori sejak render pertama, yang menambah overhead signifikan untuk aplikasi dengan banyak rute dan bahasa.
|
|
85
|
+
|
|
86
|
+
Dengan pemuatan dinamis, Anda menerima kompromi: JS awal yang lebih sedikit, tetapi terkadang permintaan ekstra saat mengganti bahasa.
|
|
87
|
+
|
|
88
|
+
**Pemisahan konten (Splitting)**
|
|
89
|
+
|
|
90
|
+
Sintaks yang dibangun di sekitar `t('a.b.c')` sangat nyaman tetapi sering kali mendorong penyimpanan objek JSON besar saat runtime. Model tersebut membuat tree-shaking sulit kecuali pustaka menawarkan strategi pemisahan per halaman yang nyata.
|
|
91
|
+
|
|
92
|
+
## Metodologi Penelitian
|
|
93
|
+
|
|
94
|
+
Untuk benchmark ini, kami membandingkan pustaka berikut:
|
|
95
|
+
|
|
96
|
+
- `Base App` (Tanpa pustaka i18n)
|
|
97
|
+
- `solid-intlayer` (v8.7.12)
|
|
98
|
+
- `@solid-primitives/i18n` (v2.2.1)
|
|
99
|
+
- `solid-i18next` (v17.0.2)
|
|
100
|
+
- `@inlang/paraglide-js` (v2.17.0)
|
|
101
|
+
|
|
102
|
+
Framework yang digunakan adalah `Solid` dengan aplikasi multibahasa yang terdiri dari **10 halaman** dan **10 bahasa**.
|
|
103
|
+
|
|
104
|
+
Kami membandingkan **empat strategi pemuatan**:
|
|
105
|
+
|
|
106
|
+
| Strategia | Tanpa namespace (global) | Dengan namespace (scoped) |
|
|
107
|
+
| :------------------- | :-------------------------------------------------- | :------------------------------------------------------------------------------- |
|
|
108
|
+
| **Pemuatan statis** | **Static**: Segalanya di memori saat startup. | **Scoped static**: Dipisah berdasarkan namespace; segalanya dimuat saat startup. |
|
|
109
|
+
| **Pemuatan dinamis** | **Dynamic**: Pemuatan sesuai permintaan per bahasa. | **Scoped dynamic**: Pemuatan granular per namespace dan bahasa. |
|
|
110
|
+
|
|
111
|
+
## Ringkasan strategi
|
|
112
|
+
|
|
113
|
+
- **Static**: Sederhana; tidak ada latensi jaringan setelah pemuatan awal. Kekurangan: ukuran bundle besar.
|
|
114
|
+
- **Dynamic**: Mengurangi beban awal (lazy-loading). Ideal bila Anda memiliki banyak bahasa.
|
|
115
|
+
- **Scoped static**: Menjaga kode tetap teratur (pemisahan logis) tanpa permintaan jaringan ekstra yang kompleks.
|
|
116
|
+
- **Scoped dynamic**: Pendekatan terbaik untuk _code splitting_ dan performa. Meminimalkan memori dengan hanya memuat apa yang dibutuhkan oleh tampilan saat ini dan bahasa yang aktif.
|
|
117
|
+
|
|
118
|
+
## Hasil secara mendetail
|
|
119
|
+
|
|
120
|
+
### 1 — Solusi yang harus dihindari
|
|
121
|
+
|
|
122
|
+
> Tidak ada solusi yang jelas untuk dihindari dalam ekosistem Solid.
|
|
123
|
+
|
|
124
|
+
### 2 — Solusi yang dapat diterima
|
|
125
|
+
|
|
126
|
+
**(solid-i18next)** (`solid-i18next@17.0.2`):
|
|
127
|
+
|
|
128
|
+
`solid-i18next` mungkin merupakan opsi yang paling populer karena merupakan salah satu yang pertama memenuhi kebutuhan i18n aplikasi JavaScript. Ia juga memiliki serangkaian plugin komunitas yang luas untuk masalah tertentu.
|
|
129
|
+
|
|
130
|
+
Paketnya berat (~14.6kb, yang mana sekitar 4.7× `solid-intlayer`).
|
|
131
|
+
|
|
132
|
+
Namun, ia memiliki kelemahan utama yang sama dengan stack yang dibangun di atas `t('a.b.c')`: optimasi dimungkinkan tetapi sangat memakan waktu, dan proyek besar berisiko terkena praktik buruk (namespace + pemuatan dinamis + tipe).
|
|
133
|
+
|
|
134
|
+
**(@solid-primitives/i18n)** (`@solid-primitives/i18n@2.2.1`):
|
|
135
|
+
|
|
136
|
+
Solid primitive sangat ringan dan efisien. Saya merekomendasikan solusi tersebut untuk proyek ringan, tetapi fitur-fiturnya mungkin cepat terasa kurang untuk solusi profesional yang mencakup manajemen cookie, pengalihan proxy, formatter, dll.
|
|
137
|
+
Ia juga tidak memiliki lazy loading dan scoping namespace untuk optimasi ukuran halaman.
|
|
138
|
+
|
|
139
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.17.0`):
|
|
140
|
+
|
|
141
|
+
`Paraglide` menawarkan pendekatan yang inovatif dan dipikirkan dengan matang. Meskipun demikian, dalam benchmark ini, tree-shaking yang diiklankan perusahaan mereka tidak berhasil untuk implementasi saya. Alur kerja dan DX juga lebih kompleks daripada opsi lainnya.
|
|
142
|
+
Secara pribadi saya tidak suka harus meregenerasi file JS sebelum setiap push, yang menciptakan risiko konflik merge yang konstan melalui PR.
|
|
143
|
+
Terakhir, dibandingkan dengan solusi lain, Paraglide tidak menggunakan store (misalnya Solid signal) untuk mengambil locale saat ini guna merender konten. Untuk setiap node yang di-parse, ia akan meminta locale dari localStorage / cookie dll. Hal ini menyebabkan eksekusi logika yang tidak perlu yang berdampak pada reaktivitas komponen.
|
|
144
|
+
|
|
145
|
+
### 3 — Rekomendasi
|
|
146
|
+
|
|
147
|
+
**(Intlayer)** (`solid-intlayer@8.7.12`):
|
|
148
|
+
|
|
149
|
+
Saya tidak akan menilai `solid-intlayer` secara pribadi demi objektivitas, karena ini adalah solusi saya sendiri.
|
|
150
|
+
|
|
151
|
+
### Catatan pribadi
|
|
152
|
+
|
|
153
|
+
Catatan ini bersifat pribadi dan tidak memengaruhi hasil benchmark. Namun, di dunia i18n Anda sering melihat konsensus seputar pola seperti `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>` untuk konten terjemahan.
|
|
154
|
+
|
|
155
|
+
Dalam aplikasi Solid, menginjeksi fungsi sebagai `JSX.Element` menurut pandangan saya adalah sebuah anti-pattern. Hal ini juga menambah kompleksitas yang dapat dihindari dan overhead eksekusi JavaScript (meskipun hampir tidak terlihat).
|