@intlayer/docs 9.0.0-canary.7 → 9.0.0-canary.8
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: Variantes
|
|
5
|
-
description: Use o campo de metadados variant nos arquivos de conteúdo do Intlayer para declarar alternativas de conteúdo nomeadas
|
|
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:
|
|
7
7
|
- Variantes
|
|
8
8
|
- Testes A/B
|
|
9
|
-
-
|
|
10
|
-
- Conteúdo
|
|
9
|
+
- Feature Flags
|
|
10
|
+
- Conteúdo dinâmico
|
|
11
|
+
- Registros dinâmicos
|
|
12
|
+
- CMS
|
|
11
13
|
- Intlayer
|
|
12
14
|
- Internacionalização
|
|
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: "Lançamento do recurso de variantes
|
|
22
|
+
changes: "Lançamento do recurso de variantes"
|
|
23
|
+
- version: 9.1.0
|
|
24
|
+
date: 2026-06-26
|
|
25
|
+
changes: "`variant` agora aceita uma string ou um objeto — os antigos `meta` / registros dinâmicos são declarados como variantes de objeto"
|
|
21
26
|
author: aymericzip
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
# Variantes
|
|
25
30
|
|
|
26
|
-
Uma **variante**
|
|
31
|
+
Uma **variante** é um conjunto de arquivos de conteúdo que compartilham a mesma chave de dicionário (`key`), mas cada um carrega um valor `variant` diferente. O Intlayer serve o arquivo apropriado com base no seletor passado para `useIntlayer`.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
O valor de `variant` pode assumir **duas formas**:
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
- **Uma string** — uma única alternativa nomeada (testes A/B, banners sazonais, feature flags).
|
|
36
|
+
- **Um objeto** — um discriminador estruturado endereçado por um conjunto de campos (registros de CMS, conteúdo específico do usuário, qualquer conteúdo cuja chave é um ID opaco). O objeto inteiro é a identidade: o seletor deve fornecer um objeto **igual** para resolver a entrada.
|
|
37
|
+
|
|
38
|
+
> A forma de objeto substitui o antigo campo `meta`. Onde você antes escrevia `meta: { id, … }`, escreva `variant: { id, … }` e selecione-a com `{ variant: { id, … } }`.
|
|
39
|
+
|
|
40
|
+
## Variantes nomeadas (string)
|
|
41
|
+
|
|
42
|
+
Cada arquivo representa uma alternativa nomeada. Omitir `variant` (ou defini-lo como `"default"`) o marca como fallback.
|
|
31
43
|
|
|
32
44
|
```ts fileName="hero-banner.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
33
45
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -58,16 +70,16 @@ const dictionary = {
|
|
|
58
70
|
en: "50 % off — today only",
|
|
59
71
|
fr: "−50 % — aujourd'hui seulement",
|
|
60
72
|
}),
|
|
61
|
-
cta: t({ en: "Shop now", fr: "Acheter
|
|
73
|
+
cta: t({ en: "Shop now", fr: "Acheter maintenant" }),
|
|
62
74
|
},
|
|
63
75
|
} satisfies Dictionary;
|
|
64
76
|
|
|
65
77
|
export default dictionary;
|
|
66
78
|
```
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
### Consumir variantes nomeadas
|
|
69
81
|
|
|
70
|
-
|
|
82
|
+
#### Variante padrão
|
|
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
|
+
#### Variante nomeada
|
|
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
|
+
#### Variante nomeada com locale explícito
|
|
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
|
+
## Variantes de objeto (estruturadas)
|
|
242
|
+
|
|
243
|
+
Uma variante de objeto endereça o conteúdo por um conjunto arbitrário de pares chave-valor declarados no campo `variant` — possibilitando modelar registros de CMS, conteúdo específico do usuário ou qualquer conteúdo cuja chave seja um ID opaco. O **objeto inteiro** é a identidade: o seletor deve fornecer um objeto igual para que a entrada seja resolvida.
|
|
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
|
+
### Consumir variantes de objeto
|
|
276
|
+
|
|
277
|
+
Passe o objeto correspondente para `variant`. Cada campo declarado no dicionário deve ser fornecido e igual; caso contrário, o resultado é `null`. A ordem dos campos não importa.
|
|
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
|
+
#### Com locale explícito
|
|
452
|
+
|
|
453
|
+
```tsx
|
|
454
|
+
const content = useIntlayer("product", {
|
|
455
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
456
|
+
locale: "fr",
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### Campo ausente — sem correspondência
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
// Retorna null: `userId` está ausente, então o objeto não corresponde à variante declarada
|
|
464
|
+
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Modo de carregamento
|
|
468
|
+
|
|
469
|
+
As variantes de objeto costumam ser carregadas de forma preguiçosa. Defina `importMode` no dicionário para controlar isso:
|
|
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
|
+
Veja [otimização do bundle](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/bundle_optimization.md) para detalhes sobre os modos `static`, `dynamic` e `fetch`.
|
|
483
|
+
|
|
229
484
|
## Casos de uso típicos
|
|
230
485
|
|
|
231
|
-
- Testes A/B de
|
|
232
|
-
- Banners
|
|
233
|
-
- Mensagens
|
|
234
|
-
- Campanhas de marketing específicas
|
|
486
|
+
- Testes A/B de texto orientados por uma chave de experimento
|
|
487
|
+
- Banners sazonais ou promocionais
|
|
488
|
+
- Mensagens com feature flag
|
|
489
|
+
- Campanhas de marketing específicas por locale
|
|
490
|
+
- Texto de marketing por produto gerenciado em um CMS
|
|
491
|
+
- Conteúdo específico do usuário ou da conta
|
|
492
|
+
- Qualquer conteúdo indexado por um ID opaco em tempo de execução
|
|
@@ -108,7 +108,6 @@ const config: IntlayerConfig = {
|
|
|
108
108
|
* Irá carregar e escrever a saída e as traduções de volta para os arquivos JSON no diretório de localidades
|
|
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/pt/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: Novo Intlayer v9 - O que há de novo?
|
|
5
|
-
description: Descubra o que há de novo no Intlayer v9. Apresentando pacotes de compatibilidade drop-in para bibliotecas i18n populares e suporte para Collections
|
|
5
|
+
description: Descubra o que há de novo no Intlayer v9. Apresentando pacotes de compatibilidade drop-in para bibliotecas i18n populares e suporte para Collections e Variants.
|
|
6
6
|
keywords:
|
|
7
7
|
- Intlayer
|
|
8
8
|
- Compatibility
|
|
9
9
|
- Migration
|
|
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
|
# Novo Intlayer v9 - O que há de novo?
|
|
24
23
|
|
|
25
|
-
Bem-vindo ao Intlayer v9! Este grande lançamento marca um marco enorme na simplificação do caminho de migração para o Intlayer com **Compat Adapter Packages** para as principais bibliotecas de i18n (`react-i18next`, `next-intl`, `vue-i18n`, etc.) e adiciona suporte para estruturas de conteúdo ricas: **Collections
|
|
24
|
+
Bem-vindo ao Intlayer v9! Este grande lançamento marca um marco enorme na simplificação do caminho de migração para o Intlayer com **Compat Adapter Packages** para as principais bibliotecas de i18n (`react-i18next`, `next-intl`, `vue-i18n`, etc.) e adiciona suporte para estruturas de conteúdo ricas: **Collections** e **Variants**.
|
|
26
25
|
|
|
27
26
|
## Tabela de conteúdos
|
|
28
27
|
|
|
@@ -41,8 +40,10 @@ Ao substituir os imports, você obtém todos os benefícios do Intlayer (incluin
|
|
|
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
|
Por exemplo, basta alterar:
|
|
48
49
|
|
|
@@ -100,7 +101,7 @@ Todos os adaptadores de compatibilidade agora roteiam a resolução de traduçã
|
|
|
100
101
|
|
|
101
102
|
---
|
|
102
103
|
|
|
103
|
-
## Especificação de Recursos: Collections
|
|
104
|
+
## Especificação de Recursos: Collections & Variants
|
|
104
105
|
|
|
105
106
|
O Intlayer v9 vai além de objetos estáticos de chave-valor, permitindo que os dicionários declarem estruturas de layout dinâmicas que são totalmente tipadas de ponta a ponta.
|
|
106
107
|
|
|
@@ -144,6 +145,8 @@ const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: s
|
|
|
144
145
|
|
|
145
146
|
Entregue testes A/B, cabeçalhos sazonais, feature flags ou landing pages personalizadas:
|
|
146
147
|
|
|
148
|
+
#### Variantes de string (ex. testes 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
|
-
Defina dicionários cujas entradas são carregadas dinamicamente em runtime via IDs de consulta:
|
|
173
|
+
#### Variantes de objeto (ex. 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
|
-
- **Compilador**: Ativa automaticamente quando `compiler.enabled` é definido e um caminho `compiler.output` é configurado. Você não precisa mais registrar `intlayerCompiler()` separadamente.
|
|
233
|
+
- **Compilador**: Ativa automaticamente quando `compiler.enabled` é definido como `true` e um caminho `compiler.output` é configurado. Você não precisa mais registrar `intlayerCompiler()` separadamente.
|
|
233
234
|
- **Proxy**: Ativa automaticamente com base na nova opção `routing.enableProxy` (`true` por padrão). Ele conecta o middleware de detecção de localidade / redirecionamento / reescrita em desenvolvimento, visualização e SSR de produção. Você não precisa mais registrar `intlayerProxy()` separadamente.
|
|
234
235
|
|
|
235
236
|
### Opção `routing.enableProxy`
|
|
@@ -252,6 +253,27 @@ Os plugins standalone `intlayerCompiler()` e `intlayerProxy()` permanecem export
|
|
|
252
253
|
|
|
253
254
|
---
|
|
254
255
|
|
|
256
|
+
## Compilador desativado por padrão
|
|
257
|
+
|
|
258
|
+
A partir do Intlayer v9, o **compilador está desativado por padrão** (`compiler.enabled` agora tem o valor padrão `false`). Para ativar a extração dos seus arquivos `.content.ts` em tempo de build, defina `compiler.enabled: true` na sua configuração:
|
|
259
|
+
|
|
260
|
+
```ts fileName="intlayer.config.ts"
|
|
261
|
+
import type { IntlayerConfig } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const config: IntlayerConfig = {
|
|
264
|
+
compiler: {
|
|
265
|
+
enabled: true, // Padrão: false — necessário para ativar o compilador desde a v9
|
|
266
|
+
output: ({ fileName }) => `./${fileName}.content.ts`,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default config;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Quando o compilador está desativado, o Intlayer pula a etapa de extração em tempo de build e depende dos dicionários que você já declarou. Ative-o apenas quando quiser que o plugin do bundler (`@intlayer/swc`, `@intlayer/babel` ou o plugin Vite `intlayer()`) extraia o conteúdo automaticamente.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
255
277
|
## React Native: importações de um único pacote
|
|
256
278
|
|
|
257
279
|
Em um aplicativo React Native ou Expo, você não precisa mais alternar entre `react-intlayer` e `react-native-intlayer`. O pacote `react-native-intlayer` agora **reexporta toda a API do `react-intlayer`** (hooks, utilitários e os subcaminhos `/format`, `/html` e `/markdown`), e seu `IntlayerProvider` aplica automaticamente os polyfills do React Native.
|
|
@@ -278,13 +300,14 @@ npm install intlayer react-native-intlayer
|
|
|
278
300
|
|
|
279
301
|
Se você estiver atualizando da v8, observe que a v9 não inclui breaking changes. Mas aqui estão as principais mudanças:
|
|
280
302
|
|
|
303
|
+
- **Compilador desativado por padrão**: `compiler.enabled` agora tem o valor padrão `false`. Se você depende da extração dos seus arquivos `.content.ts` em tempo de build, defina `compiler.enabled: true` no seu `intlayer.config.ts`.
|
|
281
304
|
- **Locales & Dialects**: Se estiver usando dependências externas de i18n, adicione seus respectivos plugins de compatibilidade na sua configuração ou setup do bundler para reescrever os imports automaticamente.
|
|
282
|
-
- **Custom Selectors**: Ao chamar `useIntlayer`, o segundo parâmetro agora é reservado para um objeto de opções contendo `{ locale, item, variant
|
|
305
|
+
- **Custom Selectors**: Ao chamar `useIntlayer`, o segundo parâmetro agora é reservado para um objeto de opções contendo `{ locale, item, variant }`. Se você passava anteriormente uma string de locale diretamente, ainda pode fazer isso, mas o uso do objeto de opções é recomendado para seleções avançadas.
|
|
283
306
|
|
|
284
307
|
---
|
|
285
308
|
|
|
286
309
|
## Links úteis
|
|
287
310
|
|
|
288
311
|
- [Guia de Compat Adapter Packages](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/compat/index.md)
|
|
289
|
-
- [Dicionários Dinâmicos - Collections
|
|
312
|
+
- [Dicionários Dinâmicos - Collections & Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dynamic_dictionaries/index.md)
|
|
290
313
|
- [Referência de Configuração](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/configuration.md)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
4
|
-
title: Динамические
|
|
5
|
-
description: Обзор
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
|
+
title: Динамические словари
|
|
5
|
+
description: Обзор возможностей динамических словарей Intlayer — коллекций и вариантов — для создания гибкого, управляемого во время выполнения i18n-контента.
|
|
6
6
|
keywords:
|
|
7
|
-
- Динамические
|
|
7
|
+
- Динамические словари
|
|
8
8
|
- Коллекции
|
|
9
9
|
- Варианты
|
|
10
|
-
- Динамические Записи
|
|
11
10
|
- Intlayer
|
|
12
11
|
- Интернационализация
|
|
13
12
|
slugs:
|
|
@@ -18,31 +17,38 @@ history:
|
|
|
18
17
|
- version: 9.0.0
|
|
19
18
|
date: 2026-06-12
|
|
20
19
|
changes: "Выпуск функции динамических словарей"
|
|
20
|
+
- version: 9.1.0
|
|
21
|
+
date: 2026-06-26
|
|
22
|
+
changes: "Динамические записи объединены с вариантами — `variant` теперь принимает строку или объект"
|
|
21
23
|
author: aymericzip
|
|
22
24
|
---
|
|
23
25
|
|
|
24
|
-
# Динамические
|
|
26
|
+
# Динамические словари
|
|
25
27
|
|
|
26
|
-
Intlayer поддерживает
|
|
28
|
+
Intlayer поддерживает два механизма для выражения контента, выходящего за рамки единственного статического словаря на ключ. Каждый объявляется через **поле метаданных верхнего уровня** в файле контента; функция-обёртка не нужна.
|
|
27
29
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
| [Коллекции](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/collections.md)
|
|
31
|
-
| [Варианты](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/variants.md)
|
|
32
|
-
| [Динамические Записи](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
|
|
30
|
+
| Возможность | Поле метаданных | Селектор в `useIntlayer` |
|
|
31
|
+
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------ |
|
|
32
|
+
| [Коллекции](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
|
|
33
|
+
| [Варианты](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/variants.md) | `variant: "name"` _или_ `variant: { … }` | `{ variant: "name" }` _или_ `{ variant: { … } }` |
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
Оба сочетаются с аргументом locale и поддерживают выборочную / отложенную загрузку через `importMode`.
|
|
35
36
|
|
|
36
37
|
## Когда что использовать
|
|
37
38
|
|
|
38
|
-
- **Коллекции** — упорядоченный список элементов, управляемых в отдельных файлах (
|
|
39
|
-
- **Варианты** — именованные
|
|
40
|
-
-
|
|
39
|
+
- **Коллекции** — упорядоченный список элементов, управляемых в отдельных файлах (записи FAQ, посты блога, товары).
|
|
40
|
+
- **Варианты** — именованные или структурированные альтернативы контента:
|
|
41
|
+
- **строковый** вариант для A/B-тестов, сезонных баннеров или feature-флагов;
|
|
42
|
+
- **объектный** вариант для записей CMS, контента конкретного пользователя или любого контента, адресуемого набором полей (прежние «динамические записи»).
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
> В предыдущих версиях для контента по записям было отдельное поле `meta`. Оно объединено с `variant`: передавайте `variant` **объект** вместо использования `meta`.
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
## Разрешение неоднозначности селектора
|
|
47
|
+
|
|
48
|
+
Ключ может объявлять оба измерения одновременно (например, коллекция, у каждого элемента которой есть вариант). Они разрешаются в порядке:
|
|
45
49
|
|
|
46
50
|
```
|
|
47
|
-
variant →
|
|
51
|
+
variant → item
|
|
48
52
|
```
|
|
53
|
+
|
|
54
|
+
Так, `{ variant: "promo" }` для ключа variant × item возвращает все promo-элементы в виде массива, а добавление `{ item: 2 }` сужает результат до одной записи.
|