@intlayer/docs 8.9.4 → 8.9.6-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/docs/ar/benchmark/index.md +0 -3
  2. package/docs/ar/benchmark/nextjs.md +15 -6
  3. package/docs/ar/benchmark/solid.md +155 -0
  4. package/docs/ar/benchmark/svelte.md +148 -0
  5. package/docs/ar/benchmark/tanstack.md +12 -3
  6. package/docs/ar/benchmark/vue.md +160 -0
  7. package/docs/ar/configuration.md +16 -12
  8. package/docs/ar/dictionary/content_file.md +51 -1
  9. package/docs/ar/plugins/sync-po.md +0 -21
  10. package/docs/bn/configuration.md +16 -12
  11. package/docs/cs/configuration.md +16 -12
  12. package/docs/de/benchmark/index.md +0 -3
  13. package/docs/de/benchmark/nextjs.md +15 -6
  14. package/docs/de/benchmark/solid.md +155 -0
  15. package/docs/de/benchmark/svelte.md +148 -0
  16. package/docs/de/benchmark/tanstack.md +12 -3
  17. package/docs/de/benchmark/vue.md +160 -0
  18. package/docs/de/configuration.md +16 -12
  19. package/docs/de/dictionary/content_file.md +52 -2
  20. package/docs/de/plugins/sync-po.md +0 -22
  21. package/docs/en/benchmark/nextjs.md +11 -2
  22. package/docs/en/benchmark/solid.md +22 -4
  23. package/docs/en/benchmark/svelte.md +17 -5
  24. package/docs/en/benchmark/tanstack.md +18 -3
  25. package/docs/en/benchmark/vue.md +17 -11
  26. package/docs/en/configuration.md +16 -13
  27. package/docs/en/dictionary/content_file.md +51 -1
  28. package/docs/en/plugins/sync-po.md +0 -21
  29. package/docs/en-GB/benchmark/index.md +0 -3
  30. package/docs/en-GB/benchmark/nextjs.md +15 -6
  31. package/docs/en-GB/benchmark/solid.md +155 -0
  32. package/docs/en-GB/benchmark/svelte.md +148 -0
  33. package/docs/en-GB/benchmark/tanstack.md +12 -3
  34. package/docs/en-GB/benchmark/vue.md +160 -0
  35. package/docs/en-GB/configuration.md +15 -11
  36. package/docs/en-GB/dictionary/content_file.md +51 -1
  37. package/docs/en-GB/plugins/sync-po.md +0 -21
  38. package/docs/es/benchmark/index.md +0 -3
  39. package/docs/es/benchmark/nextjs.md +15 -6
  40. package/docs/es/benchmark/solid.md +155 -0
  41. package/docs/es/benchmark/svelte.md +148 -0
  42. package/docs/es/benchmark/tanstack.md +12 -3
  43. package/docs/es/benchmark/vue.md +160 -0
  44. package/docs/es/configuration.md +16 -12
  45. package/docs/es/dictionary/content_file.md +51 -1
  46. package/docs/es/plugins/sync-po.md +0 -21
  47. package/docs/fr/benchmark/index.md +0 -3
  48. package/docs/fr/benchmark/nextjs.md +15 -6
  49. package/docs/fr/benchmark/solid.md +155 -0
  50. package/docs/fr/benchmark/svelte.md +148 -0
  51. package/docs/fr/benchmark/tanstack.md +12 -3
  52. package/docs/fr/benchmark/vue.md +160 -0
  53. package/docs/fr/configuration.md +16 -12
  54. package/docs/fr/dictionary/content_file.md +51 -1
  55. package/docs/fr/plugins/sync-po.md +0 -21
  56. package/docs/hi/benchmark/nextjs.md +15 -6
  57. package/docs/hi/benchmark/solid.md +155 -0
  58. package/docs/hi/benchmark/svelte.md +148 -0
  59. package/docs/hi/benchmark/tanstack.md +12 -3
  60. package/docs/hi/benchmark/vue.md +160 -0
  61. package/docs/hi/configuration.md +16 -12
  62. package/docs/hi/dictionary/content_file.md +51 -1
  63. package/docs/hi/plugins/sync-po.md +0 -21
  64. package/docs/id/benchmark/index.md +0 -3
  65. package/docs/id/benchmark/nextjs.md +15 -6
  66. package/docs/id/benchmark/solid.md +155 -0
  67. package/docs/id/benchmark/svelte.md +148 -0
  68. package/docs/id/benchmark/tanstack.md +12 -3
  69. package/docs/id/benchmark/vue.md +160 -0
  70. package/docs/id/configuration.md +16 -12
  71. package/docs/id/dictionary/content_file.md +51 -1
  72. package/docs/id/plugins/sync-po.md +0 -21
  73. package/docs/it/benchmark/index.md +1 -4
  74. package/docs/it/benchmark/nextjs.md +15 -6
  75. package/docs/it/benchmark/solid.md +155 -0
  76. package/docs/it/benchmark/svelte.md +148 -0
  77. package/docs/it/benchmark/tanstack.md +12 -3
  78. package/docs/it/benchmark/vue.md +160 -0
  79. package/docs/it/configuration.md +16 -12
  80. package/docs/it/dictionary/content_file.md +51 -1
  81. package/docs/it/plugins/sync-po.md +0 -21
  82. package/docs/ja/benchmark/index.md +5 -5
  83. package/docs/ja/benchmark/nextjs.md +15 -6
  84. package/docs/ja/benchmark/solid.md +155 -0
  85. package/docs/ja/benchmark/svelte.md +148 -0
  86. package/docs/ja/benchmark/tanstack.md +12 -3
  87. package/docs/ja/benchmark/vue.md +160 -0
  88. package/docs/ja/configuration.md +16 -12
  89. package/docs/ja/dictionary/content_file.md +50 -2
  90. package/docs/ja/intlayer_with_nextjs_no_locale_path.md +4 -3
  91. package/docs/ja/plugins/sync-po.md +0 -21
  92. package/docs/ko/benchmark/nextjs.md +15 -6
  93. package/docs/ko/benchmark/solid.md +155 -0
  94. package/docs/ko/benchmark/svelte.md +148 -0
  95. package/docs/ko/benchmark/tanstack.md +12 -3
  96. package/docs/ko/benchmark/vue.md +160 -0
  97. package/docs/ko/configuration.md +16 -12
  98. package/docs/ko/dictionary/content_file.md +51 -1
  99. package/docs/ko/intlayer_with_nextjs_no_locale_path.md +3 -2
  100. package/docs/ko/plugins/sync-po.md +0 -21
  101. package/docs/nl/configuration.md +16 -12
  102. package/docs/pl/benchmark/index.md +0 -3
  103. package/docs/pl/benchmark/nextjs.md +15 -6
  104. package/docs/pl/benchmark/solid.md +155 -0
  105. package/docs/pl/benchmark/svelte.md +148 -0
  106. package/docs/pl/benchmark/tanstack.md +12 -3
  107. package/docs/pl/benchmark/vue.md +160 -0
  108. package/docs/pl/configuration.md +16 -12
  109. package/docs/pl/dictionary/content_file.md +51 -1
  110. package/docs/pl/plugins/sync-po.md +0 -21
  111. package/docs/pt/benchmark/index.md +0 -3
  112. package/docs/pt/benchmark/nextjs.md +16 -7
  113. package/docs/pt/benchmark/solid.md +155 -0
  114. package/docs/pt/benchmark/svelte.md +148 -0
  115. package/docs/pt/benchmark/tanstack.md +13 -4
  116. package/docs/pt/benchmark/vue.md +160 -0
  117. package/docs/pt/configuration.md +16 -12
  118. package/docs/pt/dictionary/content_file.md +51 -1
  119. package/docs/pt/plugins/sync-po.md +0 -21
  120. package/docs/ru/benchmark/nextjs.md +15 -6
  121. package/docs/ru/benchmark/solid.md +155 -0
  122. package/docs/ru/benchmark/svelte.md +148 -0
  123. package/docs/ru/benchmark/tanstack.md +12 -3
  124. package/docs/ru/benchmark/vue.md +160 -0
  125. package/docs/ru/configuration.md +16 -12
  126. package/docs/ru/dictionary/content_file.md +52 -2
  127. package/docs/ru/plugins/sync-po.md +0 -21
  128. package/docs/tr/benchmark/index.md +0 -3
  129. package/docs/tr/benchmark/nextjs.md +15 -6
  130. package/docs/tr/benchmark/solid.md +155 -0
  131. package/docs/tr/benchmark/svelte.md +148 -0
  132. package/docs/tr/benchmark/tanstack.md +12 -3
  133. package/docs/tr/benchmark/vue.md +160 -0
  134. package/docs/tr/configuration.md +16 -12
  135. package/docs/tr/dictionary/content_file.md +51 -1
  136. package/docs/tr/plugins/sync-po.md +0 -21
  137. package/docs/uk/benchmark/nextjs.md +15 -6
  138. package/docs/uk/benchmark/solid.md +155 -0
  139. package/docs/uk/benchmark/svelte.md +148 -0
  140. package/docs/uk/benchmark/tanstack.md +12 -3
  141. package/docs/uk/benchmark/vue.md +160 -0
  142. package/docs/uk/configuration.md +16 -12
  143. package/docs/uk/dictionary/content_file.md +51 -1
  144. package/docs/uk/plugins/sync-po.md +0 -21
  145. package/docs/ur/configuration.md +16 -12
  146. package/docs/vi/benchmark/index.md +0 -3
  147. package/docs/vi/benchmark/nextjs.md +15 -6
  148. package/docs/vi/benchmark/solid.md +155 -0
  149. package/docs/vi/benchmark/svelte.md +148 -0
  150. package/docs/vi/benchmark/tanstack.md +12 -3
  151. package/docs/vi/benchmark/vue.md +160 -0
  152. package/docs/vi/configuration.md +16 -12
  153. package/docs/vi/dictionary/content_file.md +51 -1
  154. package/docs/vi/intlayer_with_nextjs_15.md +10 -57
  155. package/docs/vi/plugins/sync-po.md +0 -21
  156. package/docs/zh/benchmark/nextjs.md +15 -6
  157. package/docs/zh/benchmark/solid.md +155 -0
  158. package/docs/zh/benchmark/svelte.md +148 -0
  159. package/docs/zh/benchmark/tanstack.md +12 -3
  160. package/docs/zh/benchmark/vue.md +160 -0
  161. package/docs/zh/configuration.md +16 -12
  162. package/docs/zh/dictionary/content_file.md +51 -3
  163. package/docs/zh/plugins/sync-po.md +0 -21
  164. package/frequent_questions/ar/intlayerNode.md +3 -3
  165. package/frequent_questions/de/intlayerNode.md +3 -3
  166. package/frequent_questions/en/intlayerNode.md +3 -3
  167. package/frequent_questions/en-GB/intlayerNode.md +3 -3
  168. package/frequent_questions/es/intlayerNode.md +3 -3
  169. package/frequent_questions/fr/intlayerNode.md +3 -3
  170. package/frequent_questions/hi/intlayerNode.md +3 -3
  171. package/frequent_questions/id/intlayerNode.md +3 -3
  172. package/frequent_questions/it/intlayerNode.md +3 -3
  173. package/frequent_questions/ja/intlayerNode.md +3 -3
  174. package/frequent_questions/ko/intlayerNode.md +3 -3
  175. package/frequent_questions/pl/intlayerNode.md +3 -3
  176. package/frequent_questions/pt/intlayerNode.md +3 -3
  177. package/frequent_questions/ru/intlayerNode.md +3 -3
  178. package/frequent_questions/tr/intlayerNode.md +3 -3
  179. package/frequent_questions/uk/intlayerNode.md +3 -3
  180. package/frequent_questions/vi/intlayerNode.md +3 -3
  181. package/frequent_questions/zh/intlayerNode.md +3 -3
  182. package/package.json +8 -8
@@ -0,0 +1,148 @@
1
+ ---
2
+ createdAt: 2026-04-20
3
+ updatedAt: 2026-04-21
4
+ title: Solusi i18n Terbaik untuk Svelte di Tahun 2026 - Laporan Benchmark
5
+ description: Bandingkan pustaka internasionalisasi (i18n) Svelte seperti svelte-i18n, Paraglide, dan Intlayer. Laporan performa mendetail tentang ukuran bundle, kebocoran, dan reaktivitas.
6
+ keywords:
7
+ - benchmark
8
+ - i18n
9
+ - intl
10
+ - svelte
11
+ - performa
12
+ - intlayer
13
+ slugs:
14
+ - doc
15
+ - benchmark
16
+ - svelte
17
+ author: Aymeric PINEAU
18
+ applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-svelte-template
19
+ history:
20
+ - version: 8.7.12
21
+ date: 2026-01-06
22
+ changes: "Inisialisasi benchmark"
23
+ ---
24
+
25
+ # Pustaka i18n Svelte — Laporan Benchmark 2026
26
+
27
+ Halaman ini adalah laporan benchmark untuk solusi i18n pada Svelte.
28
+
29
+ ## Daftar Isi
30
+
31
+ <Toc/>
32
+
33
+ ## Benchmark Interaktif
34
+
35
+ <I18nBenchmark framework="vite-svelte" 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_svelte.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_svelte.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 Svelte. 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 paling efisien dalam performa (v8.7.12) dengan footprint terkecil.
63
+ - **Paraglide**: Kontender kuat untuk tree-shaking tetapi memiliki pengalaman pengembang yang lebih kompleks dan overhead reaktivitas.
64
+ - **svelte-i18n**: Komprehensif dan standar untuk Svelte, tetapi membawa beban bundle yang jauh lebih besar (~7× Intlayer).
65
+
66
+ ## Uji aplikasi Anda
67
+
68
+ Untuk mendeteksi masalah kebocoran i18n dengan cepat, saya menyiapkan pemindai gratis yang tersedia [di sini](https://intlayer.org/i18n-seo-scanner).
69
+
70
+ <iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
71
+
72
+ ## Masalahnya
73
+
74
+ Dua tuas sangat penting untuk membatasi biaya aplikasi multibahasa:
75
+
76
+ - Pisahkan konten berdasarkan halaman / namespace agar Anda tidak memuat seluruh kamus saat tidak dibutuhkan.
77
+ - Muat bahasa yang tepat secara dinamis, hanya saat dibutuhkan.
78
+
79
+ Memahami batasan teknis dari pendekatan ini:
80
+
81
+ **Pemuatan dinamis**
82
+
83
+ Tanpa pemuatan dinamis, sebagian besar solusi menyimpan pesan dalam memori sejak render pertama, yang menambah overhead signifikan untuk aplikasi dengan banyak rute dan bahasa.
84
+
85
+ Dengan pemuatan dinamis, Anda menerima kompromi: JS awal yang lebih sedikit, tetapi terkadang permintaan ekstra saat mengganti bahasa.
86
+
87
+ **Pemisahan konten (Splitting)**
88
+
89
+ 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.
90
+
91
+ ## Metodologi Penelitian
92
+
93
+ Untuk benchmark ini, kami membandingkan pustaka berikut:
94
+
95
+ - `Base App` (Tanpa pustaka i18n)
96
+ - `svelte-intlayer` (v8.7.12)
97
+ - `svelte-i18n` (v4.0.1)
98
+ - `@inlang/paraglide-js` (v2.17.0)
99
+
100
+ Framework yang digunakan adalah `Svelte` dengan aplikasi multibahasa yang terdiri dari **10 halaman** dan **10 bahasa**.
101
+
102
+ Kami membandingkan **empat strategi pemuatan**:
103
+
104
+ | Strategia | Tanpa namespace (global) | Dengan namespace (scoped) |
105
+ | :------------------- | :-------------------------------------------------- | :------------------------------------------------------------------------------- |
106
+ | **Pemuatan statis** | **Static**: Segalanya di memori saat startup. | **Scoped static**: Dipisah berdasarkan namespace; segalanya dimuat saat startup. |
107
+ | **Pemuatan dinamis** | **Dynamic**: Pemuatan sesuai permintaan per bahasa. | **Scoped dynamic**: Pemuatan granular per namespace dan bahasa. |
108
+
109
+ ## Ringkasan strategi
110
+
111
+ - **Static**: Sederhana; tidak ada latensi jaringan setelah pemuatan awal. Kekurangan: ukuran bundle besar.
112
+ - **Dynamic**: Mengurangi beban awal (lazy-loading). Ideal bila Anda memiliki banyak bahasa.
113
+ - **Scoped static**: Menjaga kode tetap teratur (pemisahan logis) tanpa permintaan jaringan ekstra yang kompleks.
114
+ - **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.
115
+
116
+ ## Hasil secara mendetail
117
+
118
+ ### 1 — Solusi yang harus dihindari
119
+
120
+ > Tidak ada solusi yang jelas untuk dihindari dalam ekosistem Svelte.
121
+
122
+ ### 2 — Solusi yang dapat diterima
123
+
124
+ **(Paraglide)** (`@inlang/paraglide-js@2.17.0`):
125
+
126
+ `Paraglide` menawarkan pendekatan yang inovatif dan dipikirkan dengan matang. Dalam konteks aplikasi Vite + Svelte, tree-shaking yang diiklankan perusahaan mereka bekerja seperti yang diharapkan, yang mana sangat bagus.
127
+ Tetapi dalam kasus React + TanStack Start, tree-shaking tidak bekerja seperti yang diharapkan, sama halnya untuk Next.js. Karena itu, penggunaan Paraglide dalam proyek Svelte dan TanStack Start layak untuk diperiksa ulang.
128
+ Alur kerja dan DX juga lebih kompleks daripada opsi lainnya.
129
+ Secara pribadi saya bukan penggemar keharusan untuk meregenerasi file JS sebelum setiap push, yang menciptakan risiko konflik merge yang konstan melalui PR. Alat ini juga tampaknya lebih fokus pada Vite daripada Next.js.
130
+ Terakhir, dibandingkan dengan solusi lain, Paraglide tidak menggunakan store (misalnya Svelte store) 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.
131
+
132
+ > Catatan tentang paraglide: solusi ini menginjeksi kode ke dalam codebase Anda untuk impor; hasilnya, metrik 'lib size' dalam laporan benchmark hampir 0. Pembuatan kode (Code generation) adalah hal yang baik, karena fungsi yang digunakan hanya akan menyertakan logika yang diperlukan (prefix di mana-mana vs tanpa prefix, cookie vs storage, dll.). Sebagai perbandingan, Intlayer melakukan pemfilteran ini melalui injeksi variabel lingkungan dalam build untuk memaksa bundler melakukan tree-shaking konten tergantung pada logika. Berkat ini, paraglide dan intlayer akhirnya menjadi solusi yang 6 hingga 10 kali lebih ringan daripada i18next atau next-intl.
133
+
134
+ **(svelte-i18n)** (`svelte-i18n@3.4.0`):
135
+
136
+ Solusi ini menjawab semua kebutuhan i18n dalam proyek Svelte. Tetapi seperti halnya i18next atau solusi i18n besar lainnya, ia sedikit berat (~15.9kb, yang mana sekitar 7× `svelte-intlayer`).
137
+
138
+ ### 3 — Rekomendasi
139
+
140
+ **(Intlayer)** (`svelte-intlayer@8.7.12`):
141
+
142
+ Saya tidak akan menilai `svelte-intlayer` secara pribadi demi objektivitas, karena ini adalah solusi saya sendiri.
143
+
144
+ ### Catatan pribadi
145
+
146
+ 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.
147
+
148
+ Dalam aplikasi Svelte, menginjeksi fungsi sebagai `Slot` menurut pandangan saya adalah sebuah anti-pattern. Hal ini juga menambah kompleksitas yang dapat dihindari dan overhead eksekusi JavaScript (meskipun hampir tidak terlihat).
@@ -57,6 +57,13 @@ Dalam praktiknya, untuk implementasi yang paling tidak dioptimalkan, halaman yan
57
57
 
58
58
  Dampak lainnya adalah pada pengalaman pengembang (DX): bagaimana Anda mendeklarasikan konten, tipe, organisasi namespace, pemuatan dinamis, dan reaktivitas saat lokal berubah.
59
59
 
60
+ ## TL;DR
61
+
62
+ - **Intlayer**: Memberikan performa terbaik dan ukuran bundle terkecil (v8.7.12) untuk TanStack Start.
63
+ - **react-i18next** & **use-intl**: Alternatif matang dengan ekosistem besar, tetapi secara signifikan lebih berat dan lebih kompleks untuk dioptimalkan.
64
+ - **Paraglide**: Ide tree-shaking inovatif yang tidak berjalan dalam praktiknya. DX yang kompleks dan overhead reaktivitas di TanStack Start.
65
+ - **Hindari**: **General Translation (GT)** dan **Lingo.dev** karena masalah performa yang serius, batas kuota AI, dan vendor lock-in.
66
+
60
67
  ## Uji aplikasi Anda
61
68
 
62
69
  Untuk mendeteksi masalah kebocoran i18n dengan cepat, saya menyiapkan pemindai gratis yang tersedia [di sini](https://intlayer.org/i18n-seo-scanner).
@@ -87,12 +94,12 @@ Sintaksis yang dibangun di sekitar `const t = useTranslation()` + `t('a.b.c')` s
87
94
  Untuk benchmark ini, kami membandingkan library berikut:
88
95
 
89
96
  - `Base App` (Tanpa library i18n)
90
- - `react-intlayer` (v8.7.5-canary.0)
97
+ - `react-intlayer` (v8.7.12)
91
98
  - `react-i18next` (v17.0.2)
92
99
  - `use-intl` (v4.9.1)
93
100
  - `@lingui/core` (v5.3.0)
94
101
  - `@inlang/paraglide-js` (v2.15.1)
95
- - `tolgee` (v7.0.0)
102
+ - `@tolgee/react` (v7.0.0)
96
103
  - `react-intl` (v10.1.1)
97
104
  - `wuchale` (v0.22.11)
98
105
  - `gt-react` (vlatest)
@@ -150,7 +157,9 @@ Ide di balik `Wuchale` menarik tetapi belum menjadi solusi yang layak. Saya mene
150
157
 
151
158
  `Paraglide` menawarkan pendekatan yang inovatif dan terencana dengan baik. Meskipun demikian, dalam benchmark ini tree-shaking yang diiklankan perusahaan mereka tidak berfungsi untuk implementasi Next.js saya atau untuk TanStack Start. Alur kerja dan DX-nya juga lebih kompleks daripada opsi lainnya. Secara pribadi saya bukan penggemar keharusan untuk membuat ulang file JS sebelum setiap push, yang menciptakan risiko konflik merge yang konstan bagi pengembang melalui PR.
152
159
 
153
- **(Tolgee)** (`tolgee@7.0.0`):
160
+ > Catatan tentang paraglide: solusi ini menyuntikkan kode ke dalam basis kode Anda untuk impor; akibatnya, metrik 'lib size' dalam laporan benchmark hampir 0. Pembuatan kode (Code generation) adalah hal yang baik, karena fungsi yang digunakan hanya akan menyertakan logika yang diperlukan (awalan di mana-mana vs tanpa awalan, cookie vs penyimpanan, dll.). Sebagai perbandingan, Intlayer melakukan pemfilteran ini melalui injeksi variabel lingkungan dalam build untuk memaksa pemaket (bundler) melakukan tree-shake pada konten tergantung pada logikanya. Berkat ini, paraglide dan intlayer akhirnya menjadi solusi yang 6 hingga 10 kali lebih ringan daripada i18next atau next-intl.
161
+
162
+ **(Tolgee)** (`@tolgee/react@7.0.0`):
154
163
 
155
164
  `Tolgee` mengatasi banyak masalah yang disebutkan sebelumnya. Saya merasa lebih sulit untuk memulai adopsi Tolgee dibandingkan alat lain dengan pendekatan serupa. Ia tidak memberikan type safety, yang juga membuat pendeteksian kunci yang hilang saat compile time jauh lebih sulit. Saya harus membungkus API Tolgee dengan API saya sendiri untuk menambahkan deteksi kunci yang hilang.
156
165
 
@@ -0,0 +1,160 @@
1
+ ---
2
+ createdAt: 2026-04-20
3
+ updatedAt: 2026-04-21
4
+ title: Solusi i18n Terbaik untuk Vue di Tahun 2026 - Laporan Benchmark
5
+ description: Bandingkan pustaka internasionalisasi (i18n) Vue seperti vue-i18n, fluent-vue, dan Intlayer. Laporan performa mendetail tentang ukuran bundle, kebocoran, dan reaktivitas.
6
+ keywords:
7
+ - benchmark
8
+ - i18n
9
+ - intl
10
+ - vue
11
+ - performa
12
+ - intlayer
13
+ slugs:
14
+ - doc
15
+ - benchmark
16
+ - vue
17
+ author: Aymeric PINEAU
18
+ applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-vue-template
19
+ history:
20
+ - version: 8.7.12
21
+ date: 2026-01-06
22
+ changes: "Inisialisasi benchmark"
23
+ ---
24
+
25
+ # Pustaka i18n Vue — Laporan Benchmark 2026
26
+
27
+ Halaman ini adalah laporan benchmark untuk solusi i18n pada Vue.
28
+
29
+ ## Daftar Isi
30
+
31
+ <Toc/>
32
+
33
+ ## Benchmark Interaktif
34
+
35
+ <I18nBenchmark framework="vite-vue" 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_vue.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_vue.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 Vue. 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**: Solusi paling ringan (v8.7.12) dengan scoping bawaan dan pemuatan dinamis.
63
+ - **vue-i18n**: Standar industri dengan ekosistem yang kaya, tetapi bisa menjadi jauh lebih berat dan sulit dioptimalkan untuk code-splitting dalam aplikasi besar.
64
+ - **fluent-vue**: Organisasi pesan yang inovatif tetapi kurang dalam keamanan tipe (type-safety) dan ternyata merupakan solusi yang sangat berat.
65
+
66
+ ## Uji aplikasi Anda
67
+
68
+ Untuk mendeteksi masalah kebocoran i18n dengan cepat, saya menyiapkan pemindai gratis yang tersedia [di sini](https://intlayer.org/i18n-seo-scanner).
69
+
70
+ <iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
71
+
72
+ ## Masalahnya
73
+
74
+ Dua tuas sangat penting untuk membatasi biaya aplikasi multibahasa:
75
+
76
+ - Pisahkan konten berdasarkan halaman / namespace agar Anda tidak memuat seluruh kamus saat tidak dibutuhkan.
77
+ - Muat bahasa yang tepat secara dinamis, hanya saat dibutuhkan.
78
+
79
+ Memahami batasan teknis dari pendekatan ini:
80
+
81
+ **Pemuatan dinamis**
82
+
83
+ Tanpa pemuatan dinamis, sebagian besar solusi menyimpan pesan dalam memori sejak render pertama, yang menambah overhead signifikan untuk aplikasi dengan banyak rute dan bahasa.
84
+
85
+ Dengan pemuatan dinamis, Anda menerima kompromi: JS awal yang lebih sedikit, tetapi terkadang permintaan ekstra saat mengganti bahasa.
86
+
87
+ **Pemisahan konten (Splitting)**
88
+
89
+ Sintaks yang dibangun di sekitar `const { t } = useI18n()` + `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.
90
+
91
+ ## Metodologi Penelitian
92
+
93
+ Untuk benchmark ini, kami membandingkan pustaka berikut:
94
+
95
+ - `Base App` (Tanpa pustaka i18n)
96
+ - `vue-intlayer` (v8.7.12)
97
+ - `vue-i18n` (v11.4.0)
98
+ - `fluent-vue` (v3.8.2)
99
+
100
+ Framework yang digunakan adalah `Vue` dengan aplikasi multibahasa yang terdiri dari **10 halaman** dan **10 bahasa**.
101
+
102
+ Kami membandingkan **empat strategi pemuatan**:
103
+
104
+ | Strategi | Tanpa namespace (global) | Dengan namespace (scoped) |
105
+ | :------------------- | :-------------------------------------------------- | :------------------------------------------------------------------------------- |
106
+ | **Pemuatan statis** | **Static**: Segalanya di memori saat startup. | **Scoped static**: Dipisah berdasarkan namespace; segalanya dimuat saat startup. |
107
+ | **Pemuatan dinamis** | **Dynamic**: Pemuatan sesuai permintaan per bahasa. | **Scoped dynamic**: Pemuatan granular per namespace dan bahasa. |
108
+
109
+ ## Ringkasan strategi
110
+
111
+ - **Static**: Sederhana; tidak ada latensi jaringan setelah pemuatan awal. Kekurangan: ukuran bundle besar.
112
+ - **Dynamic**: Mengurangi beban awal (lazy-loading). Ideal bila Anda memiliki banyak bahasa.
113
+ - **Scoped static**: Menjaga kode tetap teratur (pemisahan logis) tanpa permintaan jaringan ekstra yang kompleks.
114
+ - **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.
115
+
116
+ ### Apa yang saya ukur:
117
+
118
+ Saya menjalankan aplikasi multibahasa yang sama di browser asli untuk setiap stack, lalu mencatat apa yang sebenarnya muncul di jaringan dan berapa lama waktu yang dibutuhkan. Ukuran dilaporkan **setelah kompresi web normal**, karena itu lebih dekat dengan apa yang sebenarnya diunduh orang daripada hitungan kode sumber mentah.
119
+
120
+ - **Ukuran pustaka internasionalisasi**: Setelah pembundelan, tree-shaking, dan minifikasi, ukuran pustaka i18n adalah ukuran kode provider + composable dalam komponen kosong. Ini tidak termasuk pemuatan file terjemahan. Ini menjawab seberapa "mahal" pustaka tersebut sebelum konten Anda masuk.
121
+
122
+ - **JavaScript per halaman**: Untuk setiap rute benchmark, seberapa banyak skrip yang ditarik browser untuk kunjungan tersebut, dirata-ratakan di seluruh halaman dalam pengujian (dan di seluruh bahasa). Halaman yang berat adalah halaman yang lambat.
123
+
124
+ - **Kebocoran dari bahasa lain (Leakage)**: Ini adalah konten dari halaman yang sama tetapi dalam bahasa lain yang akan dimuat secara tidak sengaja di halaman yang sedang diaudit. Konten ini tidak perlu dan harus dihindari (misalnya: konten halaman `/fr/about` dalam bundle halaman `/en/about`).
125
+
126
+ - **Kebocoran dari rute lain**: Ide yang sama untuk **layar lain** dalam aplikasi: apakah teks mereka ikut terbawa saat Anda hanya membuka satu halaman (misalnya: konten halaman `/en/about` dalam bundle halaman `/en/contact`). Skor tinggi menandakan pemisahan yang lemah atau bundle yang terlalu luas.
127
+
128
+ - **Ukuran rata-rata bundle komponen**: Potongan UI umum diukur **satu per satu** alih-alih bersembunyi di dalam satu angka aplikasi raksasa. Ini menunjukkan apakah internasionalisasi secara diam-diam membengkakkan komponen sehari-hari. Misalnya, jika komponen Anda merender ulang, ia akan memuat semua data tersebut dari memori. Melampirkan JSON raksasa ke komponen mana pun seperti menghubungkan gudang besar data yang tidak terpakai yang akan memperlambat performa komponen Anda.
129
+
130
+ - **Responsivitas perpindahan bahasa**: Saya mengganti bahasa menggunakan kontrol aplikasi itu sendiri dan menghitung waktu hingga halaman benar-benar beralih, apa yang akan diperhatikan oleh pengunjung.
131
+
132
+ - **Pekerjaan rendering setelah perubahan bahasa**: Tindak lanjut yang lebih sempit: seberapa besar upaya antarmuka untuk menggambar ulang untuk bahasa baru setelah perpindahan dimulai. Berguna saat waktu yang "dirasakan" dan biaya framework berbeda.
133
+
134
+ - **Waktu pemuatan halaman awal**: Dari navigasi hingga browser menganggap halaman dimuat sepenuhnya untuk skenario yang saya uji. Bagus untuk membandingkan cold start.
135
+
136
+ - **Waktu hidrasi (Hydration)**: Waktu yang dihabiskan klien untuk mengubah HTML server menjadi antarmuka interaktif. Tanda hubung dalam tabel berarti implementasi tersebut tidak memberikan angka hidrasi yang andal dalam benchmark ini.
137
+
138
+ ## Hasil secara mendetail
139
+
140
+ ### 1 — Solusi yang harus dihindari
141
+
142
+ > Tidak ada solusi yang jelas untuk dihindari dalam ekosistem Vue.
143
+
144
+ ### 2 — Solusi yang dapat diterima
145
+
146
+ **(vue-i18n)** (`vue-i18n@11.4.0`):
147
+
148
+ - **vue-i18n** tanpa keraguan adalah pustaka i18n yang paling banyak digunakan untuk Vue, ia memiliki banyak fitur dan ekosistem yang besar. Namun di balik layar solusinya cukup berat. Meskipun vue-i18n mengintegrasikan lazy loading untuk pesan, ia melewatkan fitur scoping. Dalam kasus aplikasi Vue SPA klasik tidak ada masalah, tetapi untuk aplikasi Nuxt, menggunakan @nuxt/i18n, hal itu menyebabkan penyertaan pesan dari semua halaman ke dalam satu halaman. Untuk aplikasi Nuxt besar yang mencakup lebih dari 10 halaman, ini bisa menjadi sangat bermasalah.
149
+
150
+ Paketnya sangat berat (~24.3kb, yang mana sekitar 9× `vue-intlayer`).
151
+
152
+ **(fluent-vue)** (`fluent-vue@0.5.0`):
153
+
154
+ - **fluent-vue** menawarkan satu upaya inovasi melalui format .ftl. Organisasi pesan sangat bagus, lebih mudah untuk memulai. Namun dalam praktiknya, kurangnya keamanan tipe meningkatkan risiko kesalahan dan dapat dengan cepat memakan waktu untuk proses debug. Selain itu, solusi tersebut memuat pesan menggunakan plugin vite yang memaksa pemuatan semua konten dalam semua bahasa ke setiap halaman. Selain itu, ini adalah solusi yang sangat berat (~92.7kb, yang mana sekitar 34× `vue-intlayer`).
155
+
156
+ ### 3 — Rekomendasi
157
+
158
+ **(Intlayer)** (`vue-intlayer@8.7.12`):
159
+
160
+ Saya tidak akan menilai `vue-intlayer` secara pribadi demi objektivitas, karena ini adalah solusi saya sendiri.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2024-08-13
3
- updatedAt: 2026-04-03
3
+ updatedAt: 2026-05-12
4
4
  title: Konfigurasi
5
5
  description: Pelajari cara mengonfigurasi Intlayer untuk aplikasi Anda. Pahami berbagai pengaturan dan opsi yang tersedia untuk menyesuaikan Intlayer sesuai kebutuhan Anda.
6
6
  keywords:
@@ -14,6 +14,9 @@ slugs:
14
14
  - concept
15
15
  - configuration
16
16
  history:
17
+ - version: 8.9.4
18
+ date: 2026-05-12
19
+ changes: "Menambahkan dukungan untuk penyedia LM Studio"
17
20
  - version: 8.7.0
18
21
  date: 2026-04-07
19
22
  changes: "Menambahkan opsi `minify` dan `prune` ke konfigurasi build"
@@ -350,7 +353,7 @@ const config: IntlayerConfig = {
350
353
  ai: {
351
354
  /**
352
355
  * Penyedia AI yang akan digunakan.
353
- * Opsi: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai'
356
+ * Opsi: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio'
354
357
  * Default: 'openai'
355
358
  */
356
359
  provider: "openai",
@@ -916,16 +919,17 @@ Intlayer mendukung berbagai penyedia AI untuk memastikan fleksibilitas maksimal.
916
919
  - **Groq**
917
920
  - **Amazon Bedrock**
918
921
  - **Together.ai**
919
-
920
- | Bidang | Deskripsi | Tipe | Default | Contoh | Catatan |
921
- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
922
- | `provider` | Penyedia yang akan digunakan untuk fitur AI Intlayer. | `'openai'` &#124; <br/> `'anthropic'` &#124; <br/> `'mistral'` &#124; <br/> `'deepseek'` &#124; <br/> `'gemini'` &#124; <br/> `'ollama'` &#124; <br/> `'openrouter'` &#124; <br/> `'alibaba'` &#124; <br/> `'fireworks'` &#124; <br/> `'groq'` &#124; <br/> `'huggingface'` &#124; <br/> `'bedrock'` &#124; <br/> `'googleaistudio'` &#124; <br/> `'googlevertex'` &#124; <br/> `'togetherai'` | `undefined` | `'anthropic'` | Penyedia yang berbeda memerlukan kunci API yang berbeda dan memiliki struktur harga yang berbeda pula. |
923
- | `model` | Model AI yang akan digunakan dalam fitur AI. | `string` | Tidak ada | `'gpt-4o-2024-11-20'` | Model tertentu bergantung pada penyedia. |
924
- | `temperature` | Mengontrol keacakan respons AI. | `number` | Tidak ada | `0.1` | Temperatur yang lebih tinggi = respons yang lebih kreatif tetapi kurang andal. |
925
- | `apiKey` | Kunci API Anda untuk penyedia yang dipilih. | `string` | Tidak ada | `process.env.OPENAI_API_KEY` | Jaga kerahasiaannya; simpan dalam variabel lingkungan. |
926
- | `applicationContext` | Konteks tambahan tentang aplikasi Anda untuk membantu AI menghasilkan terjemahan yang lebih akurat (domain, audiens target, nada, terminologi). | `string` | Tidak ada | `'mój własny kontekst aplikacji'` | Dapat digunakan untuk menambahkan aturan (misalnya: `"Anda tidak boleh menerjemahkan URL Anda"` ). |
927
- | `baseURL` | URL dasar untuk AI API. | `string` | Tidak ada | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | Dapat merujuk ke endpoint AI API lokal atau kustom. |
928
- | `dataSerialization` | Format serialisasi data untuk fitur AI. | `'json'` &#124; <br/> `'toon'` | `undefined` | `'toon'` | `'json'`: default, andal; menggunakan lebih banyak token.<br/>• `'toon'`: lebih sedikit token, kurang stabil.<br/>• Meneruskan parameter tambahan ke model (upaya penalaran, dll.). |
922
+ - **LM Studio**
923
+
924
+ | Bidang | Deskripsi | Tipe | Default | Contoh | Catatan |
925
+ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
926
+ | `provider` | Penyedia yang akan digunakan untuk fitur AI Intlayer. | `'openai'` &#124; <br/> `'anthropic'` &#124; <br/> `'mistral'` &#124; <br/> `'deepseek'` &#124; <br/> `'gemini'` &#124; <br/> `'ollama'` &#124; <br/> `'openrouter'` &#124; <br/> `'alibaba'` &#124; <br/> `'fireworks'` &#124; <br/> `'groq'` &#124; <br/> `'huggingface'` &#124; <br/> `'bedrock'` &#124; <br/> `'googleaistudio'` &#124; <br/> `'googlevertex'` &#124; <br/> `'togetherai'` &#124; <br/> `'lmstudio'` | `undefined` | `'anthropic'` | Penyedia yang berbeda memerlukan kunci API yang berbeda dan memiliki struktur harga yang berbeda pula. |
927
+ | `model` | Model AI yang akan digunakan dalam fitur AI. | `string` | Tidak ada | `'gpt-4o-2024-11-20'` | Model tertentu bergantung pada penyedia. |
928
+ | `temperature` | Mengontrol keacakan respons AI. | `number` | Tidak ada | `0.1` | Temperatur yang lebih tinggi = respons yang lebih kreatif tetapi kurang andal. |
929
+ | `apiKey` | Kunci API Anda untuk penyedia yang dipilih. | `string` | Tidak ada | `process.env.OPENAI_API_KEY` | Jaga kerahasiaannya; simpan dalam variabel lingkungan. |
930
+ | `applicationContext` | Konteks tambahan tentang aplikasi Anda untuk membantu AI menghasilkan terjemahan yang lebih akurat (domain, audiens target, nada, terminologi). | `string` | Tidak ada | `'mój własny kontekst aplikacji'` | Dapat digunakan untuk menambahkan aturan (misalnya: `"Anda tidak boleh menerjemahkan URL Anda"` ). |
931
+ | `baseURL` | URL dasar untuk AI API. | `string` | Tidak ada | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | Dapat merujuk ke endpoint AI API lokal atau kustom. |
932
+ | `dataSerialization` | Format serialisasi data untuk fitur AI. | `'json'` &#124; <br/> `'toon'` | `undefined` | `'toon'` | • `'json'`: default, andal; menggunakan lebih banyak token.<br/>• `'toon'`: lebih sedikit token, kurang stabil.<br/>• Meneruskan parameter tambahan ke model (upaya penalaran, dll.). |
929
933
 
930
934
  ---
931
935
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-02-07
3
- updatedAt: 2026-01-28
3
+ updatedAt: 2026-05-12
4
4
  title: Berkas Konten
5
5
  description: Pelajari cara menyesuaikan ekstensi untuk berkas deklarasi konten Anda. Ikuti dokumentasi ini untuk mengimplementasikan kondisi secara efisien dalam proyek Anda.
6
6
  keywords:
@@ -12,6 +12,9 @@ slugs:
12
12
  - concept
13
13
  - content
14
14
  history:
15
+ - version: 8.9.0
16
+ date: 2026-05-12
17
+ changes: "Add `plural` content node type"
15
18
  - version: 8.0.0
16
19
  date: 2026-01-28
17
20
  changes: "Tambahkan tipe node konten `html`"
@@ -66,6 +69,7 @@ import { type ReactNode } from "react";
66
69
  import {
67
70
  t,
68
71
  enu,
72
+ plural,
69
73
  cond,
70
74
  nest,
71
75
  md,
@@ -85,6 +89,7 @@ interface Content {
85
89
  };
86
90
  multilingualContent: string;
87
91
  quantityContent: string;
92
+ pluralContent: string;
88
93
  conditionalContent: string;
89
94
  markdownContent: never;
90
95
  htmlContent: never;
@@ -120,6 +125,10 @@ export default {
120
125
  ">5": "Beberapa mobil",
121
126
  ">19": "Banyak mobil",
122
127
  }),
128
+ pluralContent: plural({
129
+ one: "One car",
130
+ other: "{{count}} cars",
131
+ }),
123
132
  conditionalContent: cond({
124
133
  true: "Validasi diaktifkan",
125
134
  false: "Validasi dinonaktifkan",
@@ -174,6 +183,13 @@ export default {
174
183
  ">5": "Beberapa mobil",
175
184
  ">19": "Banyak mobil",
176
185
  },
186
+ "pluralContent": {
187
+ "nodeType": "plural",
188
+ "plural": {
189
+ "one": "One car",
190
+ "other": "{{count}} cars",
191
+ },
192
+ },
177
193
  },
178
194
  "conditionalContent": {
179
195
  "nodeType": "condition",
@@ -221,6 +237,7 @@ Content nodes adalah blok bangunan dari konten kamus. Mereka dapat berupa:
221
237
  - **Nilai primitif**: string, angka, boolean, null, undefined
222
238
  - **Node bertipe**: Jenis konten khusus seperti terjemahan, kondisi, markdown, dll.
223
239
  - **Fungsi**: Konten dinamis yang dapat dievaluasi saat runtime [lihat Pengambilan Fungsi](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/function_fetching.md)
240
+ - **Plural Content**: See Plural Content [See Plural Content](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/plural.md)
224
241
  - **Konten bersarang**: Referensi ke kamus lain
225
242
 
226
243
  #### Jenis Konten
@@ -551,6 +568,8 @@ multilingualContent: t({
551
568
  });
552
569
  ```
553
570
 
571
+ > See [Konten Terjemahan (`t`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/translation.md) for more information.
572
+
554
573
  ### Konten Kondisi (`cond`)
555
574
 
556
575
  Konten yang berubah berdasarkan kondisi boolean:
@@ -564,6 +583,8 @@ conditionalContent: cond({
564
583
  });
565
584
  ```
566
585
 
586
+ > See [Konten Kondisi (`cond`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/condition.md) for more information.
587
+
567
588
  ### Konten Enumerasi (`enu`)
568
589
 
569
590
  Konten yang bervariasi berdasarkan nilai enumerasi:
@@ -578,6 +599,23 @@ statusContent: enu({
578
599
  });
579
600
  ```
580
601
 
602
+ > See [Konten Enumerasi (`enu`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/enumeration.md) for more information.
603
+
604
+ ### Plural Content (`plural`)
605
+
606
+ Content that varies based on plural rules:
607
+
608
+ ```typescript
609
+ import { plural } from "intlayer";
610
+
611
+ pluralContent: plural({
612
+ one: "One car",
613
+ other: "{{count}} cars",
614
+ });
615
+ ```
616
+
617
+ > See [Plural Content Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/plural.md) for more information.
618
+
581
619
  ### Konten Penyisipan (`insert`)
582
620
 
583
621
  Konten yang dapat disisipkan ke dalam konten lain:
@@ -588,6 +626,8 @@ import { insert } from "intlayer";
588
626
  insertionContent: insert("Teks ini dapat disisipkan di mana saja");
589
627
  ```
590
628
 
629
+ > See [Konten Penyisipan (`insert`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/insertion.md) for more information.
630
+
591
631
  ### Konten Bersarang (`nest`)
592
632
 
593
633
  Referensi ke kamus lain:
@@ -598,6 +638,8 @@ import { nest } from "intlayer";
598
638
  nestedContent: nest("about-page");
599
639
  ```
600
640
 
641
+ > See [Konten Bersarang (`nest`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/nesting.md) for more information.
642
+
601
643
  ### Konten Markdown (`md`)
602
644
 
603
645
  Konten teks kaya dalam format Markdown:
@@ -610,6 +652,8 @@ markdownContent: md(
610
652
  );
611
653
  ```
612
654
 
655
+ > See [Konten Markdown (`md`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/markdown.md) for more information.
656
+
613
657
  ### Konten HTML (`html`)
614
658
 
615
659
  Konten HTML kaya yang dapat menggunakan tag standar atau komponen kustom:
@@ -627,6 +671,8 @@ localizedHtmlContent: t({
627
671
  });
628
672
  ```
629
673
 
674
+ > See [Konten HTML (`html`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/html.md) for more information.
675
+
630
676
  ### Konten Gender (`gender`)
631
677
 
632
678
  Konten yang bervariasi berdasarkan gender:
@@ -641,6 +687,8 @@ genderContent: gender({
641
687
  });
642
688
  ```
643
689
 
690
+ > See [Konten Gender (`gender`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/gender.md) for more information.
691
+
644
692
  ### Konten File (`file`)
645
693
 
646
694
  Referensi ke file eksternal:
@@ -651,6 +699,8 @@ import { file } from "intlayer";
651
699
  fileContent: file("./path/to/content.txt");
652
700
  ```
653
701
 
702
+ > See [Konten File (`file`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dictionary/file.md) for more information.
703
+
654
704
  ## Membuat File Konten
655
705
 
656
706
  ### Struktur Dasar File Konten
@@ -160,30 +160,9 @@ syncPO({
160
160
  source: ({ key, locale }) => string, // wajib
161
161
  location?: string, // label opsional, default: "sync-po::path/to/source"
162
162
  priority?: number, // prioritas opsional untuk resolusi konflik, default: 0
163
- format?: 'icu' | 'i18next' | 'vue-i18n', // opsional, hanya diperlukan jika nilai msgstr Anda menggunakan sintaks interpolasi tertentu
164
163
  });
165
164
  ```
166
165
 
167
- #### `format` ('icu' | 'i18next' | 'vue-i18n')
168
-
169
- File PO selalu berupa file Gettext Portable Object — itu sudah tetap. Opsi ini hanya menjelaskan **sintaks interpolasi** yang digunakan di dalam nilai `msgstr`, sehingga Intlayer dapat mengonversinya ke formatnya sendiri pada saat penguraian (melalui `formatDictionary`) dan kembali saat menulis output.
170
-
171
- - `undefined` _(default)_: nilai `msgstr` diperlakukan sebagai string biasa — tidak ada transformasi. Gunakan ini untuk sebagian besar file PO.
172
- - `'icu'`: nilai `msgstr` menggunakan sintaks pesan ICU (misalnya `{count, plural, one {# item} other {# items}}`).
173
- - `'i18next'`: nilai `msgstr` menggunakan sintaks interpolasi i18next (misalnya `{{variable}}`).
174
- - `'vue-i18n'`: nilai `msgstr` menggunakan sintaks Vue I18n.
175
-
176
- > Transformasi diterapkan oleh `formatDictionary` dari `@intlayer/chokidar` pada saat pemuatan, dan dibalik dengan `formatDictionaryOutput` pada saat penulisan. Untuk aturan kompleks seperti jamak ICU, kesetiaan bolak-balik tidak dijamin.
177
-
178
- **Contoh — file PO berisi interpolasi gaya i18next:**
179
-
180
- ```ts
181
- syncPO({
182
- source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
183
- format: "i18next",
184
- }),
185
- ```
186
-
187
166
  ### Beberapa sumber PO dan prioritas
188
167
 
189
168
  Anda dapat menambahkan beberapa plugin `syncPO` untuk menyinkronkan sumber PO yang berbeda. Ini berguna ketika Anda memiliki beberapa sumber terjemahan atau struktur PO yang berbeda dalam proyek Anda.
@@ -21,7 +21,7 @@ history:
21
21
 
22
22
  # Benchmark - Rapporto
23
23
 
24
- Benchmark Bloom è una suite di benchmark sulle prestazioni che misura l'impatto reale delle librerie i18n (internazionalizzazione) su più framework React e strategie di caricamento.
24
+ Benchmark Bloom è una suite di benchmark sulle prestazioni que misura l'impatto reale delle librerie i18n (internazionalizzazione) su più framework React e strategie di caricamento.
25
25
 
26
26
  Di seguito trovi i rapporti dettagliati e la documentazione tecnica per ciascun framework:
27
27
 
@@ -30,6 +30,3 @@ Di seguito trovi i rapporti dettagliati e la documentazione tecnica per ciascun
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)