@intlayer/docs 9.1.1 → 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 +214 -1
- package/docs/de/dynamic_dictionaries/variants.md +174 -1
- package/docs/en/dynamic_dictionaries/variants.md +174 -1
- package/docs/en-GB/dynamic_dictionaries/variants.md +174 -1
- package/docs/es/dynamic_dictionaries/variants.md +174 -1
- package/docs/fr/dynamic_dictionaries/variants.md +174 -1
- package/docs/hi/dynamic_dictionaries/variants.md +174 -1
- package/docs/id/dynamic_dictionaries/variants.md +174 -1
- package/docs/it/dynamic_dictionaries/variants.md +174 -1
- package/docs/ja/dynamic_dictionaries/variants.md +174 -1
- package/docs/ko/dynamic_dictionaries/variants.md +174 -1
- package/docs/pl/dynamic_dictionaries/variants.md +174 -1
- package/docs/pt/dynamic_dictionaries/variants.md +174 -1
- package/docs/ru/dynamic_dictionaries/variants.md +174 -1
- package/docs/tr/dynamic_dictionaries/variants.md +174 -1
- package/docs/uk/dynamic_dictionaries/variants.md +174 -1
- package/docs/vi/dynamic_dictionaries/variants.md +174 -1
- package/docs/zh/dynamic_dictionaries/variants.md +174 -1
- 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: Variantes
|
|
5
5
|
description: Use o campo de metadados variant nos arquivos de conteúdo do Intlayer para declarar alternativas de conteúdo nomeadas ou estruturadas — testes A/B, banners sazonais, texto com feature flag, registros de CMS, conteúdo específico do usuário — e alternar entre elas em tempo de execução sem mudanças de código.
|
|
6
6
|
keywords:
|
|
@@ -26,6 +26,9 @@ history:
|
|
|
26
26
|
- version: 9.1.1
|
|
27
27
|
date: 2026-07-31
|
|
28
28
|
changes: "Uma variante declara apenas as chaves que sobrescreve; as variantes não declaradas retornam para a entrada padrão"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Os provedores aceitam uma prop `variant` ambiente; os seletores aceitam uma cadeia de preferência ordenada"
|
|
29
32
|
author: aymericzip
|
|
30
33
|
---
|
|
31
34
|
|
|
@@ -498,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
498
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
499
502
|
```
|
|
500
503
|
|
|
504
|
+
## Variante ambiente
|
|
505
|
+
|
|
506
|
+
Algumas dimensões de variante são fixas durante toda uma sessão: o inquilino, o tipo de instituição, o nível do plano. São resolvidas uma única vez, e nenhum componente deveria ter de as passar à mão.
|
|
507
|
+
|
|
508
|
+
> Não envolva `useIntlayer` num hook próprio para as injetar. A otimização em tempo de compilação apenas reescreve uma chamada literal `useIntlayer("key")` importada do pacote do framework, pelo que nada atrás de um wrapper entra no bundle.
|
|
509
|
+
|
|
510
|
+
Declare antes a variante uma única vez no provedor, exatamente como `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
|
+
Cada leitura de dicionário abaixo do provedor passa a resolver-se com essa variante, e um seletor no local da chamada ganha sempre:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → a variante do provedor
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — substitui a variante do provedor, não a estende
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Formas
|
|
629
|
+
|
|
630
|
+
A prop `variant` aceita três formas:
|
|
631
|
+
|
|
632
|
+
| Forma | Significado |
|
|
633
|
+
| --------------------------------------------------------- | ----------------------------------------- |
|
|
634
|
+
| `variant="school1"` | uma variante nomeada para todas as chaves |
|
|
635
|
+
| `variant={["school1", "default"]}` | uma cadeia de preferência ordenada |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | uma variante por chave de dicionário |
|
|
637
|
+
|
|
638
|
+
#### Cadeia de preferência
|
|
639
|
+
|
|
640
|
+
Uma cadeia é percorrida da esquerda para a direita entre as entradas declaradas por cada chave, e a primeira declarada ganha. Quando nenhuma está declarada, usa-se a entrada padrão implícita — exatamente como para um valor único.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` não declara uma entrada `school1`, mas declara `school2` → "school2"
|
|
645
|
+
// uma chave que não declara nenhuma das duas → a entrada padrão
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Assim, `["black_friday", "summer"]` lê-se como «black friday se esta chave tiver uma, senão summer, senão padrão». As cadeias também são aceites no local da chamada:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Note que esta é a imagem invertida do array aceite pelo **campo** `variant` de um ficheiro de conteúdo: aí um array _declara_ uma entrada por elemento; aqui _consome_-as por ordem de prioridade.
|
|
655
|
+
|
|
656
|
+
#### Mapa por chave
|
|
657
|
+
|
|
658
|
+
Enderece cada chave de dicionário separadamente. A entrada reservada `default` cobre todas as chaves não listadas:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> Num provedor, um objeto simples é **sempre** lido como o mapa por chave, nunca como uma variante de objeto — as duas são estruturalmente idênticas. Para fixar uma variante de objeto globalmente, aninhe-a sob uma entrada: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Como as chaves do mapa são verificadas contra as suas chaves de dicionário declaradas, um erro de escrita — ou uma variante de objeto escrita diretamente, como `variant={{ id: "prod_abc" }}` — é um erro de compilação.
|
|
673
|
+
|
|
501
674
|
## Modo de carregamento
|
|
502
675
|
|
|
503
676
|
As variantes de objeto costumam ser carregadas de forma preguiçosa. Defina `importMode` no dicionário para controlar isso:
|
|
@@ -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: Используйте поле метаданных variant в файлах контента Intlayer, чтобы объявлять именованные или структурированные альтернативы контента — A/B-тесты, сезонные баннеры, тексты под feature-флагами, записи CMS, контент конкретного пользователя — и переключаться между ними во время выполнения без изменений кода.
|
|
6
6
|
keywords:
|
|
@@ -26,6 +26,9 @@ history:
|
|
|
26
26
|
- version: 9.1.1
|
|
27
27
|
date: 2026-07-31
|
|
28
28
|
changes: "Вариант объявляет только ключи, которые он переопределяет; необъявленные варианты возвращаются к записи по умолчанию"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Провайдеры принимают внешний проп `variant`; селекторы принимают упорядоченную цепочку предпочтений"
|
|
29
32
|
author: aymericzip
|
|
30
33
|
---
|
|
31
34
|
|
|
@@ -498,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
498
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
499
502
|
```
|
|
500
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` принимает три формы:
|
|
631
|
+
|
|
632
|
+
| Форма | Значение |
|
|
633
|
+
| --------------------------------------------------------- | ---------------------------------------- |
|
|
634
|
+
| `variant="school1"` | один именованный вариант для всех ключей |
|
|
635
|
+
| `variant={["school1", "default"]}` | упорядоченная цепочка предпочтений |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | свой вариант для каждого ключа словаря |
|
|
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` файла контента: там массив _объявляет_ по одной записи на элемент, здесь он _потребляет_ их в порядке приоритета.
|
|
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
|
+
|
|
501
674
|
## Режим загрузки
|
|
502
675
|
|
|
503
676
|
Объектные варианты часто загружаются лениво. Задайте `importMode` в словаре, чтобы управлять этим:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-08-04
|
|
4
4
|
title: Varyantlar
|
|
5
5
|
description: Adlandırılmış veya yapılandırılmış içerik alternatifleri — A/B testleri, sezonluk afişler, özellik bayraklı metin, CMS kayıtları, kullanıcıya özel içerik — bildirmek ve kod değişikliği olmadan çalışma zamanında aralarında geçiş yapmak için Intlayer içerik dosyalarında variant meta veri alanını kullanın.
|
|
6
6
|
keywords:
|
|
@@ -26,6 +26,9 @@ history:
|
|
|
26
26
|
- version: 9.1.1
|
|
27
27
|
date: 2026-07-31
|
|
28
28
|
changes: "Bir varyant yalnızca geçersiz kıldığı anahtarları bildirir; bildirilmemiş varyantlar varsayılan girdiye geri döner"
|
|
29
|
+
- version: 9.1.2
|
|
30
|
+
date: 2026-08-04
|
|
31
|
+
changes: "Sağlayıcılar ortam düzeyinde bir `variant` prop'u kabul eder; seçiciler sıralı bir tercih zinciri kabul eder"
|
|
29
32
|
author: aymericzip
|
|
30
33
|
---
|
|
31
34
|
|
|
@@ -498,6 +501,176 @@ const content = useIntlayer("product", {
|
|
|
498
501
|
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
499
502
|
```
|
|
500
503
|
|
|
504
|
+
## Ortam varyantı
|
|
505
|
+
|
|
506
|
+
Bazı varyant boyutları tüm oturum boyunca sabittir — kiracı, okul türü, plan seviyesi. Bir kez çözümlenirler ve hiçbir bileşenin bunları elle geçirmesi gerekmemelidir.
|
|
507
|
+
|
|
508
|
+
> Bunları enjekte etmek için `useIntlayer`'ı kendi hook'unuza sarmayın. Derleme zamanı optimizasyonu yalnızca framework paketinden içe aktarılan düz bir `useIntlayer("key")` çağrısını yeniden yazar; bir sarmalayıcının arkasındaki hiçbir şey paketlenmez.
|
|
509
|
+
|
|
510
|
+
Bunun yerine varyantı sağlayıcıda bir kez bildirin, tıpkı `locale` gibi:
|
|
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
|
+
Sağlayıcının altındaki her sözlük okuması artık bu varyanta göre çözümlenir ve çağrı noktasındaki bir seçici her zaman kazanır:
|
|
619
|
+
|
|
620
|
+
```tsx
|
|
621
|
+
useIntlayer("hero-banner");
|
|
622
|
+
// → sağlayıcının varyantı
|
|
623
|
+
|
|
624
|
+
useIntlayer("hero-banner", { variant: "summer" });
|
|
625
|
+
// → "summer" — sağlayıcı varyantının yerini alır, onu genişletmez
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### Biçimler
|
|
629
|
+
|
|
630
|
+
`variant` prop'u üç biçim kabul eder:
|
|
631
|
+
|
|
632
|
+
| Biçim | Anlamı |
|
|
633
|
+
| --------------------------------------------------------- | ---------------------------------------------- |
|
|
634
|
+
| `variant="school1"` | her anahtar için tek bir adlandırılmış varyant |
|
|
635
|
+
| `variant={["school1", "default"]}` | sıralı bir tercih zinciri |
|
|
636
|
+
| `variant={{ "hero-banner": "school1", default: "base" }}` | sözlük anahtarı başına bir varyant |
|
|
637
|
+
|
|
638
|
+
#### Tercih zinciri
|
|
639
|
+
|
|
640
|
+
Zincir, her anahtarın bildirdiği girdilere karşı soldan sağa denenir ve bildirilen ilk girdi kazanır. Hiçbiri bildirilmemişse örtük varsayılan girdi kullanılır — tıpkı tek bir değerde olduğu gibi.
|
|
641
|
+
|
|
642
|
+
```tsx
|
|
643
|
+
<IntlayerProvider variant={["school1", "school2"]} />
|
|
644
|
+
// `hero-banner` bir `school1` girdisi bildirmez ama `school2` bildirir → "school2"
|
|
645
|
+
// ikisini de bildirmeyen bir anahtar → varsayılan girdi
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Yani `["black_friday", "summer"]` şöyle okunur: «bu anahtarda varsa black friday, yoksa summer, o da yoksa varsayılan». Zincirler çağrı noktasında da kabul edilir:
|
|
649
|
+
|
|
650
|
+
```tsx
|
|
651
|
+
useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
> Bunun, bir içerik dosyasının `variant` **alanının** kabul ettiği dizinin ayna görüntüsü olduğuna dikkat edin: orada bir dizi öğe başına bir girdi _bildirir_, burada ise onları öncelik sırasına göre _tüketir_.
|
|
655
|
+
|
|
656
|
+
#### Anahtar başına eşleme
|
|
657
|
+
|
|
658
|
+
Her sözlük anahtarını ayrı ayrı adresleyin. Ayrılmış `default` girdisi, listelenmeyen tüm anahtarları kapsar:
|
|
659
|
+
|
|
660
|
+
```tsx
|
|
661
|
+
<IntlayerProvider
|
|
662
|
+
variant={{
|
|
663
|
+
"hero-banner": "school1",
|
|
664
|
+
product: ["school1", "default"],
|
|
665
|
+
default: "base",
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
> Bir sağlayıcıda düz bir nesne **her zaman** anahtar başına eşleme olarak okunur, asla nesne varyantı olarak değil — ikisi yapısal olarak aynıdır. Bir nesne varyantını global olarak sabitlemek için onu bir girdinin altına yerleştirin: `variant={{ default: { id: "prod_abc" } }}`.
|
|
671
|
+
|
|
672
|
+
Eşlemenin anahtarları bildirdiğiniz sözlük anahtarlarına karşı denetlendiğinden, bir yazım hatası — ya da doğrudan yazılmış bir nesne varyantı, örneğin `variant={{ id: "prod_abc" }}` — derleme zamanı hatasıdır.
|
|
673
|
+
|
|
501
674
|
## Yükleme modu
|
|
502
675
|
|
|
503
676
|
Nesne varyantları genellikle tembel olarak yüklenir. Bunu kontrol etmek için sözlükte `importMode`'u ayarlayın:
|