@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: Bản Ghi Động
|
|
5
|
-
description: Sử dụng trường meta trong các tệp nội dung Intlayer để khai báo các bản ghi do CMS quản lý được truy xuất tại runtime bằng ID ẩn, cho phép nội dung động có kiểu dữ liệu mạnh mẽ (strongly-typed) mà không cần đếm tại thời điểm build.
|
|
6
|
-
keywords:
|
|
7
|
-
- Bản Ghi Động
|
|
8
|
-
- Nội Dung Động
|
|
9
|
-
- CMS
|
|
10
|
-
- Nội Dung Runtime
|
|
11
|
-
- Intlayer
|
|
12
|
-
- Quốc tế hóa
|
|
13
|
-
slugs:
|
|
14
|
-
- doc
|
|
15
|
-
- concept
|
|
16
|
-
- dynamic-records
|
|
17
|
-
history:
|
|
18
|
-
- version: 9.0.0
|
|
19
|
-
date: 2026-06-12
|
|
20
|
-
changes: "Phát hành tính năng nội dung động"
|
|
21
|
-
author: aymericzip
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Bản Ghi Động
|
|
25
|
-
|
|
26
|
-
Một **bản ghi động** (dynamic record) là một tệp nội dung có danh tính không phải là một chỉ mục tuần tự hoặc một biến thể có tên, mà là một tập hợp tùy ý gồm các cặp khóa-giá trị được khai báo trong trường `meta`. Intlayer sử dụng các trường đó làm bộ chọn tại runtime, giúp có thể định địa chỉ các bản ghi CMS, nội dung dành riêng cho người dùng hoặc bất kỳ nội dung nào có khóa không được biết tại thời điểm build.
|
|
27
|
-
|
|
28
|
-
## Khai báo các bản ghi động
|
|
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
|
-
## Sử dụng bản ghi động
|
|
67
|
-
|
|
68
|
-
Tất cả các trường `meta` đều **bắt buộc** trong bộ chọn. Việc bỏ qua bất kỳ trường nào sẽ trả về `null` và gây ra lỗi TypeScript.
|
|
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 đảm bảo rằng cả `id` và `userId` đều được cung cấp.
|
|
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 đảm bảo rằng cả `id` và `userId` đều được cung cấp.
|
|
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 đảm bảo rằng cả `id` và `userId` đều được cung cấp.
|
|
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 đảm bảo rằng cả `id` và `userId` đều được cung cấp.
|
|
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
|
-
### Với ngôn ngữ rõ ràng
|
|
234
|
-
|
|
235
|
-
```tsx
|
|
236
|
-
const content = useIntlayer("product-copy", {
|
|
237
|
-
id: "prod_abc",
|
|
238
|
-
userId: "user_123",
|
|
239
|
-
locale: "vi",
|
|
240
|
-
});
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Thiếu trường meta — lỗi compile-time
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
// Lỗi kiểu dữ liệu: thiếu `userId`
|
|
247
|
-
const content = useIntlayer("product-copy", { id: "prod_abc" });
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## Chế độ tải (loading mode)
|
|
251
|
-
|
|
252
|
-
Các bản ghi động thường được tải lười (lazy loaded). Hãy thiết lập `importMode` trên từ điển để kiểm soát điều này:
|
|
253
|
-
|
|
254
|
-
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
255
|
-
const dictionary = {
|
|
256
|
-
key: "product-copy",
|
|
257
|
-
importMode: "fetch", // hoặc "dynamic"
|
|
258
|
-
meta: { id: "prod_abc", userId: "user_123" },
|
|
259
|
-
content: { … },
|
|
260
|
-
} satisfies Dictionary;
|
|
261
|
-
|
|
262
|
-
export default dictionary;
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Xem [tối ưu hóa gói bundle](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/bundle_optimization.md) để biết thêm chi tiết về chế độ `static`, `dynamic` và `fetch`.
|
|
266
|
-
|
|
267
|
-
## Các trường hợp sử dụng điển hình
|
|
268
|
-
|
|
269
|
-
- Nội dung tiếp thị trên mỗi sản phẩm được quản lý trong CMS
|
|
270
|
-
- Nội dung dành riêng cho người dùng hoặc tài khoản cụ thể
|
|
271
|
-
- Bất kỳ nội dung nào được xác định bằng một ID runtime ẩn
|
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-12
|
|
4
|
-
title: 动态记录
|
|
5
|
-
description: 在 Intlayer 内容文件中使用 meta 字段来声明在运行时通过不透明 ID 获取的 CMS 管理记录,从而实现强类型的动态内容,而无需在构建时进行枚举。
|
|
6
|
-
keywords:
|
|
7
|
-
- 动态记录
|
|
8
|
-
- 动态内容
|
|
9
|
-
- CMS
|
|
10
|
-
- 运行时内容
|
|
11
|
-
- Intlayer
|
|
12
|
-
- 国际化
|
|
13
|
-
slugs:
|
|
14
|
-
- doc
|
|
15
|
-
- concept
|
|
16
|
-
- dynamic-records
|
|
17
|
-
history:
|
|
18
|
-
- version: 9.0.0
|
|
19
|
-
date: 2026-06-12
|
|
20
|
-
changes: "发布动态内容功能"
|
|
21
|
-
author: aymericzip
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# 动态记录
|
|
25
|
-
|
|
26
|
-
**动态记录**(dynamic record)是指其唯一身份标识不是顺序索引或命名变体,而是在 `meta` 字段中声明的任意键值对集合的内容文件。Intlayer 将在运行时使用这些字段作为选择器,从而可以定位 CMS 记录、用户特定文案或任何在构建时未知其键的内容。
|
|
27
|
-
|
|
28
|
-
## 声明动态记录
|
|
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
|
-
## 使用动态记录
|
|
67
|
-
|
|
68
|
-
选择器中所有的 `meta` 字段都是**必填**的。省略任何字段都将返回 `null` 并导致 TypeScript 报错。
|
|
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 会强制要求同时提供 `id` 和 `userId`。
|
|
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 会强制要求同时提供 `id` 和 `userId`。
|
|
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 会强制要求同时提供 `id` 和 `userId`。
|
|
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 会强制要求同时提供 `id` 和 `userId`。
|
|
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
|
-
### 使用显式语言环境
|
|
234
|
-
|
|
235
|
-
```tsx
|
|
236
|
-
const content = useIntlayer("product-copy", {
|
|
237
|
-
id: "prod_abc",
|
|
238
|
-
userId: "user_123",
|
|
239
|
-
locale: "zh",
|
|
240
|
-
});
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### 缺少 meta 字段 — 编译时错误
|
|
244
|
-
|
|
245
|
-
```ts
|
|
246
|
-
// 类型错误:缺少 `userId`
|
|
247
|
-
const content = useIntlayer("product-copy", { id: "prod_abc" });
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
## 加载模式 (loading mode)
|
|
251
|
-
|
|
252
|
-
动态记录通常采用延迟加载方式。在字典中设置 `importMode` 来控制此行为:
|
|
253
|
-
|
|
254
|
-
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
255
|
-
const dictionary = {
|
|
256
|
-
key: "product-copy",
|
|
257
|
-
importMode: "fetch", // 或 "dynamic"
|
|
258
|
-
meta: { id: "prod_abc", userId: "user_123" },
|
|
259
|
-
content: { … },
|
|
260
|
-
} satisfies Dictionary;
|
|
261
|
-
|
|
262
|
-
export default dictionary;
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
关于 `static`、`dynamic` 和 `fetch` 模式的详细信息,请参阅[分包优化](https://github.com/aymericzip/intlayer/blob/main/docs/docs/zh/bundle_optimization.md)。
|
|
266
|
-
|
|
267
|
-
## 典型使用场景
|
|
268
|
-
|
|
269
|
-
- 在 CMS 中管理的单件商品营销文案
|
|
270
|
-
- 用户特定或账户特定的内容
|
|
271
|
-
- 在运行时通过不透明 ID 标识的任何内容
|