@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: Варианты
|
|
5
|
-
description: Используйте поле метаданных variant в файлах контента Intlayer
|
|
5
|
+
description: Используйте поле метаданных variant в файлах контента Intlayer, чтобы объявлять именованные или структурированные альтернативы контента — A/B-тесты, сезонные баннеры, тексты под feature-флагами, записи CMS, контент конкретного пользователя — и переключаться между ними во время выполнения без изменений кода.
|
|
6
6
|
keywords:
|
|
7
7
|
- Варианты
|
|
8
|
-
- A/B
|
|
9
|
-
-
|
|
10
|
-
- Динамический
|
|
8
|
+
- A/B-тестирование
|
|
9
|
+
- Feature-флаги
|
|
10
|
+
- Динамический контент
|
|
11
|
+
- Динамические записи
|
|
12
|
+
- CMS
|
|
11
13
|
- Intlayer
|
|
12
14
|
- Интернационализация
|
|
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: "Выпуск функции вариантов
|
|
22
|
+
changes: "Выпуск функции вариантов"
|
|
23
|
+
- version: 9.1.0
|
|
24
|
+
date: 2026-06-26
|
|
25
|
+
changes: "`variant` теперь принимает строку или объект — прежние `meta` / динамические записи объявляются как объектные варианты"
|
|
21
26
|
author: aymericzip
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
# Варианты
|
|
25
30
|
|
|
26
|
-
**Вариант**
|
|
31
|
+
**Вариант** — это набор файлов контента, которые имеют общий ключ словаря (`key`), но каждый несёт своё значение `variant`. Intlayer отдаёт нужный файл на основе селектора, переданного в `useIntlayer`.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
Значение `variant` может принимать **две формы**:
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
- **Строка** — одна именованная альтернатива (A/B-тесты, сезонные баннеры, feature-флаги).
|
|
36
|
+
- **Объект** — структурированный дискриминатор, адресуемый набором полей (записи CMS, контент конкретного пользователя, любой контент с непрозрачным ID в качестве ключа). Идентичностью является весь объект: селектор должен предоставить **равный** объект, чтобы разрешить запись.
|
|
37
|
+
|
|
38
|
+
> Объектная форма заменяет прежнее поле `meta`. Везде, где раньше вы писали `meta: { id, … }`, пишите `variant: { id, … }` и выбирайте её через `{ variant: { id, … } }`.
|
|
39
|
+
|
|
40
|
+
## Именованные (строковые) варианты
|
|
41
|
+
|
|
42
|
+
Каждый файл представляет одну именованную альтернативу. Пропуск `variant` (или значение `"default"`) помечает его как запасной вариант.
|
|
31
43
|
|
|
32
44
|
```ts fileName="hero-banner.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
33
45
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -65,9 +77,9 @@ const dictionary = {
|
|
|
65
77
|
export default dictionary;
|
|
66
78
|
```
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
### Использование именованных вариантов
|
|
69
81
|
|
|
70
|
-
|
|
82
|
+
#### Вариант по умолчанию
|
|
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
|
+
#### Именованный вариант
|
|
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
|
+
#### Именованный вариант с явной локалью
|
|
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
|
|
|
229
|
-
##
|
|
241
|
+
## Объектные (структурированные) варианты
|
|
242
|
+
|
|
243
|
+
Объектный вариант адресует контент произвольным набором пар ключ-значение, объявленных в поле `variant`, — что позволяет моделировать записи CMS, контент конкретного пользователя или любой контент с непрозрачным ID в качестве ключа. Идентичностью является **весь объект**: селектор должен предоставить равный объект, чтобы запись была разрешена.
|
|
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
|
+
### Использование объектных вариантов
|
|
276
|
+
|
|
277
|
+
Передайте соответствующий объект в `variant`. Каждое поле, объявленное в словаре, должно быть предоставлено и равно; иначе результат — `null`. Порядок полей не имеет значения.
|
|
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
|
+
#### С явной локалью
|
|
452
|
+
|
|
453
|
+
```tsx
|
|
454
|
+
const content = useIntlayer("product", {
|
|
455
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
456
|
+
locale: "fr",
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### Отсутствует поле — нет совпадения
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
// Возвращает null: отсутствует `userId`, поэтому объект не совпадает с объявленным вариантом
|
|
464
|
+
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Режим загрузки
|
|
468
|
+
|
|
469
|
+
Объектные варианты часто загружаются лениво. Задайте `importMode` в словаре, чтобы управлять этим:
|
|
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
|
+
См. [оптимизацию бандла](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/bundle_optimization.md) для подробностей о режимах `static`, `dynamic` и `fetch`.
|
|
483
|
+
|
|
484
|
+
## Типичные сценарии использования
|
|
230
485
|
|
|
231
|
-
- A/B
|
|
232
|
-
- Сезонные или
|
|
233
|
-
-
|
|
234
|
-
- Маркетинговые кампании для
|
|
486
|
+
- A/B-тесты текста, управляемые ключом эксперимента
|
|
487
|
+
- Сезонные или рекламные баннеры
|
|
488
|
+
- Сообщения под feature-флагами
|
|
489
|
+
- Маркетинговые кампании для конкретной локали
|
|
490
|
+
- Маркетинговый текст по товарам, управляемый в CMS
|
|
491
|
+
- Контент конкретного пользователя или аккаунта
|
|
492
|
+
- Любой контент, адресуемый непрозрачным ID во время выполнения
|
|
@@ -109,7 +109,6 @@ const config: IntlayerConfig = {
|
|
|
109
109
|
* Загрузит, а также запишет результат и переводы обратно в JSON-файлы в директории locales
|
|
110
110
|
*/
|
|
111
111
|
syncJSON({
|
|
112
|
-
format: "i18next",
|
|
113
112
|
source: ({ key, locale }) => `./locales/${locale}/${key}.json`,
|
|
114
113
|
priority: 0,
|
|
115
114
|
format: "i18next",
|
package/docs/ru/releases/v9.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: Новый Intlayer v9 — Что нового?
|
|
5
|
-
description: Узнайте, что нового в Intlayer v9. Представляем пакеты совместимости drop-in для популярных библиотек i18n, а также поддержку Collections
|
|
5
|
+
description: Узнайте, что нового в Intlayer v9. Представляем пакеты совместимости drop-in для популярных библиотек i18n, а также поддержку Collections и Variants.
|
|
6
6
|
keywords:
|
|
7
7
|
- Intlayer
|
|
8
8
|
- Совместимость
|
|
9
9
|
- Миграция
|
|
10
10
|
- Collections
|
|
11
11
|
- Variants
|
|
12
|
-
- Dynamic Records
|
|
13
12
|
- i18next
|
|
14
13
|
- next-intl
|
|
15
14
|
- vue-i18n
|
|
@@ -22,7 +21,7 @@ author: aymericzip
|
|
|
22
21
|
|
|
23
22
|
# Новый Intlayer v9 — Что нового?
|
|
24
23
|
|
|
25
|
-
Добро пожаловать в Intlayer v9! Этот мажорный релиз знаменует собой важную веху в упрощении миграции на Intlayer благодаря **пакетам адаптеров совместимости (Compat Adapter Packages)** для популярных библиотек i18n (`react-i18next`, `next-intl`, `vue-i18n` и др.), а также добавляет поддержку сложных структур контента: **Collections** (Коллекции)
|
|
24
|
+
Добро пожаловать в Intlayer v9! Этот мажорный релиз знаменует собой важную веху в упрощении миграции на Intlayer благодаря **пакетам адаптеров совместимости (Compat Adapter Packages)** для популярных библиотек i18n (`react-i18next`, `next-intl`, `vue-i18n` и др.), а также добавляет поддержку сложных структур контента: **Collections** (Коллекции) и **Variants** (Варианты).
|
|
26
25
|
|
|
27
26
|
## Содержание
|
|
28
27
|
|
|
@@ -41,8 +40,10 @@ author: aymericzip
|
|
|
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
|
Например, просто замените:
|
|
48
49
|
|
|
@@ -100,7 +101,7 @@ export default defineConfig({
|
|
|
100
101
|
|
|
101
102
|
---
|
|
102
103
|
|
|
103
|
-
## Спецификация функций: Collections
|
|
104
|
+
## Спецификация функций: Collections и Variants
|
|
104
105
|
|
|
105
106
|
Intlayer v9 выходит за рамки статических объектов типа ключ-значение, позволяя словарям объявлять динамические структуры макетов со сквозной типизацией.
|
|
106
107
|
|
|
@@ -144,6 +145,8 @@ const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: s
|
|
|
144
145
|
|
|
145
146
|
Используйте для A/B-тестирования, сезонных заголовков, фича-флагов или кастомных целевых страниц:
|
|
146
147
|
|
|
148
|
+
#### Строковые варианты (например, 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
|
-
Определяйте словари, записи которых загружаются динамически во время выполнения по идентификаторам запросов:
|
|
173
|
+
#### Объектные варианты (например, динамические записи)
|
|
173
174
|
|
|
174
175
|
```ts fileName="product.content.ts"
|
|
175
176
|
import { t, type Dictionary } from "intlayer";
|
|
176
177
|
|
|
177
178
|
export default {
|
|
178
179
|
key: "product-copy",
|
|
179
|
-
|
|
180
|
+
variant: {
|
|
180
181
|
id: "prod_123",
|
|
181
182
|
category: "books",
|
|
182
183
|
},
|
|
@@ -229,7 +230,7 @@ export default defineConfig({
|
|
|
229
230
|
});
|
|
230
231
|
```
|
|
231
232
|
|
|
232
|
-
- **Compiler**: Активируется автоматически, когда
|
|
233
|
+
- **Compiler**: Активируется автоматически, когда параметр `compiler.enabled` установлен в `true` и настроен путь `compiler.output`. Вам больше не нужно регистрировать `intlayerCompiler()` отдельно.
|
|
233
234
|
- **Proxy**: Активируется автоматически на основе нового параметра `routing.enableProxy` (`true` по умолчанию). Он подключает middleware обнаружения локалей / перенаправления / переписи в разработке, preview и production SSR. Вам больше не нужно регистрировать `intlayerProxy()` отдельно.
|
|
234
235
|
|
|
235
236
|
### Опция `routing.enableProxy`
|
|
@@ -252,6 +253,27 @@ export default config;
|
|
|
252
253
|
|
|
253
254
|
---
|
|
254
255
|
|
|
256
|
+
## Компилятор отключён по умолчанию
|
|
257
|
+
|
|
258
|
+
Начиная с Intlayer v9, **компилятор отключён по умолчанию** (значение `compiler.enabled` теперь по умолчанию равно `false`). Чтобы включить извлечение ваших файлов `.content.ts` во время сборки, установите `compiler.enabled: true` в своей конфигурации:
|
|
259
|
+
|
|
260
|
+
```ts fileName="intlayer.config.ts"
|
|
261
|
+
import type { IntlayerConfig } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const config: IntlayerConfig = {
|
|
264
|
+
compiler: {
|
|
265
|
+
enabled: true, // По умолчанию: false — требуется для включения компилятора начиная с v9
|
|
266
|
+
output: ({ fileName }) => `./${fileName}.content.ts`,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default config;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Когда компилятор отключён, Intlayer пропускает этап извлечения во время сборки и полагается на уже объявленные вами словари. Включайте его только тогда, когда хотите, чтобы плагин сборщика (`@intlayer/swc`, `@intlayer/babel` или Vite-плагин `intlayer()`) извлекал содержимое автоматически.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
255
277
|
## React Native: импорт из одного пакета
|
|
256
278
|
|
|
257
279
|
В приложении React Native или Expo вам больше не нужно жонглировать `react-intlayer` и `react-native-intlayer`. Пакет `react-native-intlayer` теперь **реэкспортирует весь API `react-intlayer`** (хуки, утилиты и подпути `/format`, `/html` и `/markdown`), а его `IntlayerProvider` автоматически применяет полифиллы React Native.
|
|
@@ -278,13 +300,14 @@ npm install intlayer react-native-intlayer
|
|
|
278
300
|
|
|
279
301
|
Если вы обновляетесь с v8, обратите внимание, что v9 не содержит ломающих изменений (breaking changes). Однако вот ключевые изменения:
|
|
280
302
|
|
|
303
|
+
- **Компилятор отключён по умолчанию**: значение `compiler.enabled` теперь по умолчанию равно `false`. Если вы полагаетесь на извлечение ваших файлов `.content.ts` во время сборки, установите `compiler.enabled: true` в своём `intlayer.config.ts`.
|
|
281
304
|
- **Локали и диалекты (Locales & Dialects)**: Если вы используете внешние зависимости i18n, добавьте соответствующие плагины адаптеров совместимости в вашу конфигурацию или настройки сборщика для автоматической перезаписи импортов.
|
|
282
|
-
- **Кастомные селекторы (Custom Selectors)**: При вызове `useIntlayer` второй параметр теперь зарезервирован для объекта опций, содержащего `{ locale, item, variant
|
|
305
|
+
- **Кастомные селекторы (Custom Selectors)**: При вызове `useIntlayer` второй параметр теперь зарезервирован для объекта опций, содержащего `{ locale, item, variant }`. Если ранее вы передавали строку локали напрямую, вы все еще можете это делать, но для расширенного выбора рекомендуется использовать объект опций.
|
|
283
306
|
|
|
284
307
|
---
|
|
285
308
|
|
|
286
309
|
## Полезные ссылки
|
|
287
310
|
|
|
288
311
|
- [Руководство по пакетам адаптеров совместимости](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/compat/index.md)
|
|
289
|
-
- [Динамические словари — Collections
|
|
312
|
+
- [Динамические словари — Collections и Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/dynamic_dictionaries/index.md)
|
|
290
313
|
- [Справочник по конфигурации](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ru/configuration.md)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
4
|
-
title: Dinamik
|
|
5
|
-
description:
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
|
+
title: Dinamik sözlükler
|
|
5
|
+
description: Intlayer'in dinamik sözlük özelliklerine — koleksiyonlar ve varyantlar — genel bakış; esnek, çalışma zamanında yönlendirilen i18n içeriği oluşturmak için.
|
|
6
6
|
keywords:
|
|
7
|
-
- Dinamik
|
|
7
|
+
- Dinamik sözlükler
|
|
8
8
|
- Koleksiyonlar
|
|
9
9
|
- Varyantlar
|
|
10
|
-
- Dinamik Kayıtlar
|
|
11
10
|
- Intlayer
|
|
12
11
|
- Uluslararasılaştırma
|
|
13
12
|
slugs:
|
|
@@ -17,32 +16,39 @@ slugs:
|
|
|
17
16
|
history:
|
|
18
17
|
- version: 9.0.0
|
|
19
18
|
date: 2026-06-12
|
|
20
|
-
changes: "Dinamik sözlükler özelliğinin
|
|
19
|
+
changes: "Dinamik sözlükler özelliğinin yayımlanması"
|
|
20
|
+
- version: 9.1.0
|
|
21
|
+
date: 2026-06-26
|
|
22
|
+
changes: "Dinamik kayıtlar varyantlara birleştirildi — `variant` artık bir dize veya nesne kabul ediyor"
|
|
21
23
|
author: aymericzip
|
|
22
24
|
---
|
|
23
25
|
|
|
24
|
-
# Dinamik
|
|
26
|
+
# Dinamik sözlükler
|
|
25
27
|
|
|
26
|
-
Intlayer, anahtar başına tek bir statik sözlüğün ötesine geçen içeriği ifade etmek için
|
|
28
|
+
Intlayer, anahtar başına tek bir statik sözlüğün ötesine geçen içeriği ifade etmek için iki mekanizmayı destekler. Her biri içerik dosyasında bir **üst düzey meta veri alanı** aracılığıyla bildirilir; sarmalayıcı bir fonksiyona gerek yoktur.
|
|
27
29
|
|
|
28
|
-
| Özellik
|
|
29
|
-
|
|
|
30
|
-
| [Koleksiyonlar](https://github.com/aymericzip/intlayer/blob/main/docs/docs/tr/dynamic_dictionaries/collections.md)
|
|
31
|
-
| [Varyantlar](https://github.com/aymericzip/intlayer/blob/main/docs/docs/tr/dynamic_dictionaries/variants.md)
|
|
32
|
-
| [Dinamik Kayıtlar](https://github.com/aymericzip/intlayer/blob/main/docs/docs/tr/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
|
|
30
|
+
| Özellik | Meta veri alanı | `useIntlayer` içindeki seçici |
|
|
31
|
+
| ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------- | ------------------------------------------------- |
|
|
32
|
+
| [Koleksiyonlar](https://github.com/aymericzip/intlayer/blob/main/docs/docs/tr/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
|
|
33
|
+
| [Varyantlar](https://github.com/aymericzip/intlayer/blob/main/docs/docs/tr/dynamic_dictionaries/variants.md) | `variant: "name"` _veya_ `variant: { … }` | `{ variant: "name" }` _veya_ `{ variant: { … } }` |
|
|
33
34
|
|
|
34
|
-
Her
|
|
35
|
+
Her ikisi de locale argümanıyla birlikte çalışır ve `importMode` aracılığıyla seçici / tembel yüklemeyi destekler.
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Hangisini ne zaman kullanmalı
|
|
37
38
|
|
|
38
|
-
- **Koleksiyonlar** — ayrı dosyalarda yönetilen sıralı öğe listesi (SSS
|
|
39
|
-
- **Varyantlar** —
|
|
40
|
-
-
|
|
39
|
+
- **Koleksiyonlar** — ayrı dosyalarda yönetilen sıralı öğe listesi (SSS girdileri, blog gönderileri, ürünler).
|
|
40
|
+
- **Varyantlar** — adlandırılmış veya yapılandırılmış içerik alternatifleri:
|
|
41
|
+
- A/B testleri, sezonluk afişler veya özellik bayrakları için bir **dize** varyantı;
|
|
42
|
+
- CMS kayıtları, kullanıcıya özel metin veya bir alan kümesiyle adreslenen herhangi bir içerik için bir **nesne** varyantı (eski "dinamik kayıtlar").
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
> Önceki sürümler kayda dayalı içerik için ayrı bir `meta` alanı sunuyordu. Bu, `variant` içine birleştirildi: `meta` kullanmak yerine `variant`'a bir **nesne** geçirin.
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
## Seçici belirsizlik giderme
|
|
47
|
+
|
|
48
|
+
Bir anahtar her iki boyutu da aynı anda bildirebilir (ör. her öğesinin bir varyantı olan bir koleksiyon). Bunlar şu sırayla çözümlenir:
|
|
45
49
|
|
|
46
50
|
```
|
|
47
|
-
variant →
|
|
51
|
+
variant → item
|
|
48
52
|
```
|
|
53
|
+
|
|
54
|
+
Böylece variant × item anahtarında `{ variant: "promo" }`, tüm promo öğelerini bir dizi olarak döndürür ve `{ item: 2 }` eklemek bunu tek bir girdiye daraltır.
|