@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,13 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: バリアント
|
|
5
|
-
description:
|
|
5
|
+
description: Intlayer のコンテンツファイルで variant メタデータフィールドを使用し、名前付きまたは構造化されたコンテンツの代替(A/B テスト、季節バナー、フィーチャーフラグ付きコピー、CMS レコード、ユーザー固有コンテンツ)を宣言し、コード変更なしにランタイムで切り替えます。
|
|
6
6
|
keywords:
|
|
7
7
|
- バリアント
|
|
8
|
-
- A/Bテスト
|
|
9
|
-
-
|
|
8
|
+
- A/B テスト
|
|
9
|
+
- フィーチャーフラグ
|
|
10
10
|
- 動的コンテンツ
|
|
11
|
+
- 動的レコード
|
|
12
|
+
- CMS
|
|
11
13
|
- Intlayer
|
|
12
14
|
- 国際化
|
|
13
15
|
slugs:
|
|
@@ -17,17 +19,27 @@ slugs:
|
|
|
17
19
|
history:
|
|
18
20
|
- version: 9.0.0
|
|
19
21
|
date: 2026-06-12
|
|
20
|
-
changes: "
|
|
22
|
+
changes: "バリアント機能のリリース"
|
|
23
|
+
- version: 9.1.0
|
|
24
|
+
date: 2026-06-26
|
|
25
|
+
changes: "`variant` が文字列またはオブジェクトを受け取るようになりました — 旧 `meta` / 動的レコードはオブジェクトバリアントとして宣言します"
|
|
21
26
|
author: aymericzip
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
# バリアント
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
**バリアント**は、同じ辞書 `key` を共有しつつ、それぞれ異なる `variant` 値を持つコンテンツファイルの集合です。Intlayer は `useIntlayer` に渡されたセレクターに基づいて適切なファイルを提供します。
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
`variant` の値は**2 つの形式**を取れます:
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
- **文字列** — 単一の名前付き代替(A/B テスト、季節バナー、フィーチャーフラグ)。
|
|
36
|
+
- **オブジェクト** — フィールドの集合でアドレス指定される構造化された識別子(CMS レコード、ユーザー固有コピー、不透明な ID をキーとする任意のコンテンツ)。オブジェクト全体が同一性です。エントリを解決するには、セレクターが**等しい**オブジェクトを提供する必要があります。
|
|
37
|
+
|
|
38
|
+
> オブジェクト形式は旧 `meta` フィールドを置き換えます。以前 `meta: { id, … }` と書いていた箇所はすべて `variant: { id, … }` と書き、`{ variant: { id, … } }` で選択してください。
|
|
39
|
+
|
|
40
|
+
## 名前付き(文字列)バリアント
|
|
41
|
+
|
|
42
|
+
各ファイルは 1 つの名前付き代替を表します。`variant` を省略する(または `"default"` に設定する)と、フォールバックとして扱われます。
|
|
31
43
|
|
|
32
44
|
```ts fileName="hero-banner.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
33
45
|
import { t, type Dictionary } from "intlayer";
|
|
@@ -65,9 +77,9 @@ const dictionary = {
|
|
|
65
77
|
export default dictionary;
|
|
66
78
|
```
|
|
67
79
|
|
|
68
|
-
|
|
80
|
+
### 名前付きバリアントの利用
|
|
69
81
|
|
|
70
|
-
|
|
82
|
+
#### デフォルトバリアント
|
|
71
83
|
|
|
72
84
|
<Tabs group="framework">
|
|
73
85
|
<Tab label="React" value="react">
|
|
@@ -209,7 +221,7 @@ export default dictionary;
|
|
|
209
221
|
</Tab>
|
|
210
222
|
</Tabs>
|
|
211
223
|
|
|
212
|
-
|
|
224
|
+
#### 名前付きバリアント
|
|
213
225
|
|
|
214
226
|
```tsx
|
|
215
227
|
const { headline, cta } = useIntlayer("hero-banner", {
|
|
@@ -217,18 +229,264 @@ const { headline, cta } = useIntlayer("hero-banner", {
|
|
|
217
229
|
});
|
|
218
230
|
```
|
|
219
231
|
|
|
220
|
-
|
|
232
|
+
#### ロケールを明示した名前付きバリアント
|
|
221
233
|
|
|
222
234
|
```tsx
|
|
223
235
|
const content = useIntlayer("hero-banner", {
|
|
224
236
|
variant: "black_friday",
|
|
225
|
-
locale: "
|
|
237
|
+
locale: "fr",
|
|
226
238
|
});
|
|
227
239
|
```
|
|
228
240
|
|
|
229
|
-
##
|
|
241
|
+
## オブジェクト(構造化)バリアント
|
|
242
|
+
|
|
243
|
+
オブジェクトバリアントは、`variant` フィールドで宣言された任意のキー・値ペアの集合でコンテンツをアドレス指定します。これにより、CMS レコード、ユーザー固有コピー、または不透明な ID をキーとする任意のコンテンツをモデル化できます。**オブジェクト全体**が同一性です。エントリが解決されるには、セレクターが等しいオブジェクトを提供する必要があります。
|
|
244
|
+
|
|
245
|
+
```ts fileName="product.abc.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
246
|
+
import { t, type Dictionary } from "intlayer";
|
|
247
|
+
|
|
248
|
+
const dictionary = {
|
|
249
|
+
key: "product",
|
|
250
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
251
|
+
content: {
|
|
252
|
+
name: t({ en: "Widget Pro", fr: "Widget Pro" }),
|
|
253
|
+
description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
|
|
254
|
+
},
|
|
255
|
+
} satisfies Dictionary;
|
|
256
|
+
|
|
257
|
+
export default dictionary;
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```ts fileName="product.abcd.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
261
|
+
import { t, type Dictionary } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const dictionary = {
|
|
264
|
+
key: "product",
|
|
265
|
+
variant: { id: "prod_abcd", userId: "user_123" },
|
|
266
|
+
content: {
|
|
267
|
+
name: t({ en: "Widget Lite", fr: "Widget Lite" }),
|
|
268
|
+
description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
|
|
269
|
+
},
|
|
270
|
+
} satisfies Dictionary;
|
|
271
|
+
|
|
272
|
+
export default dictionary;
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### オブジェクトバリアントの利用
|
|
276
|
+
|
|
277
|
+
一致するオブジェクトを `variant` に渡します。辞書で宣言された各フィールドはすべて提供され、等しくなければなりません。そうでない場合、結果は `null` です。フィールドの順序は問いません。
|
|
278
|
+
|
|
279
|
+
<Tabs group="framework">
|
|
280
|
+
<Tab label="React" value="react">
|
|
281
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
282
|
+
import { useIntlayer } from "react-intlayer";
|
|
283
|
+
|
|
284
|
+
export const Product = ({
|
|
285
|
+
productId,
|
|
286
|
+
userId,
|
|
287
|
+
}: {
|
|
288
|
+
productId: string;
|
|
289
|
+
userId: string;
|
|
290
|
+
}) => {
|
|
291
|
+
const content = useIntlayer("product", {
|
|
292
|
+
variant: { id: productId, userId },
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
if (!content) return null;
|
|
296
|
+
|
|
297
|
+
return <p>{content.description}</p>;
|
|
298
|
+
};
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
</Tab>
|
|
302
|
+
<Tab label="Next.js" value="nextjs">
|
|
303
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
304
|
+
import { useIntlayer } from "next-intlayer";
|
|
305
|
+
|
|
306
|
+
export const Product = ({
|
|
307
|
+
productId,
|
|
308
|
+
userId,
|
|
309
|
+
}: {
|
|
310
|
+
productId: string;
|
|
311
|
+
userId: string;
|
|
312
|
+
}) => {
|
|
313
|
+
const content = useIntlayer("product", {
|
|
314
|
+
variant: { id: productId, userId },
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
if (!content) return null;
|
|
318
|
+
|
|
319
|
+
return <p>{content.description}</p>;
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
</Tab>
|
|
324
|
+
<Tab label="Vue" value="vue">
|
|
325
|
+
```vue fileName="Product.vue" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
326
|
+
<script setup>
|
|
327
|
+
import { useIntlayer } from "vue-intlayer";
|
|
328
|
+
|
|
329
|
+
const props = defineProps({
|
|
330
|
+
productId: String,
|
|
331
|
+
userId: String,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
const content = useIntlayer("product", {
|
|
335
|
+
variant: { id: props.productId, userId: props.userId },
|
|
336
|
+
});
|
|
337
|
+
</script>
|
|
338
|
+
|
|
339
|
+
<template>
|
|
340
|
+
<p v-if="content">{{ content.description }}</p>
|
|
341
|
+
</template>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
</Tab>
|
|
345
|
+
<Tab label="Svelte" value="svelte">
|
|
346
|
+
```svelte fileName="Product.svelte" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
347
|
+
<script lang="ts">
|
|
348
|
+
import { useIntlayer } from "svelte-intlayer";
|
|
349
|
+
|
|
350
|
+
export let productId: string;
|
|
351
|
+
export let userId: string;
|
|
352
|
+
|
|
353
|
+
const content = useIntlayer("product", {
|
|
354
|
+
variant: { id: productId, userId },
|
|
355
|
+
});
|
|
356
|
+
</script>
|
|
357
|
+
|
|
358
|
+
{#if $content}
|
|
359
|
+
<p>{$content.description}</p>
|
|
360
|
+
{/if}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
</Tab>
|
|
364
|
+
<Tab label="Preact" value="preact">
|
|
365
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
366
|
+
import { useIntlayer } from "preact-intlayer";
|
|
367
|
+
|
|
368
|
+
export const Product = ({
|
|
369
|
+
productId,
|
|
370
|
+
userId,
|
|
371
|
+
}: {
|
|
372
|
+
productId: string;
|
|
373
|
+
userId: string;
|
|
374
|
+
}) => {
|
|
375
|
+
const content = useIntlayer("product", {
|
|
376
|
+
variant: { id: productId, userId },
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if (!content) return null;
|
|
380
|
+
|
|
381
|
+
return <p>{content.description}</p>;
|
|
382
|
+
};
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
</Tab>
|
|
386
|
+
<Tab label="Solid" value="solid">
|
|
387
|
+
```tsx fileName="Product.tsx" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
388
|
+
import { useIntlayer } from "solid-intlayer";
|
|
389
|
+
|
|
390
|
+
export const Product = (props: {
|
|
391
|
+
productId: string;
|
|
392
|
+
userId: string;
|
|
393
|
+
}) => {
|
|
394
|
+
const content = useIntlayer("product", {
|
|
395
|
+
variant: { id: props.productId, userId: props.userId },
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
return (
|
|
399
|
+
<>
|
|
400
|
+
{content() && <p>{content().description}</p>}
|
|
401
|
+
</>
|
|
402
|
+
);
|
|
403
|
+
};
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
</Tab>
|
|
407
|
+
<Tab label="Angular" value="angular">
|
|
408
|
+
```typescript fileName="product.component.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
409
|
+
import { Component, Input, OnInit } from "@angular/core";
|
|
410
|
+
import { useIntlayer } from "angular-intlayer";
|
|
411
|
+
|
|
412
|
+
@Component({
|
|
413
|
+
selector: "app-product",
|
|
414
|
+
template: `
|
|
415
|
+
@if (content()) {
|
|
416
|
+
<p>{{ content().description }}</p>
|
|
417
|
+
}
|
|
418
|
+
`,
|
|
419
|
+
})
|
|
420
|
+
export class ProductComponent implements OnInit {
|
|
421
|
+
@Input() productId!: string;
|
|
422
|
+
@Input() userId!: string;
|
|
423
|
+
|
|
424
|
+
content: any;
|
|
425
|
+
|
|
426
|
+
ngOnInit() {
|
|
427
|
+
this.content = useIntlayer("product", {
|
|
428
|
+
variant: { id: this.productId, userId: this.userId },
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
</Tab>
|
|
435
|
+
<Tab label="Vanilla JS" value="vanilla">
|
|
436
|
+
```javascript fileName="product.js"
|
|
437
|
+
import { useIntlayer } from "vanilla-intlayer";
|
|
438
|
+
|
|
439
|
+
const content = useIntlayer("product", {
|
|
440
|
+
variant: { id: "prod_abcd", userId: "user_123" },
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
if (content) {
|
|
444
|
+
document.body.innerHTML = `<p>${content.description}</p>`;
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
</Tab>
|
|
449
|
+
</Tabs>
|
|
450
|
+
|
|
451
|
+
#### ロケールを明示する場合
|
|
452
|
+
|
|
453
|
+
```tsx
|
|
454
|
+
const content = useIntlayer("product", {
|
|
455
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
456
|
+
locale: "fr",
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### フィールド欠落 — 一致なし
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
// null を返します: `userId` が欠落しているため、オブジェクトは宣言されたバリアントに一致しません
|
|
464
|
+
const content = useIntlayer("product", { variant: { id: "prod_abc" } });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## 読み込みモード
|
|
468
|
+
|
|
469
|
+
オブジェクトバリアントはしばしば遅延読み込みされます。これを制御するには辞書に `importMode` を設定します:
|
|
470
|
+
|
|
471
|
+
```ts contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
472
|
+
const dictionary = {
|
|
473
|
+
key: "product",
|
|
474
|
+
importMode: "fetch", // or "dynamic"
|
|
475
|
+
variant: { id: "prod_abc", userId: "user_123" },
|
|
476
|
+
content: { … },
|
|
477
|
+
} satisfies Dictionary;
|
|
478
|
+
|
|
479
|
+
export default dictionary;
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
`static`、`dynamic`、`fetch` モードの詳細については[バンドル最適化](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/bundle_optimization.md)を参照してください。
|
|
483
|
+
|
|
484
|
+
## 典型的なユースケース
|
|
230
485
|
|
|
231
|
-
-
|
|
232
|
-
-
|
|
233
|
-
-
|
|
234
|
-
-
|
|
486
|
+
- 実験キーで駆動される A/B コピーテスト
|
|
487
|
+
- 季節またはプロモーションのバナー
|
|
488
|
+
- フィーチャーフラグ付きメッセージ
|
|
489
|
+
- ロケール固有のマーケティングキャンペーン
|
|
490
|
+
- CMS で管理される製品ごとのマーケティングコピー
|
|
491
|
+
- ユーザー固有またはアカウント固有のコンテンツ
|
|
492
|
+
- 実行時に不透明な ID をキーとする任意のコンテンツ
|
package/docs/ja/releases/v9.md
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-14
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: Intlayer v9の新機能
|
|
5
|
-
description: Intlayer v9の新機能をご覧ください。主要なi18n
|
|
5
|
+
description: Intlayer v9の新機能をご覧ください。主要なi18nライブラリ向けのドロップイン互換性パッケージと、コレクション、バリアントのサポートを導入します。
|
|
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
|
# Intlayer v9の新機能
|
|
24
23
|
|
|
25
|
-
Intlayer v9へようこそ!このメジャーリリースは、主要なi18nライブラリ(`react-i18next`、`next-intl`、`vue-i18n`など)向けの**互換アダプターパッケージ**により、Intlayer
|
|
24
|
+
Intlayer v9へようこそ!このメジャーリリースは、主要なi18nライブラリ(`react-i18next`、`next-intl`、`vue-i18n`など)向けの**互換アダプターパッケージ**により、Intlayerへの移行パスを簡素化し、**コレクション**、**バリアント**といったリッチなコンテンツ構造のサポートを追加することで、大きな節目となります。
|
|
26
25
|
|
|
27
26
|
## 目次
|
|
28
27
|
|
|
@@ -41,8 +40,10 @@ Intlayer v9へようこそ!このメジャーリリースは、主要なi18n
|
|
|
41
40
|
- `@intlayer/i18next`
|
|
42
41
|
- `@intlayer/react-i18next`
|
|
43
42
|
- `@intlayer/next-intl`
|
|
43
|
+
- `@intlayer/react-intl`
|
|
44
44
|
- `@intlayer/next-i18next`
|
|
45
45
|
- `@intlayer/vue-i18n`
|
|
46
|
+
- `@intlayer/lingui`
|
|
46
47
|
|
|
47
48
|
例えば、次のように変更するだけです。
|
|
48
49
|
|
|
@@ -100,7 +101,7 @@ export default defineConfig({
|
|
|
100
101
|
|
|
101
102
|
---
|
|
102
103
|
|
|
103
|
-
##
|
|
104
|
+
## 機能仕様:コレクション、バリアント
|
|
104
105
|
|
|
105
106
|
Intlayer v9は、静的なキーと値のオブジェクトを超えて拡張され、辞書がエンドツーエンドで完全に型付けされた動的なレイアウト構造を宣言できるようになりました。
|
|
106
107
|
|
|
@@ -144,6 +145,8 @@ const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: s
|
|
|
144
145
|
|
|
145
146
|
A/Bテスト、季節限定ヘッダー、機能フラグ、またはカスタムランディングページを提供します。
|
|
146
147
|
|
|
148
|
+
#### 文字列バリアント(例:A/Bテスト)
|
|
149
|
+
|
|
147
150
|
```ts fileName="hero.content.ts"
|
|
148
151
|
import { t, type Dictionary } from "intlayer";
|
|
149
152
|
|
|
@@ -167,16 +170,14 @@ export default {
|
|
|
167
170
|
const banner = useIntlayer("hero-banner", { variant: "black_friday" });
|
|
168
171
|
```
|
|
169
172
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
クエリIDを介してランタイムで動的にエントリがロードされる辞書を定義します。
|
|
173
|
+
#### オブジェクトバリアント(例:動的レコード)
|
|
173
174
|
|
|
174
175
|
```ts fileName="product.content.ts"
|
|
175
176
|
import { t, type Dictionary } from "intlayer";
|
|
176
177
|
|
|
177
178
|
export default {
|
|
178
179
|
key: "product-copy",
|
|
179
|
-
|
|
180
|
+
variant: {
|
|
180
181
|
id: "prod_123",
|
|
181
182
|
category: "books",
|
|
182
183
|
},
|
|
@@ -229,7 +230,7 @@ export default defineConfig({
|
|
|
229
230
|
});
|
|
230
231
|
```
|
|
231
232
|
|
|
232
|
-
- **Compiler**: `compiler.enabled`
|
|
233
|
+
- **Compiler**: `compiler.enabled` が `true` に設定され、`compiler.output` パスが構成されている場合、自動的に有効化されます。`intlayerCompiler()` を個別に登録する必要はなくなりました。
|
|
233
234
|
- **Proxy**: 新しい `routing.enableProxy` オプション(デフォルトは `true`)に基づいて自動的に有効化されます。開発、プレビュー、本番 SSR でロケール検出・リダイレクト・書き換えミドルウェアを配線します。`intlayerProxy()` を個別に登録する必要はなくなりました。
|
|
234
235
|
|
|
235
236
|
### `routing.enableProxy` オプション
|
|
@@ -252,6 +253,27 @@ export default config;
|
|
|
252
253
|
|
|
253
254
|
---
|
|
254
255
|
|
|
256
|
+
## コンパイラはデフォルトで無効
|
|
257
|
+
|
|
258
|
+
Intlayer v9 以降、**コンパイラはデフォルトで無効になっています**(`compiler.enabled` のデフォルト値は `false` になりました)。`.content.ts` ファイルのビルド時抽出を有効にするには、設定で `compiler.enabled: true` を指定します。
|
|
259
|
+
|
|
260
|
+
```ts fileName="intlayer.config.ts"
|
|
261
|
+
import type { IntlayerConfig } from "intlayer";
|
|
262
|
+
|
|
263
|
+
const config: IntlayerConfig = {
|
|
264
|
+
compiler: {
|
|
265
|
+
enabled: true, // デフォルト: false — v9 以降、コンパイラを有効にするために必要
|
|
266
|
+
output: ({ fileName }) => `./${fileName}.content.ts`,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default config;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
コンパイラが無効の場合、Intlayer はビルド時の抽出ステップをスキップし、すでに宣言済みの辞書に依存します。バンドラープラグイン(`@intlayer/swc`、`@intlayer/babel`、または `intlayer()` Vite プラグイン)にコンテンツを自動的に抽出させたい場合にのみ有効にしてください。
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
255
277
|
## React Native: 単一パッケージでのインポート
|
|
256
278
|
|
|
257
279
|
React Native または Expo アプリでは、`react-intlayer` と `react-native-intlayer` の両方を使い分ける必要がなくなりました。`react-native-intlayer` パッケージは現在、**`react-intlayer` の完全な API を再エクスポート**しており(フック、ユーティリティ、および `/format`、`/html`、`/markdown` サブパス)、その `IntlayerProvider` は自動的に React Native のポリフィルを適用します。
|
|
@@ -278,13 +300,14 @@ npm install intlayer react-native-intlayer
|
|
|
278
300
|
|
|
279
301
|
v8からアップグレードする場合、v9には破壊的変更は含まれていません。ただし、主な変更点は次のとおりです。
|
|
280
302
|
|
|
303
|
+
- **コンパイラはデフォルトで無効**: `compiler.enabled` のデフォルト値は `false` になりました。`.content.ts` ファイルのビルド時抽出に依存している場合は、`intlayer.config.ts` で `compiler.enabled: true` を設定してください。
|
|
281
304
|
- **ロケールと方言**: 外部i18n依存関係を使用している場合、設定またはバンドラーセットアップにそれぞれの互換アダプタープラグインを追加して、インポートを自動的に書き換えるようにします。
|
|
282
|
-
- **カスタムセレクター**: `useIntlayer`を呼び出す際、2番目のパラメーターは`{ locale, item, variant
|
|
305
|
+
- **カスタムセレクター**: `useIntlayer`を呼び出す際、2番目のパラメーターは`{ locale, item, variant }`を含むオプションオブジェクトのために予約されるようになりました。以前にロケール文字列を直接渡していた場合でも引き続き可能ですが、高度な選択にはオプションオブジェクトの使用が推奨されます。
|
|
283
306
|
|
|
284
307
|
---
|
|
285
308
|
|
|
286
309
|
## 役立つリンク
|
|
287
310
|
|
|
288
311
|
- [互換アダプターパッケージガイド](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/compat/index.md)
|
|
289
|
-
- [動的辞書 -
|
|
312
|
+
- [動的辞書 - コレクション、バリアント](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/dynamic_dictionaries/index.md)
|
|
290
313
|
- [設定リファレンス](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ja/configuration.md)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-06-12
|
|
3
|
-
updatedAt: 2026-06-
|
|
3
|
+
updatedAt: 2026-06-26
|
|
4
4
|
title: 동적 사전
|
|
5
|
-
description:
|
|
5
|
+
description: Intlayer의 동적 사전 기능(컬렉션 및 변형) 개요 — 유연하고 런타임 기반의 i18n 콘텐츠를 구축하기 위한 것입니다.
|
|
6
6
|
keywords:
|
|
7
7
|
- 동적 사전
|
|
8
8
|
- 컬렉션
|
|
9
9
|
- 변형
|
|
10
|
-
- 동적 레코드
|
|
11
10
|
- Intlayer
|
|
12
11
|
- 국제화
|
|
13
12
|
slugs:
|
|
@@ -18,31 +17,38 @@ history:
|
|
|
18
17
|
- version: 9.0.0
|
|
19
18
|
date: 2026-06-12
|
|
20
19
|
changes: "동적 사전 기능 출시"
|
|
20
|
+
- version: 9.1.0
|
|
21
|
+
date: 2026-06-26
|
|
22
|
+
changes: "동적 레코드를 변형으로 통합 — 이제 `variant`는 문자열 또는 객체를 허용합니다"
|
|
21
23
|
author: aymericzip
|
|
22
24
|
---
|
|
23
25
|
|
|
24
26
|
# 동적 사전
|
|
25
27
|
|
|
26
|
-
Intlayer는 키당
|
|
28
|
+
Intlayer는 키당 단일 정적 사전을 넘어서는 콘텐츠를 표현하기 위한 두 가지 메커니즘을 지원합니다. 각각은 콘텐츠 파일의 **최상위 메타데이터 필드**를 통해 선언되며, 래퍼 함수가 필요하지 않습니다.
|
|
27
29
|
|
|
28
|
-
| 기능
|
|
29
|
-
|
|
|
30
|
-
| [컬렉션](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/collections.md)
|
|
31
|
-
| [변형](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/variants.md)
|
|
32
|
-
| [동적 레코드](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/dynamic_content.md) | `meta: { id, … }` | `{ id, … }` |
|
|
30
|
+
| 기능 | 메타데이터 필드 | `useIntlayer`의 셀렉터 |
|
|
31
|
+
| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------- |
|
|
32
|
+
| [컬렉션](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/collections.md) | `item: N` | `{ item: N }` |
|
|
33
|
+
| [변형](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dynamic_dictionaries/variants.md) | `variant: "name"` _또는_ `variant: { … }` | `{ variant: "name" }` _또는_ `{ variant: { … } }` |
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
둘 다 locale 인수와 결합되며 `importMode`를 통한 선택적 / 지연 로딩을 지원합니다.
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## 무엇을 언제 사용할지
|
|
37
38
|
|
|
38
|
-
- **컬렉션** — 별도의
|
|
39
|
-
- **변형** —
|
|
40
|
-
-
|
|
39
|
+
- **컬렉션** — 별도의 파일에서 관리되는 정렬된 항목 목록(FAQ 항목, 블로그 게시물, 제품).
|
|
40
|
+
- **변형** — 이름이 지정되었거나 구조화된 콘텐츠 대안:
|
|
41
|
+
- A/B 테스트, 시즌 배너 또는 기능 플래그를 위한 **문자열** 변형;
|
|
42
|
+
- CMS 레코드, 사용자별 콘텐츠, 또는 필드 집합으로 주소가 지정되는 모든 콘텐츠를 위한 **객체** 변형(이전의 "동적 레코드").
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
> 이전 버전은 레코드 키 기반 콘텐츠를 위해 별도의 `meta` 필드를 제공했습니다. 이는 `variant`로 통합되었습니다. `meta`를 사용하는 대신 `variant`에 **객체**를 전달하세요.
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
## 셀렉터 모호성 해소
|
|
47
|
+
|
|
48
|
+
키는 두 차원을 동시에 선언할 수 있습니다(예: 각 항목에 변형이 있는 컬렉션). 이는 다음 순서로 해결됩니다:
|
|
45
49
|
|
|
46
50
|
```
|
|
47
|
-
variant →
|
|
51
|
+
variant → item
|
|
48
52
|
```
|
|
53
|
+
|
|
54
|
+
따라서 variant × item 키에서 `{ variant: "promo" }`는 모든 promo 항목을 배열로 반환하고, `{ item: 2 }`를 추가하면 단일 항목으로 좁혀집니다.
|