@intlayer/docs 9.0.2 → 9.1.0

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 (44) hide show
  1. package/dist/cjs/generated/docs.entry.cjs +20 -0
  2. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  3. package/dist/esm/generated/docs.entry.mjs +20 -0
  4. package/dist/esm/generated/docs.entry.mjs.map +1 -1
  5. package/dist/types/generated/docs.entry.d.ts +1 -0
  6. package/dist/types/generated/docs.entry.d.ts.map +1 -1
  7. package/docs/ar/dictionary/content_file.md +24 -1
  8. package/docs/ar/dictionary/select.md +386 -0
  9. package/docs/de/dictionary/content_file.md +24 -1
  10. package/docs/de/dictionary/select.md +386 -0
  11. package/docs/en/dictionary/content_file.md +24 -1
  12. package/docs/en/dictionary/select.md +382 -0
  13. package/docs/en-GB/dictionary/content_file.md +24 -1
  14. package/docs/en-GB/dictionary/select.md +385 -0
  15. package/docs/es/dictionary/content_file.md +24 -1
  16. package/docs/es/dictionary/select.md +385 -0
  17. package/docs/fr/dictionary/content_file.md +24 -1
  18. package/docs/fr/dictionary/select.md +382 -0
  19. package/docs/hi/dictionary/content_file.md +24 -1
  20. package/docs/hi/dictionary/select.md +386 -0
  21. package/docs/id/dictionary/content_file.md +24 -1
  22. package/docs/id/dictionary/select.md +386 -0
  23. package/docs/it/dictionary/content_file.md +24 -1
  24. package/docs/it/dictionary/select.md +386 -0
  25. package/docs/ja/dictionary/content_file.md +24 -1
  26. package/docs/ja/dictionary/select.md +386 -0
  27. package/docs/ko/dictionary/content_file.md +24 -1
  28. package/docs/ko/dictionary/select.md +386 -0
  29. package/docs/pl/dictionary/content_file.md +24 -1
  30. package/docs/pl/dictionary/select.md +386 -0
  31. package/docs/pt/dictionary/content_file.md +24 -1
  32. package/docs/pt/dictionary/select.md +386 -0
  33. package/docs/ru/dictionary/content_file.md +25 -2
  34. package/docs/ru/dictionary/select.md +386 -0
  35. package/docs/tr/dictionary/content_file.md +24 -1
  36. package/docs/tr/dictionary/select.md +386 -0
  37. package/docs/uk/dictionary/content_file.md +24 -1
  38. package/docs/uk/dictionary/select.md +386 -0
  39. package/docs/vi/dictionary/content_file.md +24 -1
  40. package/docs/vi/dictionary/select.md +386 -0
  41. package/docs/zh/dictionary/content_file.md +24 -1
  42. package/docs/zh/dictionary/select.md +387 -0
  43. package/package.json +7 -7
  44. package/src/generated/docs.entry.ts +20 -0
@@ -0,0 +1,385 @@
1
+ ---
2
+ createdAt: 2026-07-30
3
+ updatedAt: 2026-07-30
4
+ title: Select Content
5
+ description: Learn how to use select content in Intlayer to dynamically render content based on an arbitrary string value. Follow this documentation to implement switch-like content efficiently in your project.
6
+ keywords:
7
+ - Select Content
8
+ - Switch Content
9
+ - ICU select
10
+ - Dynamic rendering
11
+ - Documentation
12
+ - Intlayer
13
+ - Next.js
14
+ - JavaScript
15
+ - React
16
+ slugs:
17
+ - doc
18
+ - concept
19
+ - content
20
+ - select
21
+ history:
22
+ - version: 9.1.0
23
+ date: 2026-07-30
24
+ changes: "Introduce select content"
25
+ author: aymericzip
26
+ ---
27
+
28
+ # Select Content / Intlayer
29
+
30
+ ## How Select Works
31
+
32
+ In Intlayer, select content is achieved through the `select` function, which maps arbitrary string values to their corresponding content. It is the equivalent of the ICU `{value, select, …}` message, or similar to a `switch` statement in your application's code.
33
+
34
+ Use `select` when the discriminant is an arbitrary string: such as a status, a plan, a platform, or a role. For other discriminants, Intlayer provides dedicated nodes:
35
+
36
+ | Discriminant | Node |
37
+ | ---------------- | ---------- |
38
+ | Quantity | `enu()` |
39
+ | Boolean | `cond()` |
40
+ | Gender | `gender()` |
41
+ | Any other string | `select()` |
42
+
43
+ ## Setting Up Select Content
44
+
45
+ To set up select content in your Intlayer project, create a content module that includes your select definitions. Below are examples in different formats.
46
+
47
+ ```typescript fileName="**/*.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
48
+ import { select, type Dictionary } from "intlayer";
49
+
50
+ const myPostContent = {
51
+ key: "my_key",
52
+ content: {
53
+ publishStatus: select({
54
+ draft: "This post is a draft",
55
+ published: "This post is live",
56
+ scheduled: "This post is scheduled",
57
+ fallback: "Unknown status", // optional
58
+ }),
59
+ },
60
+ } satisfies Dictionary;
61
+
62
+ export default myPostContent;
63
+ ```
64
+
65
+ ```json5 fileName="**/*.content.json" contentDeclarationFormat="json"
66
+ {
67
+ "$schema": "https://intlayer.org/schema.json",
68
+ "key": "my_key",
69
+ "content": {
70
+ "publishStatus": {
71
+ "nodeType": "select",
72
+ "select": {
73
+ "draft": "This post is a draft",
74
+ "published": "This post is live",
75
+ "scheduled": "This post is scheduled",
76
+ "fallback": "Unknown status", // optional
77
+ },
78
+ },
79
+ },
80
+ }
81
+ ```
82
+
83
+ > If no `fallback` is declared, the last declared key is considered as the fallback if the provided value does not match any of the declared cases: exactly the same as for `cond()` and `gender()` contracts.
84
+
85
+ ### Type Safety
86
+
87
+ The accepted argument is inferred from the declared cases:
88
+
89
+ - Without a `fallback`, only the declared cases are accepted: a typo will result in a type error.
90
+ - With a `fallback`, any string is accepted (as the fallback covers unmatched values), whilst the declared cases still provide autocomplete.
91
+
92
+ ## Why not use a regular object?
93
+
94
+ It could be tempting to declare a regular object and index it with the runtime value:
95
+
96
+ ```tsx
97
+ // ❌ Do not do this
98
+ const { publishStatus } = useIntlayer("my_key");
99
+
100
+ return <p>{publishStatus[publishType]}</p>;
101
+ ```
102
+
103
+ The Intlayer compiler parses your source code to eliminate unused content and minify the remaining keys. A dynamically computed access (`obj[expr]`) cannot be resolved statically, hence the entire branch is marked as opaque: it will be kept in the bundle, and its keys will not be minified.
104
+
105
+ By using `select()`, the case resolution happens inside a function call rather than a property access. The compiler sees it as a single, static field access and properly optimises the node exactly as it does for `enu()`, `cond()`, or `gender()`:
106
+
107
+ ```tsx
108
+ // ✅ Do this
109
+ const { publishStatus } = useIntlayer("my_key");
110
+
111
+ return <p>{publishStatus(publishType)}</p>;
112
+ ```
113
+
114
+ ## Using Select Content
115
+
116
+ <Tabs group="framework">
117
+ <Tab label="React" value="react">
118
+
119
+ To utilise select content in a React component, import and use the `useIntlayer` hook from the `react-intlayer` package. This hook fetches the content for the specified key and allows you to pass a value to select the appropriate output.
120
+
121
+ ```tsx fileName="**/*.tsx" codeFormat={["typescript", "esm"]}
122
+ import type { FC } from "react";
123
+ import { useIntlayer } from "react-intlayer";
124
+
125
+ const PostStatus: FC = () => {
126
+ const { publishStatus } = useIntlayer("my_key");
127
+
128
+ return (
129
+ <div>
130
+ <p>
131
+ {
132
+ /* Output: This post is a draft */
133
+ publishStatus("draft")
134
+ }
135
+ </p>
136
+ <p>
137
+ {
138
+ /* Output: This post is live */
139
+ publishStatus("published")
140
+ }
141
+ </p>
142
+ <p>
143
+ {
144
+ /* Output: Unknown status */
145
+ publishStatus("Archived")
146
+ }
147
+ </p>
148
+ </div>
149
+ );
150
+ };
151
+
152
+ export default PostStatus;
153
+ ```
154
+
155
+ </Tab>
156
+ <Tab label="Next.js" value="nextjs">
157
+
158
+ To utilise select content in Next.js Client Components, fetch the content via the `useIntlayer` hook. Here's an example:
159
+
160
+ ```tsx fileName="**/*.tsx" codeFormat={["typescript", "esm"]}
161
+ "use client";
162
+
163
+ import type { FC } from "react";
164
+ import { useIntlayer } from "next-intlayer";
165
+
166
+ const PostStatus: FC = () => {
167
+ const { publishStatus } = useIntlayer("my_key");
168
+
169
+ return (
170
+ <div>
171
+ <p>{publishStatus("draft")}</p>
172
+ <p>{publishStatus("published")}</p>
173
+ </div>
174
+ );
175
+ };
176
+
177
+ export default PostStatus;
178
+ ```
179
+
180
+ </Tab>
181
+ <Tab label="Vue" value="vue">
182
+
183
+ To utilise select content in Vue components, fetch the content via the `useIntlayer` hook. Here's an example:
184
+
185
+ ```vue fileName="**/*.vue"
186
+ <script setup lang="ts">
187
+ import { useIntlayer } from "vue-intlayer";
188
+
189
+ const { publishStatus } = useIntlayer("my_key");
190
+ </script>
191
+
192
+ <template>
193
+ <div>
194
+ <p>{{ publishStatus("draft") }}</p>
195
+ <p>{{ publishStatus("published") }}</p>
196
+ </div>
197
+ </template>
198
+ ```
199
+
200
+ </Tab>
201
+ <Tab label="Svelte" value="svelte">
202
+
203
+ To utilise select content in Svelte components, fetch the content via the `useIntlayer` hook. The store is accessed using `$`. Here's an example:
204
+
205
+ ```svelte fileName="**/*.svelte"
206
+ <script lang="ts">
207
+ import { useIntlayer } from "svelte-intlayer";
208
+
209
+ const content = useIntlayer("my_key");
210
+ </script>
211
+
212
+ <div>
213
+ <p>{$content.publishStatus("draft")}</p>
214
+ <p>{$content.publishStatus("published")}</p>
215
+ </div>
216
+ ```
217
+
218
+ </Tab>
219
+ <Tab label="Preact" value="preact">
220
+
221
+ To utilise select content in Preact components, fetch the content via the `useIntlayer` hook. Here's an example:
222
+
223
+ ```tsx fileName="**/*.tsx" codeFormat={["typescript", "esm"]}
224
+ import type { FC } from "preact";
225
+ import { useIntlayer } from "preact-intlayer";
226
+
227
+ const PostStatus: FC = () => {
228
+ const { publishStatus } = useIntlayer("my_key");
229
+
230
+ return (
231
+ <div>
232
+ <p>{publishStatus("draft")}</p>
233
+ <p>{publishStatus("published")}</p>
234
+ </div>
235
+ );
236
+ };
237
+
238
+ export default PostStatus;
239
+ ```
240
+
241
+ </Tab>
242
+ <Tab label="Solid" value="solid">
243
+
244
+ To utilise select content in SolidJS components, fetch the content via the `useIntlayer` hook. Here's an example:
245
+
246
+ ```tsx fileName="**/*.tsx" codeFormat={["typescript", "esm"]}
247
+ import type { Component } from "solid-js";
248
+ import { useIntlayer } from "solid-intlayer";
249
+
250
+ const PostStatus: Component = () => {
251
+ const { publishStatus } = useIntlayer("my_key");
252
+
253
+ return (
254
+ <div>
255
+ <p>{publishStatus("draft")}</p>
256
+ <p>{publishStatus("published")}</p>
257
+ </div>
258
+ );
259
+ };
260
+
261
+ export default PostStatus;
262
+ ```
263
+
264
+ </Tab>
265
+ <Tab label="Angular" value="angular">
266
+
267
+ To utilise select content in Angular components, fetch the content via the `useIntlayer` hook. Here's an example:
268
+
269
+ ```typescript fileName="app.component.ts" codeFormat="typescript"
270
+ import { Component } from "@angular/core";
271
+ import { useIntlayer } from "angular-intlayer";
272
+
273
+ @Component({
274
+ selector: "app-post-status",
275
+ template: `
276
+ <div>
277
+ <p>{{ content().publishStatus("draft") }}</p>
278
+ <p>{{ content().publishStatus("published") }}</p>
279
+ </div>
280
+ `,
281
+ })
282
+ export class PostStatusComponent {
283
+ content = useIntlayer("my_key");
284
+ }
285
+ ```
286
+
287
+ </Tab>
288
+ <Tab label="Vanilla JS" value="vanilla">
289
+
290
+ To utilise select content with `vanilla-intlayer`, fetch the content via the `useIntlayer` function. Here's an example:
291
+
292
+ ```typescript fileName="**/*.ts" codeFormat={["typescript", "esm"]}
293
+ import { installIntlayer, useIntlayer } from "vanilla-intlayer";
294
+
295
+ installIntlayer();
296
+
297
+ const content = useIntlayer("my_key").onChange((newContent) => {
298
+ document.getElementById("status")!.textContent =
299
+ newContent.publishStatus("draft");
300
+ });
301
+
302
+ // Initial render
303
+ document.getElementById("status")!.textContent = content.publishStatus("draft");
304
+ ```
305
+
306
+ </Tab>
307
+ </Tabs>
308
+
309
+ ## Composing Select with Other Nodes
310
+
311
+ Because each case is housing a complete content node, `select` can be combined with `t()`, `insert()`, `md()`, etc.:
312
+
313
+ ```typescript fileName="**/*.content.ts" codeFormat="typescript"
314
+ import { insert, select, t, type Dictionary } from "intlayer";
315
+
316
+ const myPostContent = {
317
+ key: "my_key",
318
+ content: {
319
+ publishStatus: select({
320
+ draft: insert(
321
+ t({
322
+ en: "{{name}} saved a draft",
323
+ "en-GB": "{{name}} saved a draft",
324
+ fr: "{{name}} a enregistré un brouillon",
325
+ })
326
+ ),
327
+ published: insert(
328
+ t({
329
+ en: "{{name}} published the post",
330
+ "en-GB": "{{name}} published the post",
331
+ fr: "{{name}} a publié l’article",
332
+ })
333
+ ),
334
+ fallback: insert(
335
+ t({
336
+ en: "{{name}} updated the post",
337
+ "en-GB": "{{name}} updated the post",
338
+ fr: "{{name}} a mis à jour l’article",
339
+ })
340
+ ),
341
+ }),
342
+ },
343
+ } satisfies Dictionary;
344
+
345
+ export default myPostContent;
346
+ ```
347
+
348
+ ```tsx
349
+ publishStatus("draft")({ name: "Alice" }); // Output: Alice saved a draft
350
+ ```
351
+
352
+ ## Migrating from ICU `select`
353
+
354
+ Messages using the ICU `select` argument are imported as a `select` node:
355
+
356
+ ```text
357
+ {publishType, select, draft {draft} published {published} other {Unknown}}
358
+ ```
359
+
360
+ Will become:
361
+
362
+ ```typescript
363
+ select(
364
+ {
365
+ draft: "draft",
366
+ published: "published",
367
+ fallback: "Unknown",
368
+ },
369
+ "publishType"
370
+ );
371
+ ```
372
+
373
+ The ICU `other` case is renamed to `fallback`, which is the Intlayer canonical name for all catch-all cases. The second argument holds the ICU variable name so that when exported, the message reverts back to the exact same ICU string.
374
+
375
+ > Please note that ICU `select` messages where the cases are gender values (`male` / `female` / `other`) are imported as a [`gender`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/dictionary/gender.md) node instead.
376
+
377
+ ## Additional Resources
378
+
379
+ For more detailed information on configuration and usage, please refer to the following resources:
380
+
381
+ - [Intlayer CLI Documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/cli/index.md)
382
+ - [Intlayer React Documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_with_create_react_app.md)
383
+ - [Intlayer Next.js Documentation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/intlayer_with_nextjs_15.md)
384
+
385
+ These resources provide further insights into setting up and using Intlayer across various environments and frameworks.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  createdAt: 2025-02-07
3
- updatedAt: 2026-05-12
3
+ updatedAt: 2026-07-30
4
4
  title: Archivo de Contenido
5
5
  description: Aprende a personalizar las extensiones para tus archivos de declaración de contenido. Sigue esta documentación para implementar condiciones de manera eficiente en tu proyecto.
6
6
  keywords:
@@ -12,6 +12,9 @@ slugs:
12
12
  - concept
13
13
  - content
14
14
  history:
15
+ - version: 9.1.0
16
+ date: 2026-07-30
17
+ changes: "Introducir contenido basado en selección"
15
18
  - version: 8.10.0
16
19
  date: 2026-05-19
17
20
  changes: "Añadir soporte para formatos de archivo YAML y Markdown"
@@ -256,6 +259,7 @@ Intlayer soporta varios tipos de contenido a través de nodos tipados:
256
259
  - **Contenido HTML**: Contenido HTML enriquecido con componentes personalizados opcionales [ver Contenido HTML](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/html.md)
257
260
  - **Contenido Anidado**: Referencias a otros diccionarios [ver Contenido Anidado](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/nested_content.md)
258
261
  - **Contenido de Género**: Contenido que varía según el género [ver Contenido de Género](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/gender_content.md)
262
+ - **Contenido Basado en Selección**: Contenido que varía según un valor de cadena arbitrario [ver Contenido Basado en Selección](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/select.md)
259
263
  - **Contenido de Archivo**: Referencias a archivos externos [ver Contenido de Archivo](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/file_content.md)
260
264
 
261
265
  ## Estructura del Diccionario
@@ -745,6 +749,25 @@ genderContent: gender({
745
749
 
746
750
  > Ver [Contenido según género (`gender`) Doc](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/gender.md) para más información.
747
751
 
752
+ ### Contenido Basado en Selección (`select`)
753
+
754
+ Contenido que varía según un valor de cadena arbitrario — el equivalente a `select` de ICU:
755
+
756
+ ```typescript
757
+ import { select } from "intlayer";
758
+
759
+ selectContent: select({
760
+ draft: "This post is a draft",
761
+ published: "This post is live",
762
+ scheduled: "This post is scheduled",
763
+ fallback: "Unknown status",
764
+ });
765
+ ```
766
+
767
+ Usa `select` cuando el discriminante no es una cantidad (`enu`), ni un booleano (`cond`), ni un género (`gender`). Prefiérelo antes que indexar un objeto simple con un valor de tiempo de ejecución: el compilador de Intlayer no puede resolver estáticamente un acceso computado dinámico.
768
+
769
+ > Ver [Contenido Basado en Selección](https://github.com/aymericzip/intlayer/blob/main/docs/docs/es/dictionary/select.md) para más información.
770
+
748
771
  ### Contenido de archivo (`file`)
749
772
 
750
773
  Referencias a archivos externos: