@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: Variants
|
|
5
5
|
description: Use the variant metadata field in Intlayer content files to declare named or structured content alternatives — A/B tests, seasonal banners, feature-flagged copy, CMS records, user-specific content — and switch between them at runtime without code changes.
|
|
6
6
|
keywords:
|
|
@@ -23,6 +23,12 @@ history:
|
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
25
|
changes: "`variant` now accepts a string or an object — the former `meta` / dynamic records are declared as object variants"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "A variant declares only the keys it overrides; undeclared variants fall back to the default entry"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Providers accept an ambient `variant` prop; selectors accept an ordered preference chain"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### Partial variants
|
|
87
|
+
|
|
88
|
+
A variant declares **only the keys it overrides**; the rest are inherited from the default entry.
|
|
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: "Build faster all summer", cta: "Get started" } — `cta` inherited
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → the default entry
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
So you only add a variant file where the wording actually differs. A key resolves to `null` only when it declares variants but no default entry.
|
|
116
|
+
|
|
80
117
|
### Consuming named variants
|
|
81
118
|
|
|
82
119
|
#### Default variant
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## Ambient variant
|
|
505
|
+
|
|
506
|
+
Some variant dimensions are fixed for a whole session — the tenant, the school type, the plan tier. They are resolved once, and no component should have to pass them by hand.
|
|
507
|
+
|
|
508
|
+
> Do not wrap `useIntlayer` in your own hook to inject them. The build-time optimization only rewrites a literal `useIntlayer("key")` imported from the framework package, so nothing behind a wrapper gets bundled.
|
|
509
|
+
|
|
510
|
+
Declare the variant once on the provider instead, exactly like `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
|
+
Every dictionary read below the provider now resolves against that variant, and a call-site selector always wins:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → the provider variant
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — replaces the provider variant, it is not extended
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Forms
|
|
629
|
+
|
|
630
|
+
The `variant` prop accepts three forms:
|
|
631
|
+
|
|
632
|
+
| Form | Meaning |
|
|
633
|
+
| --------------------------------------------------------- | ------------------------------- |
|
|
634
|
+
| `variant="school1"` | one named variant for every key |
|
|
635
|
+
| `variant={["school1", "default"]}` | an ordered preference chain |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | one variant per dictionary key |
|
|
637
|
+
|
|
638
|
+
#### Preference chain
|
|
639
|
+
|
|
640
|
+
A chain is tried left to right against the entries each key declares, and the first declared one wins. When none is declared, the implicit default entry is used — exactly as for a single value.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` declares no `school1` entry but declares `school2` → "school2"
|
|
645
|
+
// a key declaring neither → the default entry
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
So `["black_friday", "summer"]` reads as "black friday if this key has one, else summer, else default". Chains are also accepted at the call site:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Note this is the mirror image of the array accepted by the `variant` **field** of a content file: there an array _declares_ one entry per element, here it _consumes_ them in priority order.
|
|
655
|
+
|
|
656
|
+
#### Per-key map
|
|
657
|
+
|
|
658
|
+
Address each dictionary key separately. The reserved `default` entry covers every key not listed:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> On a provider a plain object is **always** read as the per-key map, never as an object variant — the two are structurally identical. To pin an object variant globally, nest it under an entry: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Because the map's keys are checked against your declared dictionary keys, a typo — or an object variant written directly, such as `variant={{ id: "prod_abc" }}` — is a compile-time error.
|
|
673
|
+
|
|
467
674
|
## Loading mode
|
|
468
675
|
|
|
469
676
|
Object variants are often loaded lazily. Set `importMode` on the dictionary to control this:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: Variants
|
|
5
5
|
description: Use the variant metadata field in Intlayer content files to declare named or structured content alternatives — A/B tests, seasonal banners, feature-flagged copy, CMS records, user-specific content — and switch between them at runtime without code changes.
|
|
6
6
|
keywords:
|
|
@@ -23,6 +23,12 @@ history:
|
|
|
23
23
|
- version: 9.1.0
|
|
24
24
|
date: 2026-06-26
|
|
25
25
|
changes: "`variant` now accepts a string or an object — the former `meta` / dynamic records are declared as object variants"
|
|
26
|
+
- version: 9.1.1
|
|
27
|
+
date: 2026-07-31
|
|
28
|
+
changes: "A variant declares only the keys it overrides; undeclared variants fall back to the default entry"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Providers accept an ambient `variant` prop; selectors accept an ordered preference chain"
|
|
26
32
|
author: aymericzip
|
|
27
33
|
---
|
|
28
34
|
|
|
@@ -77,6 +83,37 @@ const dictionary = {
|
|
|
77
83
|
export default dictionary;
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### Partial variants
|
|
87
|
+
|
|
88
|
+
A variant declares **only the keys it overrides**; the rest are inherited from the default entry.
|
|
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: "Build faster all summer", cta: "Get started" } — `cta` inherited
|
|
110
|
+
|
|
111
|
+
useIntlayer("hero-banner", { variant: "never-declared" });
|
|
112
|
+
// → the default entry
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
So you only add a variant file where the wording actually differs. A key resolves to `null` only when it declares variants but no default entry.
|
|
116
|
+
|
|
80
117
|
### Consuming named variants
|
|
81
118
|
|
|
82
119
|
#### Default variant
|
|
@@ -464,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
464
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
502
|
```
|
|
466
503
|
|
|
504
|
+
## Ambient variant
|
|
505
|
+
|
|
506
|
+
Some variant dimensions are fixed for a whole session — the tenant, the school type, the plan tier. They are resolved once, and no component should have to pass them by hand.
|
|
507
|
+
|
|
508
|
+
> Do not wrap `useIntlayer` in your own hook to inject them. The build-time optimisation only rewrites a literal `useIntlayer("key")` imported from the framework package, so nothing behind a wrapper gets bundled.
|
|
509
|
+
|
|
510
|
+
Declare the variant once on the provider instead, exactly like `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
|
+
Every dictionary read below the provider now resolves against that variant, and a call-site selector always wins:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → the provider variant
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — replaces the provider variant, it is not extended
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Forms
|
|
629
|
+
|
|
630
|
+
The `variant` prop accepts three forms:
|
|
631
|
+
|
|
632
|
+
| Form | Meaning |
|
|
633
|
+
| --------------------------------------------------------- | ------------------------------- |
|
|
634
|
+
| `variant="school1"` | one named variant for every key |
|
|
635
|
+
| `variant={["school1", "default"]}` | an ordered preference chain |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | one variant per dictionary key |
|
|
637
|
+
|
|
638
|
+
#### Preference chain
|
|
639
|
+
|
|
640
|
+
A chain is tried left to right against the entries each key declares, and the first declared one wins. When none is declared, the implicit default entry is used — exactly as for a single value.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` declares no `school1` entry but declares `school2` → "school2"
|
|
645
|
+
// a key declaring neither → the default entry
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
So `["black_friday", "summer"]` reads as "black friday if this key has one, else summer, else default". Chains are also accepted at the call site:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Note this is the mirror image of the array accepted by the `variant` **field** of a content file: there an array _declares_ one entry per element, here it _consumes_ them in priority order.
|
|
655
|
+
|
|
656
|
+
#### Per-key map
|
|
657
|
+
|
|
658
|
+
Address each dictionary key separately. The reserved `default` entry covers every key not listed:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> On a provider a plain object is **always** read as the per-key map, never as an object variant — the two are structurally identical. To pin an object variant globally, nest it under an entry: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Because the map's keys are checked against your declared dictionary keys, a typo — or an object variant written directly, such as `variant={{ id: "prod_abc" }}` — is a compile-time error.
|
|
673
|
+
|
|
467
674
|
## Loading mode
|
|
468
675
|
|
|
469
676
|
Object variants are often loaded lazily. Set `importMode` on the dictionary to control this:
|