@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.
- 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,271 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-12
|
|
4
|
-
title: Dynamic Records
|
|
5
|
-
description: Use the meta field in Intlayer content files to declare CMS-managed records fetched at runtime by an opaque ID, enabling strongly-typed dynamic content without build-time enumeration.
|
|
6
|
-
keywords:
|
|
7
|
-
- Dynamic Records
|
|
8
|
-
- Dynamic Content
|
|
9
|
-
- CMS
|
|
10
|
-
- Runtime Content
|
|
11
|
-
- Intlayer
|
|
12
|
-
- Internationalization
|
|
13
|
-
slugs:
|
|
14
|
-
- doc
|
|
15
|
-
- concept
|
|
16
|
-
- dynamic-records
|
|
17
|
-
history:
|
|
18
|
-
- version: 9.0.0
|
|
19
|
-
date: 2026-06-12
|
|
20
|
-
changes: "Release of the dynamic content feature"
|
|
21
|
-
author: aymericzip
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Dynamic Records
|
|
25
|
-
|
|
26
|
-
A **dynamic record** is a content file whose identity is not a sequential index or a named variant, but an arbitrary set of key-value pairs declared in a `meta` field. Intlayer uses those fields as the selector at runtime, making it possible to address CMS records, user-specific copy, or any content whose keys are not known at build time.
|
|
27
|
-
|
|
28
|
-
## Declaring dynamic records
|
|
29
|
-
|
|
30
|
-
```ts fileName="product-copy.abc.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
31
|
-
import { t, type Dictionary } from "intlayer";
|
|
32
|
-
|
|
33
|
-
const dictionary = {
|
|
34
|
-
key: "product-copy",
|
|
35
|
-
meta: {
|
|
36
|
-
id: "prod_abc",
|
|
37
|
-
userId: "user_123",
|
|
38
|
-
},
|
|
39
|
-
content: {
|
|
40
|
-
name: t({ en: "Widget Pro", fr: "Widget Pro" }),
|
|
41
|
-
description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
|
|
42
|
-
},
|
|
43
|
-
} satisfies Dictionary;
|
|
44
|
-
|
|
45
|
-
export default dictionary;
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```ts fileName="product-copy.abcd.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
49
|
-
import { t, type Dictionary } from "intlayer";
|
|
50
|
-
|
|
51
|
-
const dictionary = {
|
|
52
|
-
key: "product-copy",
|
|
53
|
-
meta: {
|
|
54
|
-
id: "prod_abcd",
|
|
55
|
-
userId: "user_123",
|
|
56
|
-
},
|
|
57
|
-
content: {
|
|
58
|
-
name: t({ en: "Widget Lite", fr: "Widget Lite" }),
|
|
59
|
-
description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
|
|
60
|
-
},
|
|
61
|
-
} satisfies Dictionary;
|
|
62
|
-
|
|
63
|
-
export default dictionary;
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Consuming dynamic records
|
|
67
|
-
|
|
68
|
-
All `meta` fields are **required** in the selector. Omitting any field returns `null` and is a TypeScript error.
|
|
69
|
-
|
|
70
|
-
<Tabs group="framework">
|
|
71
|
-
<Tab label="React" value="react">
|
|
72
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
73
|
-
import { useIntlayer } from "react-intlayer";
|
|
74
|
-
|
|
75
|
-
export const ProductCopy = ({
|
|
76
|
-
productId,
|
|
77
|
-
userId,
|
|
78
|
-
}: {
|
|
79
|
-
productId: string;
|
|
80
|
-
userId: string;
|
|
81
|
-
}) => {
|
|
82
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
83
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
84
|
-
|
|
85
|
-
if (!content) return null;
|
|
86
|
-
|
|
87
|
-
return <p>{content.description}</p>;
|
|
88
|
-
};
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
</Tab>
|
|
92
|
-
<Tab label="Next.js" value="nextjs">
|
|
93
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
94
|
-
import { useIntlayer } from "next-intlayer";
|
|
95
|
-
|
|
96
|
-
export const ProductCopy = ({
|
|
97
|
-
productId,
|
|
98
|
-
userId,
|
|
99
|
-
}: {
|
|
100
|
-
productId: string;
|
|
101
|
-
userId: string;
|
|
102
|
-
}) => {
|
|
103
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
104
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
105
|
-
|
|
106
|
-
if (!content) return null;
|
|
107
|
-
|
|
108
|
-
return <p>{content.description}</p>;
|
|
109
|
-
};
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
</Tab>
|
|
113
|
-
<Tab label="Vue" value="vue">
|
|
114
|
-
```vue fileName="ProductCopy.vue" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
115
|
-
<script setup>
|
|
116
|
-
import { useIntlayer } from "vue-intlayer";
|
|
117
|
-
|
|
118
|
-
const props = defineProps({
|
|
119
|
-
productId: String,
|
|
120
|
-
userId: String,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const content = useIntlayer("product-copy", { id: props.productId, userId: props.userId });
|
|
124
|
-
</script>
|
|
125
|
-
|
|
126
|
-
<template>
|
|
127
|
-
<p v-if="content">{{ content.description }}</p>
|
|
128
|
-
</template>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
</Tab>
|
|
132
|
-
<Tab label="Svelte" value="svelte">
|
|
133
|
-
```svelte fileName="ProductCopy.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
134
|
-
<script lang="ts">
|
|
135
|
-
import { useIntlayer } from "svelte-intlayer";
|
|
136
|
-
|
|
137
|
-
export let productId: string;
|
|
138
|
-
export let userId: string;
|
|
139
|
-
|
|
140
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
141
|
-
</script>
|
|
142
|
-
|
|
143
|
-
{#if $content}
|
|
144
|
-
<p>{$content.description}</p>
|
|
145
|
-
{/if}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
</Tab>
|
|
149
|
-
<Tab label="Preact" value="preact">
|
|
150
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
151
|
-
import { useIntlayer } from "preact-intlayer";
|
|
152
|
-
|
|
153
|
-
export const ProductCopy = ({
|
|
154
|
-
productId,
|
|
155
|
-
userId,
|
|
156
|
-
}: {
|
|
157
|
-
productId: string;
|
|
158
|
-
userId: string;
|
|
159
|
-
}) => {
|
|
160
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
161
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
162
|
-
|
|
163
|
-
if (!content) return null;
|
|
164
|
-
|
|
165
|
-
return <p>{content.description}</p>;
|
|
166
|
-
};
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
</Tab>
|
|
170
|
-
<Tab label="Solid" value="solid">
|
|
171
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
172
|
-
import { useIntlayer } from "solid-intlayer";
|
|
173
|
-
|
|
174
|
-
export const ProductCopy = (props: {
|
|
175
|
-
productId: string;
|
|
176
|
-
userId: string;
|
|
177
|
-
}) => {
|
|
178
|
-
const content = useIntlayer("product-copy", { id: props.productId, userId: props.userId });
|
|
179
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<>
|
|
183
|
-
{content() && <p>{content().description}</p>}
|
|
184
|
-
</>
|
|
185
|
-
);
|
|
186
|
-
};
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
</Tab>
|
|
190
|
-
<Tab label="Angular" value="angular">
|
|
191
|
-
```typescript fileName="product-copy.component.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
192
|
-
import { Component, Input, OnInit } from "@angular/core";
|
|
193
|
-
import { useIntlayer } from "angular-intlayer";
|
|
194
|
-
|
|
195
|
-
@Component({
|
|
196
|
-
selector: "app-product-copy",
|
|
197
|
-
template: `
|
|
198
|
-
@if (content()) {
|
|
199
|
-
<p>{{ content().description }}</p>
|
|
200
|
-
}
|
|
201
|
-
`,
|
|
202
|
-
})
|
|
203
|
-
export class ProductCopyComponent implements OnInit {
|
|
204
|
-
@Input() productId!: string;
|
|
205
|
-
@Input() userId!: string;
|
|
206
|
-
|
|
207
|
-
content: any;
|
|
208
|
-
|
|
209
|
-
ngOnInit() {
|
|
210
|
-
this.content = useIntlayer("product-copy", { id: this.productId, userId: this.userId });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
</Tab>
|
|
216
|
-
<Tab label="Vanilla JS" value="vanilla">
|
|
217
|
-
```javascript fileName="product-copy.js"
|
|
218
|
-
import { useIntlayer } from "vanilla-intlayer";
|
|
219
|
-
|
|
220
|
-
const content = useIntlayer("product-copy", {
|
|
221
|
-
id: "prod_abcd",
|
|
222
|
-
userId: "user_123"
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (content) {
|
|
226
|
-
document.body.innerHTML = `<p>${content.description}</p>`;
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
</Tab>
|
|
231
|
-
</Tabs>
|
|
232
|
-
|
|
233
|
-
### With explicit locale
|
|
234
|
-
|
|
235
|
-
```tsx
|
|
236
|
-
const content = useIntlayer("product-copy", {
|
|
237
|
-
id: "prod_abc",
|
|
238
|
-
userId: "user_123",
|
|
239
|
-
locale: "fr",
|
|
240
|
-
});
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Missing meta field — compile-time error
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
// Type error: `userId` is missing
|
|
247
|
-
const content = useIntlayer("product-copy", { id: "prod_abc" });
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Loading mode
|
|
251
|
-
|
|
252
|
-
Dynamic records are typically loaded lazily. Set `importMode` on the dictionary to control this:
|
|
253
|
-
|
|
254
|
-
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
255
|
-
const dictionary = {
|
|
256
|
-
key: "product-copy",
|
|
257
|
-
importMode: "fetch", // or "dynamic"
|
|
258
|
-
meta: { id: "prod_abc", userId: "user_123" },
|
|
259
|
-
content: { … },
|
|
260
|
-
} satisfies Dictionary;
|
|
261
|
-
|
|
262
|
-
export default dictionary;
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
See [bundle optimization](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/bundle_optimization.md) for details on `static`, `dynamic`, and `fetch` modes.
|
|
266
|
-
|
|
267
|
-
## Typical use-cases
|
|
268
|
-
|
|
269
|
-
- Per-product marketing copy managed in a CMS
|
|
270
|
-
- User-specific or account-specific content
|
|
271
|
-
- Any content keyed by an opaque runtime ID
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-12
|
|
4
|
-
title: Dynamic Records
|
|
5
|
-
description: Use the meta field in Intlayer content files to declare CMS-managed records fetched at runtime by an opaque ID, enabling strongly-typed dynamic content without build-time enumeration.
|
|
6
|
-
keywords:
|
|
7
|
-
- Dynamic Records
|
|
8
|
-
- Dynamic Content
|
|
9
|
-
- CMS
|
|
10
|
-
- Runtime Content
|
|
11
|
-
- Intlayer
|
|
12
|
-
- Internationalisation
|
|
13
|
-
slugs:
|
|
14
|
-
- doc
|
|
15
|
-
- concept
|
|
16
|
-
- dynamic-records
|
|
17
|
-
history:
|
|
18
|
-
- version: 9.0.0
|
|
19
|
-
date: 2026-06-12
|
|
20
|
-
changes: "Release of the dynamic content feature"
|
|
21
|
-
author: aymericzip
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Dynamic Records
|
|
25
|
-
|
|
26
|
-
A **dynamic record** is a content file whose identity is not a sequential index or a named variant, but an arbitrary set of key-value pairs declared in a `meta` field. Intlayer uses those fields as the selector at runtime, making it possible to address CMS records, user-specific copy, or any content whose keys are not known at build time.
|
|
27
|
-
|
|
28
|
-
## Declaring dynamic records
|
|
29
|
-
|
|
30
|
-
```ts fileName="product-copy.abc.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
31
|
-
import { t, type Dictionary } from "intlayer";
|
|
32
|
-
|
|
33
|
-
const dictionary = {
|
|
34
|
-
key: "product-copy",
|
|
35
|
-
meta: {
|
|
36
|
-
id: "prod_abc",
|
|
37
|
-
userId: "user_123",
|
|
38
|
-
},
|
|
39
|
-
content: {
|
|
40
|
-
name: t({ en: "Widget Pro", fr: "Widget Pro" }),
|
|
41
|
-
description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
|
|
42
|
-
},
|
|
43
|
-
} satisfies Dictionary;
|
|
44
|
-
|
|
45
|
-
export default dictionary;
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```ts fileName="product-copy.abcd.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
49
|
-
import { t, type Dictionary } from "intlayer";
|
|
50
|
-
|
|
51
|
-
const dictionary = {
|
|
52
|
-
key: "product-copy",
|
|
53
|
-
meta: {
|
|
54
|
-
id: "prod_abcd",
|
|
55
|
-
userId: "user_123",
|
|
56
|
-
},
|
|
57
|
-
content: {
|
|
58
|
-
name: t({ en: "Widget Lite", fr: "Widget Lite" }),
|
|
59
|
-
description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
|
|
60
|
-
},
|
|
61
|
-
} satisfies Dictionary;
|
|
62
|
-
|
|
63
|
-
export default dictionary;
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Consuming dynamic records
|
|
67
|
-
|
|
68
|
-
All `meta` fields are **required** in the selector. Omitting any field returns `null` and is a TypeScript error.
|
|
69
|
-
|
|
70
|
-
<Tabs group="framework">
|
|
71
|
-
<Tab label="React" value="react">
|
|
72
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
73
|
-
import { useIntlayer } from "react-intlayer";
|
|
74
|
-
|
|
75
|
-
export const ProductCopy = ({
|
|
76
|
-
productId,
|
|
77
|
-
userId,
|
|
78
|
-
}: {
|
|
79
|
-
productId: string;
|
|
80
|
-
userId: string;
|
|
81
|
-
}) => {
|
|
82
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
83
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
84
|
-
|
|
85
|
-
if (!content) return null;
|
|
86
|
-
|
|
87
|
-
return <p>{content.description}</p>;
|
|
88
|
-
};
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
</Tab>
|
|
92
|
-
<Tab label="Next.js" value="nextjs">
|
|
93
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
94
|
-
import { useIntlayer } from "next-intlayer";
|
|
95
|
-
|
|
96
|
-
export const ProductCopy = ({
|
|
97
|
-
productId,
|
|
98
|
-
userId,
|
|
99
|
-
}: {
|
|
100
|
-
productId: string;
|
|
101
|
-
userId: string;
|
|
102
|
-
}) => {
|
|
103
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
104
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
105
|
-
|
|
106
|
-
if (!content) return null;
|
|
107
|
-
|
|
108
|
-
return <p>{content.description}</p>;
|
|
109
|
-
};
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
</Tab>
|
|
113
|
-
<Tab label="Vue" value="vue">
|
|
114
|
-
```vue fileName="ProductCopy.vue" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
115
|
-
<script setup>
|
|
116
|
-
import { useIntlayer } from "vue-intlayer";
|
|
117
|
-
|
|
118
|
-
const props = defineProps({
|
|
119
|
-
productId: String,
|
|
120
|
-
userId: String,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
const content = useIntlayer("product-copy", { id: props.productId, userId: props.userId });
|
|
124
|
-
</script>
|
|
125
|
-
|
|
126
|
-
<template>
|
|
127
|
-
<p v-if="content">{{ content.description }}</p>
|
|
128
|
-
</template>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
</Tab>
|
|
132
|
-
<Tab label="Svelte" value="svelte">
|
|
133
|
-
```svelte fileName="ProductCopy.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
134
|
-
<script lang="ts">
|
|
135
|
-
import { useIntlayer } from "svelte-intlayer";
|
|
136
|
-
|
|
137
|
-
export let productId: string;
|
|
138
|
-
export let userId: string;
|
|
139
|
-
|
|
140
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
141
|
-
</script>
|
|
142
|
-
|
|
143
|
-
{#if $content}
|
|
144
|
-
<p>{$content.description}</p>
|
|
145
|
-
{/if}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
</Tab>
|
|
149
|
-
<Tab label="Preact" value="preact">
|
|
150
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
151
|
-
import { useIntlayer } from "preact-intlayer";
|
|
152
|
-
|
|
153
|
-
export const ProductCopy = ({
|
|
154
|
-
productId,
|
|
155
|
-
userId,
|
|
156
|
-
}: {
|
|
157
|
-
productId: string;
|
|
158
|
-
userId: string;
|
|
159
|
-
}) => {
|
|
160
|
-
const content = useIntlayer("product-copy", { id: productId, userId });
|
|
161
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
162
|
-
|
|
163
|
-
if (!content) return null;
|
|
164
|
-
|
|
165
|
-
return <p>{content.description}</p>;
|
|
166
|
-
};
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
</Tab>
|
|
170
|
-
<Tab label="Solid" value="solid">
|
|
171
|
-
```tsx fileName="ProductCopy.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
172
|
-
import { useIntlayer } from "solid-intlayer";
|
|
173
|
-
|
|
174
|
-
export const ProductCopy = (props: {
|
|
175
|
-
productId: string;
|
|
176
|
-
userId: string;
|
|
177
|
-
}) => {
|
|
178
|
-
const content = useIntlayer("product-copy", { id: props.productId, userId: props.userId });
|
|
179
|
-
// TypeScript enforces that both `id` and `userId` are provided.
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<>
|
|
183
|
-
{content() && <p>{content().description}</p>}
|
|
184
|
-
</>
|
|
185
|
-
);
|
|
186
|
-
};
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
</Tab>
|
|
190
|
-
<Tab label="Angular" value="angular">
|
|
191
|
-
```typescript fileName="product-copy.component.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
192
|
-
import { Component, Input, OnInit } from "@angular/core";
|
|
193
|
-
import { useIntlayer } from "angular-intlayer";
|
|
194
|
-
|
|
195
|
-
@Component({
|
|
196
|
-
selector: "app-product-copy",
|
|
197
|
-
template: `
|
|
198
|
-
@if (content()) {
|
|
199
|
-
<p>{{ content().description }}</p>
|
|
200
|
-
}
|
|
201
|
-
`,
|
|
202
|
-
})
|
|
203
|
-
export class ProductCopyComponent implements OnInit {
|
|
204
|
-
@Input() productId!: string;
|
|
205
|
-
@Input() userId!: string;
|
|
206
|
-
|
|
207
|
-
content: any;
|
|
208
|
-
|
|
209
|
-
ngOnInit() {
|
|
210
|
-
this.content = useIntlayer("product-copy", { id: this.productId, userId: this.userId });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
</Tab>
|
|
216
|
-
<Tab label="Vanilla JS" value="vanilla">
|
|
217
|
-
```javascript fileName="product-copy.js"
|
|
218
|
-
import { useIntlayer } from "vanilla-intlayer";
|
|
219
|
-
|
|
220
|
-
const content = useIntlayer("product-copy", {
|
|
221
|
-
id: "prod_abcd",
|
|
222
|
-
userId: "user_123"
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (content) {
|
|
226
|
-
document.body.innerHTML = `<p>${content.description}</p>`;
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
</Tab>
|
|
231
|
-
</Tabs>
|
|
232
|
-
|
|
233
|
-
### With explicit locale
|
|
234
|
-
|
|
235
|
-
```tsx
|
|
236
|
-
const content = useIntlayer("product-copy", {
|
|
237
|
-
id: "prod_abc",
|
|
238
|
-
userId: "user_123",
|
|
239
|
-
locale: "fr",
|
|
240
|
-
});
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Missing meta field — compile-time error
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
// Type error: `userId` is missing
|
|
247
|
-
const content = useIntlayer("product-copy", { id: "prod_abc" });
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Loading mode
|
|
251
|
-
|
|
252
|
-
Dynamic records are typically loaded lazily. Set `importMode` on the dictionary to control this:
|
|
253
|
-
|
|
254
|
-
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
255
|
-
const dictionary = {
|
|
256
|
-
key: "product-copy",
|
|
257
|
-
importMode: "fetch", // or "dynamic"
|
|
258
|
-
meta: { id: "prod_abc", userId: "user_123" },
|
|
259
|
-
content: { … },
|
|
260
|
-
} satisfies Dictionary;
|
|
261
|
-
|
|
262
|
-
export default dictionary;
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
See [bundle optimisation](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en-GB/bundle_optimization.md) for details on `static`, `dynamic`, and `fetch` modes.
|
|
266
|
-
|
|
267
|
-
## Typical use-cases
|
|
268
|
-
|
|
269
|
-
- Per-product marketing copy managed in a CMS
|
|
270
|
-
- User-specific or account-specific content
|
|
271
|
-
- Any content keyed by an opaque runtime ID
|