@intlayer/docs 9.0.0-canary.7 → 9.0.0-canary.9

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,15 +1,17 @@
1
1
  ---
2
2
  createdAt: 2026-06-12
3
- updatedAt: 2026-06-12
3
+ updatedAt: 2026-06-26
4
4
  title: Variants
5
- description: Use the variant metadata field in Intlayer content files to declare named content alternatives — A/B tests, seasonal banners, feature-flagged copy — and switch between them at runtime without code changes.
5
+ description: Use the variant metadata field in Intlayer content files to declare named or structured content alternatives — A/B tests, seasonal banners, feature-flagged copy, CMS records, user-specific content — and switch between them at runtime without code changes.
6
6
  keywords:
7
7
  - Variants
8
8
  - A/B Testing
9
9
  - Feature Flags
10
10
  - Dynamic Content
11
+ - Dynamic Records
12
+ - CMS
11
13
  - Intlayer
12
- - Internationalisation
14
+ - Internationalization
13
15
  slugs:
14
16
  - doc
15
17
  - concept
@@ -18,14 +20,24 @@ history:
18
20
  - version: 9.0.0
19
21
  date: 2026-06-12
20
22
  changes: "Release of the variants feature"
23
+ - version: 9.1.0
24
+ date: 2026-06-26
25
+ changes: "`variant` now accepts a string or an object — the former `meta` / dynamic records are declared as object variants"
21
26
  author: aymericzip
22
27
  ---
23
28
 
24
29
  # Variants
25
30
 
26
- A **variant** is a set of content files that share the same dictionary `key` but each carry a different `variant` name. Intlayer serves the appropriate file based on the selector passed to `useIntlayer`.
31
+ A **variant** is a set of content files that share the same dictionary `key` but each carry a different `variant` value. Intlayer serves the appropriate file based on the selector passed to `useIntlayer`.
27
32
 
28
- ## Declaring variants
33
+ The `variant` value can take **two forms**:
34
+
35
+ - **A string** — a single named alternative (A/B tests, seasonal banners, feature flags).
36
+ - **An object** — a structured discriminator addressed by a set of fields (CMS records, user-specific copy, any content keyed by an opaque ID). The whole object is the identity: the selector must provide an **equal** object to resolve the entry.
37
+
38
+ > The object form replaces the former `meta` field. Anywhere you previously wrote `meta: { id, … }`, write `variant: { id, … }`, and select it with `{ variant: { id, … } }`.
39
+
40
+ ## Named (string) variants
29
41
 
30
42
  Each file represents one named alternative. Omitting `variant` (or setting it to `"default"`) marks it as the fallback.
31
43
 
@@ -65,9 +77,9 @@ const dictionary = {
65
77
  export default dictionary;
66
78
  ```
67
79
 
68
- ## Consuming variants
80
+ ### Consuming named variants
69
81
 
70
- ### Default variant
82
+ #### Default variant
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
- ### Named variant
224
+ #### Named variant
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
- ### Named variant with explicit locale
232
+ #### Named variant with explicit locale
221
233
 
222
234
  ```tsx
223
235
  const content = useIntlayer("hero-banner", {
224
236
  variant: "black_friday",
225
- locale: "en-GB",
237
+ locale: "fr",
226
238
  });
227
239
  ```
228
240
 
241
+ ## Object (structured) variants
242
+
243
+ An object variant addresses content by an arbitrary set of key-value pairs declared in the `variant` field — making it possible to model CMS records, user-specific copy, or any content whose key is an opaque ID. The **whole object** is the identity: the selector must provide an equal object for the entry to resolve.
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
+ ### Consuming object variants
276
+
277
+ Pass the matching object to `variant`. Every field declared on the dictionary must be provided and equal; otherwise the result is `null`. Field order does not matter.
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
+ #### With explicit locale
452
+
453
+ ```tsx
454
+ const content = useIntlayer("product", {
455
+ variant: { id: "prod_abc", userId: "user_123" },
456
+ locale: "fr",
457
+ });
458
+ ```
459
+
460
+ #### Missing field — no match
461
+
462
+ ```ts
463
+ // Returns null: `userId` is missing, so the object does not match the declared variant
464
+ const content = useIntlayer("product", { variant: { id: "prod_abc" } });
465
+ ```
466
+
467
+ ## Loading mode
468
+
469
+ Object variants are often loaded lazily. Set `importMode` on the dictionary to control this:
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
+ See [bundle optimization](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/bundle_optimization.md) for details on `static`, `dynamic`, and `fetch` modes.
483
+
229
484
  ## Typical use-cases
230
485
 
231
486
  - A/B copy tests driven by an experiment key
232
487
  - Seasonal or promotional banners
233
488
  - Feature-flagged messaging
234
489
  - Locale-specific marketing campaigns
490
+ - Per-product marketing copy managed in a CMS
491
+ - User-specific or account-specific content
492
+ - Any content keyed by an opaque runtime ID
@@ -108,7 +108,6 @@ const config: IntlayerConfig = {
108
108
  * Will load, and write the output and translations back to the JSON files in the locales directory
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: New Intlayer v9 - What's new?
5
- description: Discover what's new in Intlayer v9. Introducing drop-in compatibility packages for popular i18n libraries and support for Collections, Variants, and Dynamic Records.
5
+ description: Discover what's new in Intlayer v9. Introducing drop-in compatibility packages for popular i18n libraries and support for Collections and 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
  # New Intlayer v9 - What's new?
24
23
 
25
- Welcome to Intlayer v9! This major release marks a huge milestone in simplifying the migration path to Intlayer with **Compat Adapter Packages** for major i18n libraries (`react-i18next`, `next-intl`, `vue-i18n`, etc.) and adds support for rich content structures: **Collections**, **Variants**, and **Dynamic Records**.
24
+ Welcome to Intlayer v9! This major release marks a huge milestone in simplifying the migration path to Intlayer with **Compat Adapter Packages** for major i18n libraries (`react-i18next`, `next-intl`, `vue-i18n`, etc.) and adds support for rich content structures: **Collections** and **Variants**.
26
25
 
27
26
  ## Table of contents
28
27
 
@@ -41,8 +40,10 @@ By replacing imports, you get all the benefits of Intlayer (including compile-ti
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
  For example, simply change:
48
49
 
@@ -100,7 +101,7 @@ All compat adapters now route translation resolution through a single, highly op
100
101
 
101
102
  ---
102
103
 
103
- ## Feature Spec: Collections, Variants & Dynamic Records
104
+ ## Feature Spec: Collections & Variants
104
105
 
105
106
  Intlayer v9 expands beyond static key-value objects, allowing dictionaries to declare dynamic layout structures that are fully typed end-to-end.
106
107
 
@@ -136,6 +137,8 @@ const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: s
136
137
 
137
138
  Deliver A/B tests, seasonal headers, feature flags, or custom landing pages:
138
139
 
140
+ #### String variants (e.g. A/B testing)
141
+
139
142
  ```ts fileName="hero.content.ts"
140
143
  import { t, type Dictionary } from "intlayer";
141
144
 
@@ -155,16 +158,14 @@ export default {
155
158
  const banner = useIntlayer("hero-banner", { variant: "black_friday" });
156
159
  ```
157
160
 
158
- ### 3. Dynamic Records
159
-
160
- Define dictionaries whose entries are loaded dynamically at runtime via query IDs:
161
+ #### Object variants (e.g. Dynamic Records)
161
162
 
162
163
  ```ts fileName="product.content.ts"
163
164
  import { t, type Dictionary } from "intlayer";
164
165
 
165
166
  export default {
166
167
  key: "product-copy",
167
- meta: {
168
+ variant: {
168
169
  id: "prod_123",
169
170
  category: "books",
170
171
  },
@@ -217,7 +218,7 @@ export default defineConfig({
217
218
  });
218
219
  ```
219
220
 
220
- - **Compiler**: Activates automatically when `compiler.enabled` is set and a `compiler.output` path is configured. You no longer need to register `intlayerCompiler()` separately.
221
+ - **Compiler**: Activates automatically when `compiler.enabled` is set to `true` and a `compiler.output` path is configured. You no longer need to register `intlayerCompiler()` separately.
221
222
  - **Proxy**: Activates automatically based on the new `routing.enableProxy` option (`true` by default). It wires the locale detection / redirect / rewrite middleware in development, preview, and production SSR. You no longer need to register `intlayerProxy()` separately.
222
223
 
223
224
  ### `routing.enableProxy` option
@@ -240,6 +241,27 @@ The standalone `intlayerCompiler()` and `intlayerProxy()` plugins remain exporte
240
241
 
241
242
  ---
242
243
 
244
+ ## Compiler disabled by default
245
+
246
+ Starting with Intlayer v9, the **compiler is disabled by default** (`compiler.enabled` now defaults to `false`). To opt in to build-time extraction of your `.content.ts` files, set `compiler.enabled: true` in your configuration:
247
+
248
+ ```ts fileName="intlayer.config.ts"
249
+ import type { IntlayerConfig } from "intlayer";
250
+
251
+ const config: IntlayerConfig = {
252
+ compiler: {
253
+ enabled: true, // Default: false — required to enable the compiler since v9
254
+ output: ({ fileName }) => `./${fileName}.content.ts`,
255
+ },
256
+ };
257
+
258
+ export default config;
259
+ ```
260
+
261
+ When the compiler is disabled, Intlayer skips the build-time extraction step and relies on your already-declared dictionaries. Enable it only when you want the bundler plugin (`@intlayer/swc`, `@intlayer/babel`, or the `intlayer()` Vite plugin) to extract content automatically.
262
+
263
+ ---
264
+
243
265
  ## React Native: single-package imports
244
266
 
245
267
  In a React Native or Expo app, you no longer need to juggle both `react-intlayer` and `react-native-intlayer`. The `react-native-intlayer` package now **re-exports the full `react-intlayer` API** (hooks, utilities, and the `/format`, `/html`, and `/markdown` subpaths), and its `IntlayerProvider` automatically applies the React Native polyfills.
@@ -266,13 +288,14 @@ npm install intlayer react-native-intlayer
266
288
 
267
289
  If you are upgrading from v8, note that the v9 does not include breaking changes. But here are the key changes:
268
290
 
291
+ - **Compiler disabled by default**: `compiler.enabled` now defaults to `false`. If you rely on build-time extraction of your `.content.ts` files, set `compiler.enabled: true` in your `intlayer.config.ts`.
269
292
  - **Locales & Dialects**: If using external i18n dependencies, add their respective compat adapter plugins in your configuration or bundler setup to automatically rewrite imports.
270
- - **Custom Selectors**: When calling `useIntlayer`, the second parameter is now reserved for an option object containing `{ locale, item, variant, id }`. If you previously passed a locale string directly, you can still do so, but using the options object is recommended for advanced selections.
293
+ - **Custom Selectors**: When calling `useIntlayer`, the second parameter is now reserved for an option object containing `{ locale, item, variant }`. If you previously passed a locale string directly, you can still do so, but using the options object is recommended for advanced selections.
271
294
 
272
295
  ---
273
296
 
274
297
  ## Useful links
275
298
 
276
299
  - [Compat Adapter Packages Guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/compat/index.md)
277
- - [Dynamic Dictionaries - Collections, Variants & Dynamic Records](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dynamic_dictionaries/index.md)
300
+ - [Dynamic Dictionaries - Collections & Variants](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dynamic_dictionaries/index.md)
278
301
  - [Configuration Reference](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md)
@@ -1,13 +1,12 @@
1
1
  ---
2
2
  createdAt: 2026-06-12
3
- updatedAt: 2026-06-12
4
- title: Diccionarios Dinámicos
5
- description: Descripción general de las tres funciones de diccionario dinámico de Intlayer — colecciones, variantes y registros dinámicos — para crear contenido i18n flexible y controlado en tiempo de ejecución.
3
+ updatedAt: 2026-06-26
4
+ title: Diccionarios dinámicos
5
+ description: Resumen de las funciones de diccionarios dinámicos de Intlayer — colecciones y variantes — para crear contenido i18n flexible y dirigido en tiempo de ejecución.
6
6
  keywords:
7
- - Diccionarios Dinámicos
7
+ - Diccionarios dinámicos
8
8
  - Colecciones
9
9
  - Variantes
10
- - Registros Dinámicos
11
10
  - Intlayer
12
11
  - Internacionalización
13
12
  slugs:
@@ -18,31 +17,38 @@ history:
18
17
  - version: 9.0.0
19
18
  date: 2026-06-12
20
19
  changes: "Lanzamiento de la función de diccionarios dinámicos"
20
+ - version: 9.1.0
21
+ date: 2026-06-26
22
+ changes: "Fusión de los registros dinámicos en las variantes — `variant` ahora acepta una cadena o un objeto"
21
23
  author: aymericzip
22
24
  ---
23
25
 
24
- # Diccionarios Dinámicos
26
+ # Diccionarios dinámicos
25
27
 
26
- Intlayer admite tres mecanismos para expresar contenido que va más allá de un único diccionario estático por clave. Cada uno se declara a través de un **campo de metadatos de nivel superior** en el archivo de contenido; no se necesita ninguna función contenedora (wrapper).
28
+ Intlayer admite dos mecanismos para expresar contenido que va más allá de un único diccionario estático por clave. Cada uno se declara mediante un **campo de metadatos de nivel superior** en el archivo de contenido; no se necesita ninguna función envolvente.
27
29
 
28
- | Característica | Campo de metadatos | Selector en `useIntlayer` |
29
- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------- |
30
- | [Colecciones](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
31
- | [Variantes](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/variants.md) | `variant: "name"` | `{ variant: "name" }` |
32
- | [Registros Dinámicos](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
30
+ | Función | Campo de metadatos | Selector en `useIntlayer` |
31
+ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------- |
32
+ | [Colecciones](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
33
+ | [Variantes](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dynamic_dictionaries/variants.md) | `variant: "name"` _o_ `variant: { … }` | `{ variant: "name" }` _o_ `{ variant: { … } }` |
33
34
 
34
- Los tres se componen con el argumento de configuración regional y admiten la carga selectiva / diferida mediante `importMode`.
35
+ Ambos se combinan con el argumento de locale y admiten la carga selectiva / diferida mediante `importMode`.
35
36
 
36
37
  ## Cuándo usar cada uno
37
38
 
38
- - **Colecciones**: lista ordenada de elementos gestionados en archivos separados (entradas de preguntas frecuentes, publicaciones de blog, productos).
39
- - **Variantes**: alternativas de contenido nombradas para pruebas A/B, banners estacionales o indicadores de funciones (feature flags).
40
- - **Registros dinámicos**: contenido obtenido en tiempo de ejecución mediante un ID opaco (registros de CMS, copia específica del usuario).
39
+ - **Colecciones** lista ordenada de elementos gestionados en archivos separados (entradas de FAQ, artículos de blog, productos).
40
+ - **Variantes** alternativas de contenido con nombre o estructuradas:
41
+ - una variante de **cadena** para pruebas A/B, banners de temporada o feature flags;
42
+ - una variante de **objeto** para registros de CMS, contenido específico de usuario o cualquier contenido direccionado por un conjunto de campos (los antiguos «registros dinámicos»).
41
43
 
42
- ## Desambiguación de selectores
44
+ > Las versiones anteriores exponían un campo `meta` separado para el contenido indexado por registro. Se ha fusionado en `variant`: pase un **objeto** a `variant` en lugar de usar `meta`.
43
45
 
44
- Cuando hay múltiples selectores presentes en un diccionario, el orden de resolución es:
46
+ ## Desambiguación del selector
47
+
48
+ Una clave puede declarar ambas dimensiones a la vez (p. ej. una colección cuyos elementos tienen cada uno una variante). Se resuelven en el orden:
45
49
 
46
50
  ```
47
- variant → meta → item
51
+ variant → item
48
52
  ```
53
+
54
+ Así, `{ variant: "promo" }` en una clave variante × item devuelve todos los elementos promo como un array, y añadir `{ item: 2 }` lo reduce a una sola entrada.