@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.
Files changed (98) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +0 -20
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +0 -20
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +0 -1
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/dynamic_dictionaries/index.md +24 -18
  8. package/docs/ar/dynamic_dictionaries/variants.md +280 -22
  9. package/docs/ar/plugins/sync-json.md +0 -1
  10. package/docs/ar/releases/v9.md +35 -12
  11. package/docs/de/dynamic_dictionaries/index.md +22 -22
  12. package/docs/de/dynamic_dictionaries/variants.md +272 -14
  13. package/docs/de/plugins/sync-json.md +0 -1
  14. package/docs/de/releases/v9.md +35 -12
  15. package/docs/en/dynamic_dictionaries/index.md +20 -14
  16. package/docs/en/dynamic_dictionaries/variants.md +266 -8
  17. package/docs/en/plugins/sync-json.md +0 -1
  18. package/docs/en/releases/v9.md +35 -12
  19. package/docs/en-GB/dynamic_dictionaries/index.md +21 -15
  20. package/docs/en-GB/dynamic_dictionaries/variants.md +268 -10
  21. package/docs/en-GB/plugins/sync-json.md +0 -1
  22. package/docs/en-GB/releases/v9.md +35 -12
  23. package/docs/es/dynamic_dictionaries/index.md +25 -19
  24. package/docs/es/dynamic_dictionaries/variants.md +275 -17
  25. package/docs/es/plugins/sync-json.md +0 -1
  26. package/docs/es/releases/v9.md +35 -12
  27. package/docs/fr/dynamic_dictionaries/index.md +26 -20
  28. package/docs/fr/dynamic_dictionaries/variants.md +273 -15
  29. package/docs/fr/plugins/sync-json.md +0 -1
  30. package/docs/fr/releases/v9.md +35 -12
  31. package/docs/hi/dynamic_dictionaries/index.md +28 -22
  32. package/docs/hi/dynamic_dictionaries/variants.md +282 -24
  33. package/docs/hi/plugins/sync-json.md +0 -1
  34. package/docs/hi/releases/v9.md +35 -12
  35. package/docs/id/dynamic_dictionaries/index.md +25 -19
  36. package/docs/id/dynamic_dictionaries/variants.md +274 -16
  37. package/docs/id/plugins/sync-json.md +0 -1
  38. package/docs/id/releases/v9.md +35 -12
  39. package/docs/it/dynamic_dictionaries/index.md +26 -20
  40. package/docs/it/dynamic_dictionaries/variants.md +273 -15
  41. package/docs/it/plugins/sync-json.md +0 -1
  42. package/docs/it/releases/v9.md +35 -12
  43. package/docs/ja/dynamic_dictionaries/index.md +27 -21
  44. package/docs/ja/dynamic_dictionaries/variants.md +276 -18
  45. package/docs/ja/plugins/sync-json.md +0 -1
  46. package/docs/ja/releases/v9.md +35 -12
  47. package/docs/ko/dynamic_dictionaries/index.md +23 -17
  48. package/docs/ko/dynamic_dictionaries/variants.md +273 -15
  49. package/docs/ko/plugins/sync-json.md +0 -1
  50. package/docs/ko/releases/v9.md +35 -12
  51. package/docs/pl/dynamic_dictionaries/index.md +26 -20
  52. package/docs/pl/dynamic_dictionaries/variants.md +275 -17
  53. package/docs/pl/plugins/sync-json.md +0 -1
  54. package/docs/pl/releases/v9.md +35 -12
  55. package/docs/pt/dynamic_dictionaries/index.md +25 -19
  56. package/docs/pt/dynamic_dictionaries/variants.md +276 -18
  57. package/docs/pt/plugins/sync-json.md +0 -1
  58. package/docs/pt/releases/v9.md +35 -12
  59. package/docs/ru/dynamic_dictionaries/index.md +25 -19
  60. package/docs/ru/dynamic_dictionaries/variants.md +277 -19
  61. package/docs/ru/plugins/sync-json.md +0 -1
  62. package/docs/ru/releases/v9.md +35 -12
  63. package/docs/tr/dynamic_dictionaries/index.md +27 -21
  64. package/docs/tr/dynamic_dictionaries/variants.md +274 -16
  65. package/docs/tr/plugins/sync-json.md +0 -1
  66. package/docs/tr/releases/v9.md +35 -12
  67. package/docs/uk/dynamic_dictionaries/index.md +25 -19
  68. package/docs/uk/dynamic_dictionaries/variants.md +277 -19
  69. package/docs/uk/plugins/sync-json.md +0 -1
  70. package/docs/uk/releases/v9.md +35 -12
  71. package/docs/vi/dynamic_dictionaries/index.md +28 -22
  72. package/docs/vi/dynamic_dictionaries/variants.md +278 -20
  73. package/docs/vi/plugins/sync-json.md +0 -1
  74. package/docs/vi/releases/v9.md +35 -12
  75. package/docs/zh/dynamic_dictionaries/index.md +24 -18
  76. package/docs/zh/dynamic_dictionaries/variants.md +274 -16
  77. package/docs/zh/plugins/sync-json.md +0 -1
  78. package/docs/zh/releases/v9.md +35 -12
  79. package/package.json +6 -6
  80. package/src/generated/docs.entry.ts +0 -20
  81. package/docs/ar/dynamic_dictionaries/dynamic_content.md +0 -271
  82. package/docs/de/dynamic_dictionaries/dynamic_content.md +0 -271
  83. package/docs/en/dynamic_dictionaries/dynamic_content.md +0 -271
  84. package/docs/en-GB/dynamic_dictionaries/dynamic_content.md +0 -271
  85. package/docs/es/dynamic_dictionaries/dynamic_content.md +0 -271
  86. package/docs/fr/dynamic_dictionaries/dynamic_content.md +0 -271
  87. package/docs/hi/dynamic_dictionaries/dynamic_content.md +0 -271
  88. package/docs/id/dynamic_dictionaries/dynamic_content.md +0 -271
  89. package/docs/it/dynamic_dictionaries/dynamic_content.md +0 -271
  90. package/docs/ja/dynamic_dictionaries/dynamic_content.md +0 -271
  91. package/docs/ko/dynamic_dictionaries/dynamic_content.md +0 -271
  92. package/docs/pl/dynamic_dictionaries/dynamic_content.md +0 -271
  93. package/docs/pt/dynamic_dictionaries/dynamic_content.md +0 -271
  94. package/docs/ru/dynamic_dictionaries/dynamic_content.md +0 -271
  95. package/docs/tr/dynamic_dictionaries/dynamic_content.md +0 -271
  96. package/docs/uk/dynamic_dictionaries/dynamic_content.md +0 -271
  97. package/docs/vi/dynamic_dictionaries/dynamic_content.md +0 -271
  98. 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-12
3
+ updatedAt: 2026-06-26
4
4
  title: 변형
5
- description: 코드 변경 없이 런타임에 서로 전환할 있는 이름이 지정된 대체 콘텐츠(A/B 테스트, 시즌별 배너, 기능 플래그가 지정된 텍스트)를 선언하기 위해 Intlayer 콘텐츠 파일에서 variant 메타데이터 필드를 사용합니다.
5
+ description: Intlayer 콘텐츠 파일에서 variant 메타데이터 필드를 사용하여 이름이 지정되었거나 구조화된 콘텐츠 대안 — A/B 테스트, 시즌 배너, 기능 플래그 텍스트, CMS 레코드, 사용자별 콘텐츠 선언하고 코드 변경 없이 런타임에 전환합니다.
6
6
  keywords:
7
7
  - 변형
8
8
  - A/B 테스트
9
9
  - 기능 플래그
10
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
- **변형**(Variant)은 동일한 사전 키(`key`)를 공유하지만 서로 다른 `variant` 이름을 선언하는 콘텐츠 파일의 집합입니다. Intlayer는 `useIntlayer`에 전달된 선택기에 따라 적절한 파일을 서비스합니다.
31
+ **변형**은 동일한 사전 `key`를 공유하지만 각각 다른 `variant` 값을 갖는 콘텐츠 파일의 집합입니다. Intlayer는 `useIntlayer`에 전달된 셀렉터에 따라 적절한 파일을 제공합니다.
27
32
 
28
- ## 변형 선언
33
+ `variant` 값은 **두 가지 형태**를 가질 수 있습니다:
29
34
 
30
- 파일은 하나의 이름이 지정된 대체 콘텐츠를 나타냅니다. `variant` 필드를 생략하거나 `"default"`로 설정하면 기본(fallback) 변형으로 표시됩니다.
35
+ - **문자열** 단일 이름 지정 대안(A/B 테스트, 시즌 배너, 기능 플래그).
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: "ko",
237
+ locale: "fr",
226
238
  });
227
239
  ```
228
240
 
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
+ `static`, `dynamic`, `fetch` 모드에 대한 자세한 내용은 [번들 최적화](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/bundle_optimization.md)를 참조하세요.
483
+
229
484
  ## 일반적인 사용 사례
230
485
 
231
- - 실험 키(experiment key)에 따른 A/B 카피 테스트
232
- - 시즌별 또는 프로모션 배너
233
- - 기능 플래그(feature flags)로 제어되는 문구
234
- - 특정 로케일 타겟 마케팅 캠페인
486
+ - 실험 키로 구동되는 A/B 카피 테스트
487
+ - 시즌 또는 프로모션 배너
488
+ - 기능 플래그 메시지
489
+ - 로케일별 마케팅 캠페인
490
+ - CMS에서 관리되는 제품별 마케팅 카피
491
+ - 사용자별 또는 계정별 콘텐츠
492
+ - 런타임에 불투명한 ID로 키가 지정된 모든 콘텐츠
@@ -108,7 +108,6 @@ const config: IntlayerConfig = {
108
108
  * 출력 및 번역을 로케일 디렉토리의 JSON 파일로 로드하고 다시 씁니다.
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",
@@ -1,15 +1,14 @@
1
1
  ---
2
2
  createdAt: 2026-06-14
3
- updatedAt: 2026-06-25
3
+ updatedAt: 2026-06-26
4
4
  title: 새로운 Intlayer v9 - 무엇이 달라졌나요?
5
- description: Intlayer v9의 새로운 기능을 알아보세요. 인기 있는 i18n 라이브러리를 위한 드롭인 호환성 패키지와 컬렉션(Collections), 베리언트(Variants), 동적 레코드(Dynamic Records) 지원을 소개합니다.
5
+ description: Intlayer v9의 새로운 기능을 알아보세요. 인기 있는 i18n 라이브러리를 위한 드롭인 호환성 패키지와 컬렉션(Collections), 베리언트(Variants) 지원을 소개합니다.
6
6
  keywords:
7
7
  - Intlayer
8
8
  - 호환성
9
9
  - 마이그레이션
10
10
  - 컬렉션
11
11
  - 베리언트
12
- - 동적 레코드
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에 오신 것을 환영합니다! 이번 메이저 릴리스는 주요 i18n 라이브러리(`react-i18next`, `next-intl`, `vue-i18n` 등)를 위한 **호환 어댑터 패키지(Compat Adapter Packages)**를 통해 Intlayer로의 마이그레이션 경로를 획기적으로 단순화하고, **컬렉션(Collections)**, **베리언트(Variants)**, **동적 레코드(Dynamic Records)**와 같은 풍부한 콘텐츠 구조 지원을 추가하는 큰 이정표를 세웠습니다.
24
+ Intlayer v9에 오신 것을 환영합니다! 이번 메이저 릴리스는 주요 i18n 라이브러리(`react-i18next`, `next-intl`, `vue-i18n` 등)를 위한 **호환 어댑터 패키지(Compat Adapter Packages)**를 통해 Intlayer로의 마이그레이션 경로를 획기적으로 단순화하고, **컬렉션(Collections)** **베리언트(Variants)**와 같은 풍부한 콘텐츠 구조 지원을 추가하는 큰 이정표를 세웠습니다.
26
25
 
27
26
  ## 목차
28
27
 
@@ -41,8 +40,10 @@ Intlayer v9에 오신 것을 환영합니다! 이번 메이저 릴리스는 주
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
- ## 기능 사양: 컬렉션, 베리언트 동적 레코드
104
+ ## 기능 사양: 컬렉션베리언트
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 테스트, 시즌별 헤더, 피처 플래그(feature flags) 또는 커스텀 랜딩 페이지를 제공합니다:
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
- ### 3. 동적 레코드 (Dynamic Records)
171
-
172
- 쿼리 ID를 통해 런타임에 동적으로 로드되는 항목을 가진 딕셔너리를 정의합니다:
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
- meta: {
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**: `compiler.enabled`가 설정되고 `compiler.output` 경로가 구성되면 자동으로 활성화됩니다. 더 이상 `intlayerCompiler()`를 별도로 등록할 필요가 없습니다.
233
+ - **Compiler**: `compiler.enabled`가 `true`로 설정되고 `compiler.output` 경로가 구성되면 자동으로 활성화됩니다. 더 이상 `intlayerCompiler()`를 별도로 등록할 필요가 없습니다.
233
234
  - **Proxy**: 새로운 `routing.enableProxy` 옵션(`기본값: true`)을 기반으로 자동으로 활성화됩니다. 개발, 미리보기 및 프로덕션 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` 또는 `intlayer()` Vite 플러그인)이 콘텐츠를 자동으로 추출하기를 원할 때만 활성화하세요.
274
+
275
+ ---
276
+
255
277
  ## React Native: 단일 패키지 임포트
256
278
 
257
279
  React Native 또는 Expo 앱에서는 더 이상 `react-intlayer`와 `react-native-intlayer`를 번갈아 사용할 필요가 없습니다. `react-native-intlayer` 패키지는 이제 **`react-intlayer`의 전체 API를 다시 내보내며** (훅, 유틸리티 및 `/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` 파일의 빌드 타임 추출에 의존하는 경우 `intlayer.config.ts`에서 `compiler.enabled: true`를 설정하세요.
281
304
  - **로케일 및 다이얼렉트 (Locales & Dialects)**: 외부 i18n 의존성을 사용하는 경우, 설정 또는 번들러 구성에 해당 호환 어댑터 플러그인을 추가하여 임포트를 자동으로 변환하세요.
282
- - **커스텀 셀렉터 (Custom Selectors)**: `useIntlayer`를 호출할 때 두 번째 매개변수는 이제 `{ locale, item, variant, id }`를 포함하는 옵션 객체 전용으로 예약됩니다. 이전에 로케일 문자열을 직접 전달했다면 여전히 그렇게 사용할 수 있지만, 고급 선택을 위해서는 옵션 객체를 사용하는 것을 권장합니다.
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/ko/compat/index.md)
289
- - [동적 딕셔너리 - 컬렉션, 베리언트 동적 레코드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/index.md)
312
+ - [동적 딕셔너리 - 컬렉션베리언트](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/index.md)
290
313
  - [설정 레퍼런스](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/configuration.md)
@@ -1,15 +1,14 @@
1
1
  ---
2
2
  createdAt: 2026-06-12
3
- updatedAt: 2026-06-12
4
- title: Słowniki Dynamiczne
5
- description: Omówienie trzech funkcji dynamicznych słowników w Intlayer — kolekcji, wariantów i rekordów dynamicznych — do budowania elastycznych, sterowanych w czasie wykonania treści i18n.
3
+ updatedAt: 2026-06-26
4
+ title: Słowniki dynamiczne
5
+ description: Przegląd funkcji słowników dynamicznych Intlayer — kolekcji i wariantów — do tworzenia elastycznej, sterowanej w czasie wykonywania treści i18n.
6
6
  keywords:
7
- - Słowniki Dynamiczne
7
+ - Słowniki dynamiczne
8
8
  - Kolekcje
9
9
  - Warianty
10
- - Rekordy Dynamiczne
11
10
  - Intlayer
12
- - Umiędzynarodowienie
11
+ - Internacjonalizacja
13
12
  slugs:
14
13
  - doc
15
14
  - concept
@@ -18,31 +17,38 @@ history:
18
17
  - version: 9.0.0
19
18
  date: 2026-06-12
20
19
  changes: "Wydanie funkcji słowników dynamicznych"
20
+ - version: 9.1.0
21
+ date: 2026-06-26
22
+ changes: "Scalono rekordy dynamiczne z wariantami — `variant` przyjmuje teraz ciąg znaków lub obiekt"
21
23
  author: aymericzip
22
24
  ---
23
25
 
24
- # Słowniki Dynamiczne
26
+ # Słowniki dynamiczne
25
27
 
26
- Intlayer obsługuje trzy mechanizmy definiowania treści wykraczających poza pojedynczy, statyczny słownik na klucz. Każdy z nich jest deklarowany poprzez **pole metadanych najwyższego poziomu** w pliku zawartości; funkcja opakowująca (wrapper) nie jest wymagana.
28
+ Intlayer obsługuje dwa mechanizmy wyrażania treści wykraczającej poza pojedynczy statyczny słownik na klucz. Każdy jest deklarowany przez **pole metadanych najwyższego poziomu** w pliku treści; nie jest potrzebna żadna funkcja opakowująca.
27
29
 
28
- | Funkcja | Pole metadanych | Selektor w `useIntlayer` |
29
- | --------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------ |
30
- | [Kolekcje](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
31
- | [Warianty](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dynamic_dictionaries/variants.md) | `variant: "name"` | `{ variant: "name" }` |
32
- | [Rekordy Dynamiczne](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
30
+ | Funkcja | Pole metadanych | Selektor w `useIntlayer` |
31
+ | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------ |
32
+ | [Kolekcje](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
33
+ | [Warianty](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dynamic_dictionaries/variants.md) | `variant: "name"` _lub_ `variant: { … }` | `{ variant: "name" }` _lub_ `{ variant: { … } }` |
33
34
 
34
- Wszystkie trzy łączą się z argumentem lokalizacji i obsługują wybiórcze / leniwe ładowanie (lazy loading) za pomocą `importMode`.
35
+ Oba łączą się z argumentem locale i obsługują selektywne / leniwe ładowanie przez `importMode`.
35
36
 
36
- ## Kiedy używać którego rozwiązania
37
+ ## Kiedy czego używać
37
38
 
38
39
  - **Kolekcje** — uporządkowana lista elementów zarządzanych w osobnych plikach (wpisy FAQ, posty na blogu, produkty).
39
- - **Warianty** — nazwane alternatywy treści dla testów A/B, banerów sezonowych lub flag funkcji (feature flags).
40
- - **Rekordy dynamiczne** treści pobierane w czasie wykonania za pomocą nieprzezroczystego identyfikatora ID (rekordy CMS, treści specyficzne dla użytkownika).
40
+ - **Warianty** — nazwane lub strukturalne alternatywy treści:
41
+ - wariant **tekstowy** do testów A/B, banerów sezonowych lub feature flag;
42
+ - wariant **obiektowy** dla rekordów CMS, treści zależnej od użytkownika lub dowolnej treści adresowanej zestawem pól (dawne „rekordy dynamiczne").
41
43
 
42
- ## Rozstrzyganie konfliktów selektorów
44
+ > Wcześniejsze wersje udostępniały osobne pole `meta` dla treści indeksowanej rekordami. Zostało scalone z `variant`: przekaż do `variant` **obiekt** zamiast używać `meta`.
43
45
 
44
- Gdy słownik posiada wiele selektorów, kolejność ich rozstrzygania to:
46
+ ## Ujednoznacznianie selektora
47
+
48
+ Klucz może deklarować obydwa wymiary jednocześnie (np. kolekcja, której elementy mają wariant). Są one rozwiązywane w kolejności:
45
49
 
46
50
  ```
47
- variant → meta → item
51
+ variant → item
48
52
  ```
53
+
54
+ Zatem `{ variant: "promo" }` dla klucza variant × item zwraca wszystkie elementy promo jako tablicę, a dodanie `{ item: 2 }` zawęża wynik do pojedynczego wpisu.