@intlayer/docs 9.1.0 → 9.1.2
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/docs/ar/dynamic_dictionaries/variants.md +248 -5
- package/docs/de/dynamic_dictionaries/variants.md +208 -1
- package/docs/en/dynamic_dictionaries/variants.md +208 -1
- package/docs/en-GB/dynamic_dictionaries/variants.md +208 -1
- package/docs/es/dynamic_dictionaries/variants.md +208 -1
- package/docs/fr/dynamic_dictionaries/variants.md +208 -1
- package/docs/hi/dynamic_dictionaries/variants.md +210 -3
- package/docs/id/dynamic_dictionaries/variants.md +208 -1
- package/docs/it/dynamic_dictionaries/variants.md +209 -2
- package/docs/ja/dynamic_dictionaries/variants.md +209 -2
- package/docs/ko/dynamic_dictionaries/variants.md +209 -2
- package/docs/pl/dynamic_dictionaries/variants.md +209 -2
- package/docs/pt/dynamic_dictionaries/variants.md +208 -1
- package/docs/ru/dynamic_dictionaries/variants.md +209 -2
- package/docs/tr/dynamic_dictionaries/variants.md +209 -2
- package/docs/uk/dynamic_dictionaries/variants.md +208 -1
- package/docs/vi/dynamic_dictionaries/variants.md +210 -3
- package/docs/zh/dynamic_dictionaries/variants.md +209 -2
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: Varianti
|
|
5
5
|
description: Usa il campo di metadati variant nei file di contenuto Intlayer per dichiarare alternative di contenuto con nome o strutturate — test A/B, banner stagionali, testo con feature flag, record di CMS, contenuti specifici per utente — e passare dall'una all'altra a runtime senza modifiche al codice.
|
|
6
6
|
keywords:
|
|
@@ -22,7 +22,13 @@ history:
|
|
|
22
22
|
changes: "Rilascio della funzionalità delle varianti"
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
|
-
changes: "`variant` ora accetta una stringa o un oggetto — i precedenti `meta` / record dinamici
|
|
25
|
+
changes: "`variant` ora accetta una stringa o un oggetto — i precedenti `meta` / record dinamici vengono dichiarati come varianti oggetto"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "Una variante dichiara solo le chiavi che sovrascrive; le varianti non dichiarate ricadono sulla voce predefinita"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "I provider accettano una prop `variant` ambientale; i selettori accettano una catena di preferenza ordinata"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### Varianti parziali
|
|
87
|
+
|
|
88
|
+
Una variante dichiara **solo le chiavi che sovrascrive**; il resto viene ereditato dalla voce predefinita.
|
|
89
|
+
|
|
90
|
+
```ts fileName="hero-banner.summer.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
91
|
+
import { t, type Dictionary } from "intlayer";
|
|
92
|
+
|
|
93
|
+
const dictionary = {
|
|
94
|
+
key: "hero-banner",
|
|
95
|
+
variant: "summer",
|
|
96
|
+
content: {
|
|
97
|
+
headline: t({
|
|
98
|
+
en: "Build faster all summer",
|
|
99
|
+
fr: "Développez plus vite tout l'été",
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
} satisfies Dictionary;
|
|
103
|
+
|
|
104
|
+
export default dictionary;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
109
|
+
// → { headline: "Développez plus vite tout l'été", cta: "Commencer" } — `cta` ereditato
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → la voce predefinita
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Quindi aggiungi un file variante solo dove la formulazione differisce effettivamente. Una chiave si risolve in `null` solo quando dichiara varianti ma nessuna voce predefinita.
|
|
116
|
+
|
|
80
117
|
### Consumare varianti con nome
|
|
81
118
|
|
|
82
119
|
#### Variante predefinita
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## Variante ambientale
|
|
505
|
+
|
|
506
|
+
Alcune dimensioni di variante sono fisse per un'intera sessione: il tenant, il tipo di istituto, il livello di piano. Vengono risolte una sola volta e nessun componente dovrebbe doverle passare a mano.
|
|
507
|
+
|
|
508
|
+
> Non incapsulare `useIntlayer` in un hook personalizzato per iniettarle. L'ottimizzazione in fase di build riscrive solo una chiamata letterale `useIntlayer("key")` importata dal pacchetto del framework, quindi nulla dietro un wrapper finisce nel bundle.
|
|
509
|
+
|
|
510
|
+
Dichiara invece la variante una sola volta sul provider, esattamente come `locale`:
|
|
511
|
+
|
|
512
|
+
<Tabs group="framework">
|
|
513
|
+
<Tab label="React" value="react">
|
|
514
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
515
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
516
|
+
|
|
517
|
+
export const App = ({ locale, schoolType }) => (
|
|
518
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
519
|
+
<Hero />
|
|
520
|
+
</IntlayerProvider>
|
|
521
|
+
);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
</Tab>
|
|
525
|
+
<Tab label="Next.js" value="nextjs">
|
|
526
|
+
```tsx fileName="layout.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
527
|
+
import { IntlayerServerProvider } from "next-intlayer/server";
|
|
528
|
+
import { IntlayerClientProvider } from "next-intlayer";
|
|
529
|
+
|
|
530
|
+
export default async function Layout({ children, params }) {
|
|
531
|
+
const { locale } = await params;
|
|
532
|
+
const schoolType = await getSchoolType();
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
<IntlayerServerProvider locale={locale} variant={schoolType}>
|
|
536
|
+
<IntlayerClientProvider locale={locale} variant={schoolType}>
|
|
537
|
+
{children}
|
|
538
|
+
</IntlayerClientProvider>
|
|
539
|
+
</IntlayerServerProvider>
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
</Tab>
|
|
545
|
+
<Tab label="Vue" value="vue">
|
|
546
|
+
```ts fileName="main.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
547
|
+
import { createApp } from "vue";
|
|
548
|
+
import { installIntlayer } from "vue-intlayer";
|
|
549
|
+
import App from "./App.vue";
|
|
550
|
+
|
|
551
|
+
const app = createApp(App);
|
|
552
|
+
|
|
553
|
+
installIntlayer(app, { locale: "en", variant: schoolType });
|
|
554
|
+
|
|
555
|
+
app.mount("#app");
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
</Tab>
|
|
559
|
+
<Tab label="Svelte" value="svelte">
|
|
560
|
+
```svelte fileName="+layout.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
561
|
+
<script lang="ts">
|
|
562
|
+
import { setupIntlayer } from "svelte-intlayer";
|
|
563
|
+
|
|
564
|
+
export let schoolType: string;
|
|
565
|
+
|
|
566
|
+
setupIntlayer("en", schoolType);
|
|
567
|
+
</script>
|
|
568
|
+
|
|
569
|
+
<slot />
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
</Tab>
|
|
573
|
+
<Tab label="Preact" value="preact">
|
|
574
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
575
|
+
import { IntlayerProvider } from "preact-intlayer";
|
|
576
|
+
|
|
577
|
+
export const App = ({ locale, schoolType }) => (
|
|
578
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
579
|
+
<Hero />
|
|
580
|
+
</IntlayerProvider>
|
|
581
|
+
);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
</Tab>
|
|
585
|
+
<Tab label="Solid" value="solid">
|
|
586
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
587
|
+
import { IntlayerProvider } from "solid-intlayer";
|
|
588
|
+
|
|
589
|
+
export const App = (props) => (
|
|
590
|
+
<IntlayerProvider locale={props.locale} variant={props.schoolType}>
|
|
591
|
+
<Hero />
|
|
592
|
+
</IntlayerProvider>
|
|
593
|
+
);
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
</Tab>
|
|
597
|
+
<Tab label="Angular" value="angular">
|
|
598
|
+
```typescript fileName="app.config.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
599
|
+
import { ApplicationConfig } from "@angular/core";
|
|
600
|
+
import { provideIntlayer } from "angular-intlayer";
|
|
601
|
+
|
|
602
|
+
export const appConfig: ApplicationConfig = {
|
|
603
|
+
providers: [provideIntlayer("en", true, schoolType)],
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
</Tab>
|
|
608
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
609
|
+
```javascript fileName="main.js"
|
|
610
|
+
import { installIntlayer } from "vanilla-intlayer";
|
|
611
|
+
|
|
612
|
+
installIntlayer({ locale: "en", variant: schoolType });
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
</Tab>
|
|
616
|
+
</Tabs>
|
|
617
|
+
|
|
618
|
+
Ogni lettura di dizionario sotto il provider si risolve ora con quella variante, e un selettore nel punto di chiamata vince sempre:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → la variante del provider
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — sostituisce la variante del provider, non la estende
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Forme
|
|
629
|
+
|
|
630
|
+
La prop `variant` accetta tre forme:
|
|
631
|
+
|
|
632
|
+
| Forma | Significato |
|
|
633
|
+
| --------------------------------------------------------- | --------------------------------------- |
|
|
634
|
+
| `variant="school1"` | una variante denominata per ogni chiave |
|
|
635
|
+
| `variant={["school1", "default"]}` | una catena di preferenza ordinata |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | una variante per chiave di dizionario |
|
|
637
|
+
|
|
638
|
+
#### Catena di preferenza
|
|
639
|
+
|
|
640
|
+
Una catena viene percorsa da sinistra a destra tra le voci dichiarate da ciascuna chiave e vince la prima dichiarata. Quando nessuna è dichiarata, si usa la voce predefinita implicita, esattamente come per un valore singolo.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` non dichiara una voce `school1` ma dichiara `school2` → "school2"
|
|
645
|
+
// una chiave che non dichiara nessuna delle due → la voce predefinita
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Quindi `["black_friday", "summer"]` si legge come «black friday se questa chiave ne ha una, altrimenti summer, altrimenti predefinita». Le catene sono accettate anche nel punto di chiamata:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Nota che questa è l'immagine speculare dell'array accettato dal **campo** `variant` di un file di contenuto: lì un array _dichiara_ una voce per elemento, qui le _consuma_ in ordine di priorità.
|
|
655
|
+
|
|
656
|
+
#### Mappa per chiave
|
|
657
|
+
|
|
658
|
+
Indirizza ogni chiave di dizionario separatamente. La voce riservata `default` copre tutte le chiavi non elencate:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> Su un provider un oggetto semplice è **sempre** letto come mappa per chiave, mai come variante oggetto: le due sono strutturalmente identiche. Per fissare una variante oggetto a livello globale, annidala sotto una voce: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Poiché le chiavi della mappa sono verificate rispetto alle chiavi di dizionario dichiarate, un refuso — o una variante oggetto scritta direttamente, come `variant={{ id: "prod_abc" }}` — è un errore di compilazione.
|
|
673
|
+
|
|
467
674
|
## Modalità di caricamento
|
|
468
675
|
|
|
469
676
|
Le varianti oggetto sono spesso caricate in modo differito. Imposta `importMode` sul dizionario per controllarlo:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: バリアント
|
|
5
5
|
description: Intlayer のコンテンツファイルで variant メタデータフィールドを使用し、名前付きまたは構造化されたコンテンツの代替(A/B テスト、季節バナー、フィーチャーフラグ付きコピー、CMS レコード、ユーザー固有コンテンツ)を宣言し、コード変更なしにランタイムで切り替えます。
|
|
6
6
|
keywords:
|
|
@@ -22,7 +22,13 @@ history:
|
|
|
22
22
|
changes: "バリアント機能のリリース"
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
|
-
changes: "`variant
|
|
25
|
+
changes: "`variant`は文字列またはオブジェクトを受け付けるようになりました — 以前の `meta` / 動的レコードはオブジェクトバリアントとして宣言されます"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "バリアントは上書きするキーのみを宣言します。宣言されていないバリアントはデフォルトのエントリにフォールバックします"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "プロバイダーがアンビエントな `variant` プロパティを受け取り、セレクターが順序付きの優先チェーンを受け取れるようになりました"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### 部分的なバリアント
|
|
87
|
+
|
|
88
|
+
バリアントは**上書きするキーのみを宣言します**。残りはデフォルトのエントリから継承されます。
|
|
89
|
+
|
|
90
|
+
```ts fileName="hero-banner.summer.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
91
|
+
import { t, type Dictionary } from "intlayer";
|
|
92
|
+
|
|
93
|
+
const dictionary = {
|
|
94
|
+
key: "hero-banner",
|
|
95
|
+
variant: "summer",
|
|
96
|
+
content: {
|
|
97
|
+
headline: t({
|
|
98
|
+
en: "Build faster all summer",
|
|
99
|
+
fr: "Développez plus vite tout l'été",
|
|
100
|
+
}),
|
|
101
|
+
},
|
|
102
|
+
} satisfies Dictionary;
|
|
103
|
+
|
|
104
|
+
export default dictionary;
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
109
|
+
// → { headline: "Développez plus vite tout l'été", cta: "Commencer" } — `cta` は継承されます
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → デフォルトのエントリ
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
したがって、実際にテキストが異なる場所にのみバリアントファイルを追加します。バリアントを宣言しているがデフォルトのエントリがない場合にのみ、キーは `null` に解決されます。
|
|
116
|
+
|
|
80
117
|
### 名前付きバリアントの利用
|
|
81
118
|
|
|
82
119
|
#### デフォルトバリアント
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## アンビエントバリアント
|
|
505
|
+
|
|
506
|
+
バリアントの次元の中には、テナント、学校種別、プラン階層のように、セッション全体で固定されるものがあります。これらは一度だけ解決されるものであり、各コンポーネントが手で渡すべきものではありません。
|
|
507
|
+
|
|
508
|
+
> これらを注入するために `useIntlayer` を独自のフックでラップしないでください。ビルド時の最適化は、フレームワークパッケージからインポートされたリテラルな `useIntlayer("key")` の呼び出しだけを書き換えるため、ラッパーの背後にあるものはバンドルされません。
|
|
509
|
+
|
|
510
|
+
代わりに、`locale` とまったく同じように、プロバイダーで一度だけバリアントを宣言します:
|
|
511
|
+
|
|
512
|
+
<Tabs group="framework">
|
|
513
|
+
<Tab label="React" value="react">
|
|
514
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
515
|
+
import { IntlayerProvider } from "react-intlayer";
|
|
516
|
+
|
|
517
|
+
export const App = ({ locale, schoolType }) => (
|
|
518
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
519
|
+
<Hero />
|
|
520
|
+
</IntlayerProvider>
|
|
521
|
+
);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
</Tab>
|
|
525
|
+
<Tab label="Next.js" value="nextjs">
|
|
526
|
+
```tsx fileName="layout.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
527
|
+
import { IntlayerServerProvider } from "next-intlayer/server";
|
|
528
|
+
import { IntlayerClientProvider } from "next-intlayer";
|
|
529
|
+
|
|
530
|
+
export default async function Layout({ children, params }) {
|
|
531
|
+
const { locale } = await params;
|
|
532
|
+
const schoolType = await getSchoolType();
|
|
533
|
+
|
|
534
|
+
return (
|
|
535
|
+
<IntlayerServerProvider locale={locale} variant={schoolType}>
|
|
536
|
+
<IntlayerClientProvider locale={locale} variant={schoolType}>
|
|
537
|
+
{children}
|
|
538
|
+
</IntlayerClientProvider>
|
|
539
|
+
</IntlayerServerProvider>
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
</Tab>
|
|
545
|
+
<Tab label="Vue" value="vue">
|
|
546
|
+
```ts fileName="main.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
547
|
+
import { createApp } from "vue";
|
|
548
|
+
import { installIntlayer } from "vue-intlayer";
|
|
549
|
+
import App from "./App.vue";
|
|
550
|
+
|
|
551
|
+
const app = createApp(App);
|
|
552
|
+
|
|
553
|
+
installIntlayer(app, { locale: "en", variant: schoolType });
|
|
554
|
+
|
|
555
|
+
app.mount("#app");
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
</Tab>
|
|
559
|
+
<Tab label="Svelte" value="svelte">
|
|
560
|
+
```svelte fileName="+layout.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
561
|
+
<script lang="ts">
|
|
562
|
+
import { setupIntlayer } from "svelte-intlayer";
|
|
563
|
+
|
|
564
|
+
export let schoolType: string;
|
|
565
|
+
|
|
566
|
+
setupIntlayer("en", schoolType);
|
|
567
|
+
</script>
|
|
568
|
+
|
|
569
|
+
<slot />
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
</Tab>
|
|
573
|
+
<Tab label="Preact" value="preact">
|
|
574
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
575
|
+
import { IntlayerProvider } from "preact-intlayer";
|
|
576
|
+
|
|
577
|
+
export const App = ({ locale, schoolType }) => (
|
|
578
|
+
<IntlayerProvider locale={locale} variant={schoolType}>
|
|
579
|
+
<Hero />
|
|
580
|
+
</IntlayerProvider>
|
|
581
|
+
);
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
</Tab>
|
|
585
|
+
<Tab label="Solid" value="solid">
|
|
586
|
+
```tsx fileName="App.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
587
|
+
import { IntlayerProvider } from "solid-intlayer";
|
|
588
|
+
|
|
589
|
+
export const App = (props) => (
|
|
590
|
+
<IntlayerProvider locale={props.locale} variant={props.schoolType}>
|
|
591
|
+
<Hero />
|
|
592
|
+
</IntlayerProvider>
|
|
593
|
+
);
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
</Tab>
|
|
597
|
+
<Tab label="Angular" value="angular">
|
|
598
|
+
```typescript fileName="app.config.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
599
|
+
import { ApplicationConfig } from "@angular/core";
|
|
600
|
+
import { provideIntlayer } from "angular-intlayer";
|
|
601
|
+
|
|
602
|
+
export const appConfig: ApplicationConfig = {
|
|
603
|
+
providers: [provideIntlayer("en", true, schoolType)],
|
|
604
|
+
};
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
</Tab>
|
|
608
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
609
|
+
```javascript fileName="main.js"
|
|
610
|
+
import { installIntlayer } from "vanilla-intlayer";
|
|
611
|
+
|
|
612
|
+
installIntlayer({ locale: "en", variant: schoolType });
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
</Tab>
|
|
616
|
+
</Tabs>
|
|
617
|
+
|
|
618
|
+
これでプロバイダー配下のすべての辞書の読み取りがそのバリアントで解決され、呼び出し側のセレクターが常に優先されます:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → プロバイダーのバリアント
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — プロバイダーのバリアントを置き換えます(拡張はしません)
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### 形式
|
|
629
|
+
|
|
630
|
+
`variant` プロパティは 3 つの形式を受け取ります:
|
|
631
|
+
|
|
632
|
+
| 形式 | 意味 |
|
|
633
|
+
| --------------------------------------------------------- | --------------------------------------------- |
|
|
634
|
+
| `variant="school1"` | すべてのキーに対する 1 つの名前付きバリアント |
|
|
635
|
+
| `variant={["school1", "default"]}` | 順序付きの優先チェーン |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | 辞書キーごとに 1 つのバリアント |
|
|
637
|
+
|
|
638
|
+
#### 優先チェーン
|
|
639
|
+
|
|
640
|
+
チェーンは各キーが宣言しているエントリーに対して左から右へ順に試され、最初に宣言されているものが採用されます。どれも宣言されていない場合は、単一の値のときとまったく同じく、暗黙のデフォルトエントリーが使われます。
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` は `school1` エントリーを宣言していないが `school2` を宣言している → "school2"
|
|
645
|
+
// どちらも宣言していないキー → デフォルトエントリー
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
したがって `["black_friday", "summer"]` は「このキーに black friday があればそれ、なければ summer、それもなければデフォルト」と読めます。チェーンは呼び出し側でも使えます:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> これはコンテンツファイルの `variant` **フィールド**が受け取る配列とちょうど逆であることに注意してください。あちらでは配列が要素ごとに 1 つのエントリーを*宣言*しますが、こちらでは優先順位に従ってそれらを*消費*します。
|
|
655
|
+
|
|
656
|
+
#### キーごとのマップ
|
|
657
|
+
|
|
658
|
+
辞書キーごとに個別に指定します。予約された `default` エントリーが、記載されていないすべてのキーをカバーします:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> プロバイダーでは、プレーンなオブジェクトは**常に**キーごとのマップとして読み取られ、オブジェクトバリアントとしては解釈されません(両者は構造的に同一のためです)。オブジェクトバリアントをグローバルに指定するには、エントリーの下にネストしてください: `variant={{ default: { id: "prod_abc" } }}`。
|
|
671
|
+
|
|
672
|
+
マップのキーは宣言済みの辞書キーと照合されるため、タイプミス(あるいは `variant={{ id: "prod_abc" }}` のようにオブジェクトバリアントを直接書いた場合)はコンパイルエラーになります。
|
|
673
|
+
|
|
467
674
|
## 読み込みモード
|
|
468
675
|
|
|
469
676
|
オブジェクトバリアントはしばしば遅延読み込みされます。これを制御するには辞書に `importMode` を設定します:
|