@intlayer/docs 9.0.0-canary.7 → 9.0.0-canary.9
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 +0 -20
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +0 -20
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +0 -1
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/dynamic_dictionaries/index.md +24 -18
- package/docs/ar/dynamic_dictionaries/variants.md +280 -22
- package/docs/ar/plugins/sync-json.md +0 -1
- package/docs/ar/releases/v9.md +35 -12
- package/docs/de/dynamic_dictionaries/index.md +22 -22
- package/docs/de/dynamic_dictionaries/variants.md +272 -14
- package/docs/de/plugins/sync-json.md +0 -1
- package/docs/de/releases/v9.md +35 -12
- package/docs/en/dynamic_dictionaries/index.md +20 -14
- package/docs/en/dynamic_dictionaries/variants.md +266 -8
- package/docs/en/plugins/sync-json.md +0 -1
- package/docs/en/releases/v9.md +35 -12
- package/docs/en-GB/dynamic_dictionaries/index.md +21 -15
- package/docs/en-GB/dynamic_dictionaries/variants.md +268 -10
- package/docs/en-GB/plugins/sync-json.md +0 -1
- package/docs/en-GB/releases/v9.md +35 -12
- package/docs/es/dynamic_dictionaries/index.md +25 -19
- package/docs/es/dynamic_dictionaries/variants.md +275 -17
- package/docs/es/plugins/sync-json.md +0 -1
- package/docs/es/releases/v9.md +35 -12
- package/docs/fr/dynamic_dictionaries/index.md +26 -20
- package/docs/fr/dynamic_dictionaries/variants.md +273 -15
- package/docs/fr/plugins/sync-json.md +0 -1
- package/docs/fr/releases/v9.md +35 -12
- package/docs/hi/dynamic_dictionaries/index.md +28 -22
- package/docs/hi/dynamic_dictionaries/variants.md +282 -24
- package/docs/hi/plugins/sync-json.md +0 -1
- package/docs/hi/releases/v9.md +35 -12
- package/docs/id/dynamic_dictionaries/index.md +25 -19
- package/docs/id/dynamic_dictionaries/variants.md +274 -16
- package/docs/id/plugins/sync-json.md +0 -1
- package/docs/id/releases/v9.md +35 -12
- package/docs/it/dynamic_dictionaries/index.md +26 -20
- package/docs/it/dynamic_dictionaries/variants.md +273 -15
- package/docs/it/plugins/sync-json.md +0 -1
- package/docs/it/releases/v9.md +35 -12
- package/docs/ja/dynamic_dictionaries/index.md +27 -21
- package/docs/ja/dynamic_dictionaries/variants.md +276 -18
- package/docs/ja/plugins/sync-json.md +0 -1
- package/docs/ja/releases/v9.md +35 -12
- package/docs/ko/dynamic_dictionaries/index.md +23 -17
- package/docs/ko/dynamic_dictionaries/variants.md +273 -15
- package/docs/ko/plugins/sync-json.md +0 -1
- package/docs/ko/releases/v9.md +35 -12
- package/docs/pl/dynamic_dictionaries/index.md +26 -20
- package/docs/pl/dynamic_dictionaries/variants.md +275 -17
- package/docs/pl/plugins/sync-json.md +0 -1
- package/docs/pl/releases/v9.md +35 -12
- package/docs/pt/dynamic_dictionaries/index.md +25 -19
- package/docs/pt/dynamic_dictionaries/variants.md +276 -18
- package/docs/pt/plugins/sync-json.md +0 -1
- package/docs/pt/releases/v9.md +35 -12
- package/docs/ru/dynamic_dictionaries/index.md +25 -19
- package/docs/ru/dynamic_dictionaries/variants.md +277 -19
- package/docs/ru/plugins/sync-json.md +0 -1
- package/docs/ru/releases/v9.md +35 -12
- package/docs/tr/dynamic_dictionaries/index.md +27 -21
- package/docs/tr/dynamic_dictionaries/variants.md +274 -16
- package/docs/tr/plugins/sync-json.md +0 -1
- package/docs/tr/releases/v9.md +35 -12
- package/docs/uk/dynamic_dictionaries/index.md +25 -19
- package/docs/uk/dynamic_dictionaries/variants.md +277 -19
- package/docs/uk/plugins/sync-json.md +0 -1
- package/docs/uk/releases/v9.md +35 -12
- package/docs/vi/dynamic_dictionaries/index.md +28 -22
- package/docs/vi/dynamic_dictionaries/variants.md +278 -20
- package/docs/vi/plugins/sync-json.md +0 -1
- package/docs/vi/releases/v9.md +35 -12
- package/docs/zh/dynamic_dictionaries/index.md +24 -18
- package/docs/zh/dynamic_dictionaries/variants.md +274 -16
- package/docs/zh/plugins/sync-json.md +0 -1
- package/docs/zh/releases/v9.md +35 -12
- package/package.json +6 -6
- package/src/generated/docs.entry.ts +0 -20
- package/docs/ar/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/de/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/en/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/en-GB/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/es/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/fr/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/hi/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/id/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/it/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/ja/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/ko/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/pl/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/pt/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/ru/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/tr/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/uk/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/vi/dynamic_dictionaries/dynamic_content.md +0 -271
- package/docs/zh/dynamic_dictionaries/dynamic_content.md +0 -271
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: Varian
|
|
5
|
-
description: Gunakan
|
|
5
|
+
description: Gunakan field metadata variant di file konten Intlayer untuk mendeklarasikan alternatif konten bernama atau terstruktur — pengujian A/B, banner musiman, teks ber-feature flag, record CMS, konten khusus pengguna — dan beralih di antaranya saat runtime tanpa perubahan kode.
|
|
6
6
|
keywords:
|
|
7
7
|
- Varian
|
|
8
8
|
- Pengujian A/B
|
|
9
|
-
-
|
|
9
|
+
- Feature Flag
|
|
10
10
|
- Konten Dinamis
|
|
11
|
+
- Record Dinamis
|
|
12
|
+
- CMS
|
|
11
13
|
- Intlayer
|
|
12
14
|
- Internasionalisasi
|
|
13
15
|
slugs:
|
|
@@ -17,17 +19,27 @@ slugs:
|
|
|
17
19
|
history:
|
|
18
20
|
- version: 9.0.0
|
|
19
21
|
date: 2026-06-12
|
|
20
|
-
changes: "Rilis fitur varian
|
|
22
|
+
changes: "Rilis fitur varian"
|
|
23
|
+
- version: 9.1.0
|
|
24
|
+
date: 2026-06-26
|
|
25
|
+
changes: "`variant` kini menerima string atau objek — `meta` / record dinamis sebelumnya dideklarasikan sebagai varian objek"
|
|
21
26
|
author: aymericzip
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
# Varian
|
|
25
30
|
|
|
26
|
-
Sebuah **varian**
|
|
31
|
+
Sebuah **varian** adalah sekumpulan file konten yang berbagi `key` kamus yang sama tetapi masing-masing membawa nilai `variant` yang berbeda. Intlayer menyajikan file yang sesuai berdasarkan selektor yang diberikan ke `useIntlayer`.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
Nilai `variant` dapat berupa **dua bentuk**:
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
- **String** — satu alternatif bernama (pengujian A/B, banner musiman, feature flag).
|
|
36
|
+
- **Objek** — diskriminator terstruktur yang dialamatkan oleh sekumpulan field (record CMS, konten khusus pengguna, konten apa pun yang dikunci oleh ID buram). Seluruh objek adalah identitasnya: selektor harus memberikan objek yang **sama** untuk menyelesaikan entri.
|
|
37
|
+
|
|
38
|
+
> Bentuk objek menggantikan field `meta` sebelumnya. Di mana pun Anda dulu menulis `meta: { id, … }`, tulis `variant: { id, … }`, dan pilih dengan `{ variant: { id, … } }`.
|
|
39
|
+
|
|
40
|
+
## Varian bernama (string)
|
|
41
|
+
|
|
42
|
+
Setiap file mewakili satu alternatif bernama. Menghilangkan `variant` (atau mengaturnya ke `"default"`) menandainya sebagai fallback.
|
|
31
43
|
|
|
32
44
|
```ts fileName="hero-banner.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
33
45
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -65,9 +77,9 @@ const dictionary = {
|
|
|
65
77
|
export default dictionary;
|
|
66
78
|
```
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
### Mengonsumsi varian bernama
|
|
69
81
|
|
|
70
|
-
|
|
82
|
+
#### Varian default
|
|
71
83
|
|
|
72
84
|
<Tabs group="framework">
|
|
73
85
|
<Tab label="React" value="react">
|
|
@@ -209,7 +221,7 @@ export default dictionary;
|
|
|
209
221
|
</Tab>
|
|
210
222
|
</Tabs>
|
|
211
223
|
|
|
212
|
-
|
|
224
|
+
#### Varian bernama
|
|
213
225
|
|
|
214
226
|
```tsx
|
|
215
227
|
const { headline, cta } = useIntlayer("hero-banner", {
|
|
@@ -217,18 +229,264 @@ const { headline, cta } = useIntlayer("hero-banner", {
|
|
|
217
229
|
});
|
|
218
230
|
```
|
|
219
231
|
|
|
220
|
-
|
|
232
|
+
#### Varian bernama dengan locale eksplisit
|
|
221
233
|
|
|
222
234
|
```tsx
|
|
223
235
|
const content = useIntlayer("hero-banner", {
|
|
224
236
|
variant: "black_friday",
|
|
225
|
-
locale: "
|
|
237
|
+
locale: "fr",
|
|
226
238
|
});
|
|
227
239
|
```
|
|
228
240
|
|
|
241
|
+
## Varian objek (terstruktur)
|
|
242
|
+
|
|
243
|
+
Varian objek mengalamatkan konten dengan sekumpulan pasangan key-value sewenang-wenang yang dideklarasikan di field `variant` — memungkinkan pemodelan record CMS, konten khusus pengguna, atau konten apa pun yang kuncinya berupa ID buram. **Seluruh objek** adalah identitasnya: selektor harus memberikan objek yang sama agar entri diselesaikan.
|
|
244
|
+
|
|
245
|
+
```ts fileName="product.abc.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
246
|
+
import { t, type Dictionary } from "intlayer";
|
|
247
|
+
|
|
248
|
+
const dictionary = {
|
|
249
|
+
key: "product",
|
|
250
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
251
|
+
content: {
|
|
252
|
+
name: t({ en: "Widget Pro", fr: "Widget Pro" }),
|
|
253
|
+
description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
|
|
254
|
+
},
|
|
255
|
+
} satisfies Dictionary;
|
|
256
|
+
|
|
257
|
+
export default dictionary;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```ts fileName="product.abcd.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
261
|
+
import { t, type Dictionary } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const dictionary = {
|
|
264
|
+
key: "product",
|
|
265
|
+
variant: { id: "prod_abcd", userId: "user_123" },
|
|
266
|
+
content: {
|
|
267
|
+
name: t({ en: "Widget Lite", fr: "Widget Lite" }),
|
|
268
|
+
description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
|
|
269
|
+
},
|
|
270
|
+
} satisfies Dictionary;
|
|
271
|
+
|
|
272
|
+
export default dictionary;
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Mengonsumsi varian objek
|
|
276
|
+
|
|
277
|
+
Berikan objek yang cocok ke `variant`. Setiap field yang dideklarasikan pada kamus harus disediakan dan sama; jika tidak, hasilnya `null`. Urutan field tidak penting.
|
|
278
|
+
|
|
279
|
+
<Tabs group="framework">
|
|
280
|
+
<Tab label="React" value="react">
|
|
281
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
282
|
+
import { useIntlayer } from "react-intlayer";
|
|
283
|
+
|
|
284
|
+
export const Product = ({
|
|
285
|
+
productId,
|
|
286
|
+
userId,
|
|
287
|
+
}: {
|
|
288
|
+
productId: string;
|
|
289
|
+
userId: string;
|
|
290
|
+
}) => {
|
|
291
|
+
const content = useIntlayer("product", {
|
|
292
|
+
variant: { id: productId, userId },
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
if (!content) return null;
|
|
296
|
+
|
|
297
|
+
return <p>{content.description}</p>;
|
|
298
|
+
};
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
</Tab>
|
|
302
|
+
<Tab label="Next.js" value="nextjs">
|
|
303
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
304
|
+
import { useIntlayer } from "next-intlayer";
|
|
305
|
+
|
|
306
|
+
export const Product = ({
|
|
307
|
+
productId,
|
|
308
|
+
userId,
|
|
309
|
+
}: {
|
|
310
|
+
productId: string;
|
|
311
|
+
userId: string;
|
|
312
|
+
}) => {
|
|
313
|
+
const content = useIntlayer("product", {
|
|
314
|
+
variant: { id: productId, userId },
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (!content) return null;
|
|
318
|
+
|
|
319
|
+
return <p>{content.description}</p>;
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
</Tab>
|
|
324
|
+
<Tab label="Vue" value="vue">
|
|
325
|
+
```vue fileName="Product.vue" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
326
|
+
<script setup>
|
|
327
|
+
import { useIntlayer } from "vue-intlayer";
|
|
328
|
+
|
|
329
|
+
const props = defineProps({
|
|
330
|
+
productId: String,
|
|
331
|
+
userId: String,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const content = useIntlayer("product", {
|
|
335
|
+
variant: { id: props.productId, userId: props.userId },
|
|
336
|
+
});
|
|
337
|
+
</script>
|
|
338
|
+
|
|
339
|
+
<template>
|
|
340
|
+
<p v-if="content">{{ content.description }}</p>
|
|
341
|
+
</template>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
</Tab>
|
|
345
|
+
<Tab label="Svelte" value="svelte">
|
|
346
|
+
```svelte fileName="Product.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
347
|
+
<script lang="ts">
|
|
348
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
349
|
+
|
|
350
|
+
export let productId: string;
|
|
351
|
+
export let userId: string;
|
|
352
|
+
|
|
353
|
+
const content = useIntlayer("product", {
|
|
354
|
+
variant: { id: productId, userId },
|
|
355
|
+
});
|
|
356
|
+
</script>
|
|
357
|
+
|
|
358
|
+
{#if $content}
|
|
359
|
+
<p>{$content.description}</p>
|
|
360
|
+
{/if}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
</Tab>
|
|
364
|
+
<Tab label="Preact" value="preact">
|
|
365
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
366
|
+
import { useIntlayer } from "preact-intlayer";
|
|
367
|
+
|
|
368
|
+
export const Product = ({
|
|
369
|
+
productId,
|
|
370
|
+
userId,
|
|
371
|
+
}: {
|
|
372
|
+
productId: string;
|
|
373
|
+
userId: string;
|
|
374
|
+
}) => {
|
|
375
|
+
const content = useIntlayer("product", {
|
|
376
|
+
variant: { id: productId, userId },
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if (!content) return null;
|
|
380
|
+
|
|
381
|
+
return <p>{content.description}</p>;
|
|
382
|
+
};
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
</Tab>
|
|
386
|
+
<Tab label="Solid" value="solid">
|
|
387
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
388
|
+
import { useIntlayer } from "solid-intlayer";
|
|
389
|
+
|
|
390
|
+
export const Product = (props: {
|
|
391
|
+
productId: string;
|
|
392
|
+
userId: string;
|
|
393
|
+
}) => {
|
|
394
|
+
const content = useIntlayer("product", {
|
|
395
|
+
variant: { id: props.productId, userId: props.userId },
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
return (
|
|
399
|
+
<>
|
|
400
|
+
{content() && <p>{content().description}</p>}
|
|
401
|
+
</>
|
|
402
|
+
);
|
|
403
|
+
};
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
</Tab>
|
|
407
|
+
<Tab label="Angular" value="angular">
|
|
408
|
+
```typescript fileName="product.component.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
409
|
+
import { Component, Input, OnInit } from "@angular/core";
|
|
410
|
+
import { useIntlayer } from "angular-intlayer";
|
|
411
|
+
|
|
412
|
+
@Component({
|
|
413
|
+
selector: "app-product",
|
|
414
|
+
template: `
|
|
415
|
+
@if (content()) {
|
|
416
|
+
<p>{{ content().description }}</p>
|
|
417
|
+
}
|
|
418
|
+
`,
|
|
419
|
+
})
|
|
420
|
+
export class ProductComponent implements OnInit {
|
|
421
|
+
@Input() productId!: string;
|
|
422
|
+
@Input() userId!: string;
|
|
423
|
+
|
|
424
|
+
content: any;
|
|
425
|
+
|
|
426
|
+
ngOnInit() {
|
|
427
|
+
this.content = useIntlayer("product", {
|
|
428
|
+
variant: { id: this.productId, userId: this.userId },
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
</Tab>
|
|
435
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
436
|
+
```javascript fileName="product.js"
|
|
437
|
+
import { useIntlayer } from "vanilla-intlayer";
|
|
438
|
+
|
|
439
|
+
const content = useIntlayer("product", {
|
|
440
|
+
variant: { id: "prod_abcd", userId: "user_123" },
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
if (content) {
|
|
444
|
+
document.body.innerHTML = `<p>${content.description}</p>`;
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
</Tab>
|
|
449
|
+
</Tabs>
|
|
450
|
+
|
|
451
|
+
#### Dengan locale eksplisit
|
|
452
|
+
|
|
453
|
+
```tsx
|
|
454
|
+
const content = useIntlayer("product", {
|
|
455
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
456
|
+
locale: "fr",
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### Field hilang — tidak cocok
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
// Mengembalikan null: `userId` hilang, sehingga objek tidak cocok dengan varian yang dideklarasikan
|
|
464
|
+
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Mode pemuatan
|
|
468
|
+
|
|
469
|
+
Varian objek sering dimuat secara malas. Atur `importMode` pada kamus untuk mengendalikannya:
|
|
470
|
+
|
|
471
|
+
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
472
|
+
const dictionary = {
|
|
473
|
+
key: "product",
|
|
474
|
+
importMode: "fetch", // or "dynamic"
|
|
475
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
476
|
+
content: { … },
|
|
477
|
+
} satisfies Dictionary;
|
|
478
|
+
|
|
479
|
+
export default dictionary;
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Lihat [optimasi bundle](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/bundle_optimization.md) untuk detail tentang mode `static`, `dynamic`, dan `fetch`.
|
|
483
|
+
|
|
229
484
|
## Kasus penggunaan umum
|
|
230
485
|
|
|
231
|
-
- Pengujian
|
|
232
|
-
-
|
|
233
|
-
- Pesan
|
|
234
|
-
- Kampanye pemasaran
|
|
486
|
+
- Pengujian A/B teks yang digerakkan oleh kunci eksperimen
|
|
487
|
+
- Banner musiman atau promosi
|
|
488
|
+
- Pesan ber-feature flag
|
|
489
|
+
- Kampanye pemasaran spesifik locale
|
|
490
|
+
- Teks pemasaran per-produk yang dikelola di CMS
|
|
491
|
+
- Konten khusus pengguna atau akun
|
|
492
|
+
- Konten apa pun yang dikunci oleh ID buram saat runtime
|
|
@@ -108,7 +108,6 @@ const config: IntlayerConfig = {
|
|
|
108
108
|
* Will load, and write the output and translations back to the JSON files in the locales directory
|
|
109
109
|
*/
|
|
110
110
|
syncJSON({
|
|
111
|
-
format: "i18next",
|
|
112
111
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
113
112
|
priority: 0,
|
|
114
113
|
format: "i18next",
|
package/docs/id/releases/v9.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: Intlayer v9 Baru - Apa yang baru?
|
|
5
|
-
description: Temukan apa yang baru di Intlayer v9. Memperkenalkan paket kompatibilitas drop-in untuk pustaka i18n populer dan dukungan untuk Collections
|
|
5
|
+
description: Temukan apa yang baru di Intlayer v9. Memperkenalkan paket kompatibilitas drop-in untuk pustaka i18n populer dan dukungan untuk Collections dan Variants.
|
|
6
6
|
keywords:
|
|
7
7
|
- Intlayer
|
|
8
8
|
- Kompatibilitas
|
|
9
9
|
- Migrasi
|
|
10
10
|
- Collections
|
|
11
11
|
- Variants
|
|
12
|
-
- Dynamic Records
|
|
13
12
|
- i18next
|
|
14
13
|
- next-intl
|
|
15
14
|
- vue-i18n
|
|
@@ -22,7 +21,7 @@ author: aymericzip
|
|
|
22
21
|
|
|
23
22
|
# Intlayer v9 Baru - Apa yang baru?
|
|
24
23
|
|
|
25
|
-
Selamat datang di Intlayer v9! Rilis besar ini menandai tonggak sejarah besar dalam menyederhanakan jalur migrasi ke Intlayer dengan **Compat Adapter Packages** untuk pustaka i18n utama (`react-i18next`, `next-intl`, `vue-i18n`, dll.) dan menambahkan dukungan untuk struktur konten yang kaya: **Collections
|
|
24
|
+
Selamat datang di Intlayer v9! Rilis besar ini menandai tonggak sejarah besar dalam menyederhanakan jalur migrasi ke Intlayer dengan **Compat Adapter Packages** untuk pustaka i18n utama (`react-i18next`, `next-intl`, `vue-i18n`, dll.) dan menambahkan dukungan untuk struktur konten yang kaya: **Collections** dan **Variants**.
|
|
26
25
|
|
|
27
26
|
## Daftar Isi
|
|
28
27
|
|
|
@@ -41,8 +40,10 @@ Dengan mengganti impor, Anda mendapatkan semua manfaat Intlayer (termasuk type s
|
|
|
41
40
|
- `@intlayer/i18next`
|
|
42
41
|
- `@intlayer/react-i18next`
|
|
43
42
|
- `@intlayer/next-intl`
|
|
43
|
+
- `@intlayer/react-intl`
|
|
44
44
|
- `@intlayer/next-i18next`
|
|
45
45
|
- `@intlayer/vue-i18n`
|
|
46
|
+
- `@intlayer/lingui`
|
|
46
47
|
|
|
47
48
|
Sebagai contoh, cukup ubah:
|
|
48
49
|
|
|
@@ -100,7 +101,7 @@ Semua compat adapter sekarang merutekan resolusi terjemahan melalui satu parser
|
|
|
100
101
|
|
|
101
102
|
---
|
|
102
103
|
|
|
103
|
-
## Spesifikasi Fitur: Collections
|
|
104
|
+
## Spesifikasi Fitur: Collections & Variants
|
|
104
105
|
|
|
105
106
|
Intlayer v9 berkembang melampaui objek key-value statis, memungkinkan dictionary untuk mendeklarasikan struktur tata letak dinamis yang sepenuhnya bertipe (fully typed) dari ujung ke ujung (end-to-end).
|
|
106
107
|
|
|
@@ -144,6 +145,8 @@ const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: s
|
|
|
144
145
|
|
|
145
146
|
Sajikan pengujian A/B (A/B tests), header musiman, feature flags, atau landing page kustom:
|
|
146
147
|
|
|
148
|
+
#### Varian string (misal, pengujian A/B)
|
|
149
|
+
|
|
147
150
|
```ts fileName="hero.content.ts"
|
|
148
151
|
import { t, type Dictionary } from "intlayer";
|
|
149
152
|
|
|
@@ -167,16 +170,14 @@ export default {
|
|
|
167
170
|
const banner = useIntlayer("hero-banner", { variant: "black_friday" });
|
|
168
171
|
```
|
|
169
172
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
Definisikan dictionary yang entrinya dimuat secara dinamis pada saat runtime melalui ID kueri:
|
|
173
|
+
#### Varian objek (misal, Dynamic Records)
|
|
173
174
|
|
|
174
175
|
```ts fileName="product.content.ts"
|
|
175
176
|
import { t, type Dictionary } from "intlayer";
|
|
176
177
|
|
|
177
178
|
export default {
|
|
178
179
|
key: "product-copy",
|
|
179
|
-
|
|
180
|
+
variant: {
|
|
180
181
|
id: "prod_123",
|
|
181
182
|
category: "books",
|
|
182
183
|
},
|
|
@@ -229,7 +230,7 @@ export default defineConfig({
|
|
|
229
230
|
});
|
|
230
231
|
```
|
|
231
232
|
|
|
232
|
-
- **Compiler**: Diaktifkan secara otomatis ketika `compiler.enabled` diatur dan jalur `compiler.output` dikonfigurasi. Anda tidak lagi perlu mendaftarkan `intlayerCompiler()` secara terpisah.
|
|
233
|
+
- **Compiler**: Diaktifkan secara otomatis ketika `compiler.enabled` diatur ke `true` dan jalur `compiler.output` dikonfigurasi. Anda tidak lagi perlu mendaftarkan `intlayerCompiler()` secara terpisah.
|
|
233
234
|
- **Proxy**: Diaktifkan secara otomatis berdasarkan opsi `routing.enableProxy` yang baru (`true` secara default). Ini menghubungkan middleware deteksi locale / redirect / rewrite dalam pengembangan, preview, dan SSR produksi. Anda tidak lagi perlu mendaftarkan `intlayerProxy()` secara terpisah.
|
|
234
235
|
|
|
235
236
|
### Opsi `routing.enableProxy`
|
|
@@ -252,6 +253,27 @@ Plugin standalone `intlayerCompiler()` dan `intlayerProxy()` tetap diekspor untu
|
|
|
252
253
|
|
|
253
254
|
---
|
|
254
255
|
|
|
256
|
+
## Compiler dinonaktifkan secara default
|
|
257
|
+
|
|
258
|
+
Mulai dari Intlayer v9, **compiler dinonaktifkan secara default** (`compiler.enabled` sekarang default-nya `false`). Untuk mengaktifkan ekstraksi file `.content.ts` Anda pada saat build, atur `compiler.enabled: true` di konfigurasi Anda:
|
|
259
|
+
|
|
260
|
+
```ts fileName="intlayer.config.ts"
|
|
261
|
+
import type { IntlayerConfig } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const config: IntlayerConfig = {
|
|
264
|
+
compiler: {
|
|
265
|
+
enabled: true, // Default: false — diperlukan untuk mengaktifkan compiler sejak v9
|
|
266
|
+
output: ({ fileName }) => `./${fileName}.content.ts`,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default config;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Ketika compiler dinonaktifkan, Intlayer melewati langkah ekstraksi saat build dan mengandalkan dictionary yang sudah Anda deklarasikan. Aktifkan hanya ketika Anda ingin plugin bundler (`@intlayer/swc`, `@intlayer/babel`, atau plugin Vite `intlayer()`) mengekstrak konten secara otomatis.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
255
277
|
## React Native: impor paket tunggal
|
|
256
278
|
|
|
257
279
|
Dalam aplikasi React Native atau Expo, Anda tidak perlu lagi beralih antara `react-intlayer` dan `react-native-intlayer`. Paket `react-native-intlayer` sekarang **mengekspor ulang seluruh API `react-intlayer`** (hooks, utilitas, dan subjalur `/format`, `/html`, dan `/markdown`), dan `IntlayerProvider`-nya secara otomatis menerapkan polyfill React Native.
|
|
@@ -278,13 +300,14 @@ npm install intlayer react-native-intlayer
|
|
|
278
300
|
|
|
279
301
|
Jika Anda memperbarui dari v8, perhatikan bahwa v9 tidak menyertakan breaking changes (perubahan yang merusak). Namun berikut adalah perubahan utamanya:
|
|
280
302
|
|
|
303
|
+
- **Compiler dinonaktifkan secara default**: `compiler.enabled` sekarang default-nya `false`. Jika Anda mengandalkan ekstraksi file `.content.ts` saat build, atur `compiler.enabled: true` di `intlayer.config.ts` Anda.
|
|
281
304
|
- **Locales & Dialects**: Jika menggunakan dependensi i18n eksternal, tambahkan plugin compat adapter masing-masing dalam konfigurasi atau pengaturan bundler Anda untuk menulis ulang impor secara otomatis.
|
|
282
|
-
- **Custom Selectors**: Saat memanggil `useIntlayer`, parameter kedua sekarang dicadangkan untuk objek opsi yang berisi `{ locale, item, variant
|
|
305
|
+
- **Custom Selectors**: Saat memanggil `useIntlayer`, parameter kedua sekarang dicadangkan untuk objek opsi yang berisi `{ locale, item, variant }`. Jika sebelumnya Anda meneruskan string locale secara langsung, Anda masih dapat melakukannya, tetapi menggunakan objek opsi sangat direkomendasikan untuk pemilihan tingkat lanjut.
|
|
283
306
|
|
|
284
307
|
---
|
|
285
308
|
|
|
286
309
|
## Tautan berguna
|
|
287
310
|
|
|
288
311
|
- [Panduan Compat Adapter Packages](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/compat/index.md)
|
|
289
|
-
- [Dynamic Dictionaries - Collections
|
|
312
|
+
- [Dynamic Dictionaries - Collections & Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/dynamic_dictionaries/index.md)
|
|
290
313
|
- [Referensi Konfigurasi](https://github.com/aymericzip/intlayer/blob/main/docs/docs/id/configuration.md)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
4
|
-
title: Dizionari
|
|
5
|
-
description: Panoramica delle
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
|
+
title: Dizionari dinamici
|
|
5
|
+
description: Panoramica delle funzionalità dei dizionari dinamici di Intlayer — collezioni e varianti — per creare contenuti i18n flessibili e guidati a runtime.
|
|
6
6
|
keywords:
|
|
7
|
-
- Dizionari
|
|
7
|
+
- Dizionari dinamici
|
|
8
8
|
- Collezioni
|
|
9
9
|
- Varianti
|
|
10
|
-
- Record Dinamici
|
|
11
10
|
- Intlayer
|
|
12
11
|
- Internazionalizzazione
|
|
13
12
|
slugs:
|
|
@@ -18,31 +17,38 @@ history:
|
|
|
18
17
|
- version: 9.0.0
|
|
19
18
|
date: 2026-06-12
|
|
20
19
|
changes: "Rilascio della funzionalità dei dizionari dinamici"
|
|
20
|
+
- version: 9.1.0
|
|
21
|
+
date: 2026-06-26
|
|
22
|
+
changes: "Unione dei record dinamici nelle varianti — `variant` ora accetta una stringa o un oggetto"
|
|
21
23
|
author: aymericzip
|
|
22
24
|
---
|
|
23
25
|
|
|
24
|
-
# Dizionari
|
|
26
|
+
# Dizionari dinamici
|
|
25
27
|
|
|
26
|
-
Intlayer supporta
|
|
28
|
+
Intlayer supporta due meccanismi per esprimere contenuti che vanno oltre un singolo dizionario statico per chiave. Ciascuno è dichiarato tramite un **campo di metadati di primo livello** nel file di contenuto; non è necessaria alcuna funzione wrapper.
|
|
27
29
|
|
|
28
|
-
| Funzionalità
|
|
29
|
-
|
|
|
30
|
-
| [Collezioni](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/dynamic_dictionaries/collections.md)
|
|
31
|
-
| [Varianti](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/dynamic_dictionaries/variants.md)
|
|
32
|
-
| [Record Dinamici](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
|
|
30
|
+
| Funzionalità | Campo di metadati | Selettore in `useIntlayer` |
|
|
31
|
+
| --------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
|
|
32
|
+
| [Collezioni](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
|
|
33
|
+
| [Varianti](https://github.com/aymericzip/intlayer/blob/main/docs/docs/it/dynamic_dictionaries/variants.md) | `variant: "name"` _o_ `variant: { … }` | `{ variant: "name" }` _o_ `{ variant: { … } }` |
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
Entrambi si combinano con l'argomento locale e supportano il caricamento selettivo / differito tramite `importMode`.
|
|
35
36
|
|
|
36
|
-
## Quando usare
|
|
37
|
+
## Quando usare cosa
|
|
37
38
|
|
|
38
|
-
- **Collezioni** — elenco ordinato di elementi gestiti in file separati (
|
|
39
|
-
- **
|
|
40
|
-
-
|
|
39
|
+
- **Collezioni** — elenco ordinato di elementi gestiti in file separati (voci di FAQ, articoli di blog, prodotti).
|
|
40
|
+
- **Varianti** — alternative di contenuto con nome o strutturate:
|
|
41
|
+
- una variante **stringa** per test A/B, banner stagionali o feature flag;
|
|
42
|
+
- una variante **oggetto** per record di CMS, contenuti specifici per utente o qualsiasi contenuto indirizzato da un insieme di campi (i precedenti «record dinamici»).
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
> Le versioni precedenti esponevano un campo `meta` separato per i contenuti indicizzati per record. È stato unito in `variant`: passa un **oggetto** a `variant` invece di usare `meta`.
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
## Disambiguazione del selettore
|
|
47
|
+
|
|
48
|
+
Una chiave può dichiarare entrambe le dimensioni contemporaneamente (ad es. una collezione i cui elementi hanno ciascuno una variante). Vengono risolte nell'ordine:
|
|
45
49
|
|
|
46
50
|
```
|
|
47
|
-
variant →
|
|
51
|
+
variant → item
|
|
48
52
|
```
|
|
53
|
+
|
|
54
|
+
Quindi `{ variant: "promo" }` su una chiave variante × item restituisce tutti gli elementi promo come array, e aggiungere `{ item: 2 }` lo restringe a una singola voce.
|