@intlayer/docs 8.9.4 → 8.9.6-canary.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.
- package/docs/ar/benchmark/index.md +0 -3
- package/docs/ar/benchmark/nextjs.md +15 -6
- package/docs/ar/benchmark/solid.md +155 -0
- package/docs/ar/benchmark/svelte.md +148 -0
- package/docs/ar/benchmark/tanstack.md +12 -3
- package/docs/ar/benchmark/vue.md +160 -0
- package/docs/ar/configuration.md +16 -12
- package/docs/ar/dictionary/content_file.md +51 -1
- package/docs/ar/plugins/sync-po.md +0 -21
- package/docs/bn/configuration.md +16 -12
- package/docs/cs/configuration.md +16 -12
- package/docs/de/benchmark/index.md +0 -3
- package/docs/de/benchmark/nextjs.md +15 -6
- package/docs/de/benchmark/solid.md +155 -0
- package/docs/de/benchmark/svelte.md +148 -0
- package/docs/de/benchmark/tanstack.md +12 -3
- package/docs/de/benchmark/vue.md +160 -0
- package/docs/de/configuration.md +16 -12
- package/docs/de/dictionary/content_file.md +52 -2
- package/docs/de/plugins/sync-po.md +0 -22
- package/docs/en/benchmark/nextjs.md +11 -2
- package/docs/en/benchmark/solid.md +22 -4
- package/docs/en/benchmark/svelte.md +17 -5
- package/docs/en/benchmark/tanstack.md +18 -3
- package/docs/en/benchmark/vue.md +17 -11
- package/docs/en/configuration.md +16 -13
- package/docs/en/dictionary/content_file.md +51 -1
- package/docs/en/plugins/sync-po.md +0 -21
- package/docs/en-GB/benchmark/index.md +0 -3
- package/docs/en-GB/benchmark/nextjs.md +15 -6
- package/docs/en-GB/benchmark/solid.md +155 -0
- package/docs/en-GB/benchmark/svelte.md +148 -0
- package/docs/en-GB/benchmark/tanstack.md +12 -3
- package/docs/en-GB/benchmark/vue.md +160 -0
- package/docs/en-GB/configuration.md +15 -11
- package/docs/en-GB/dictionary/content_file.md +51 -1
- package/docs/en-GB/plugins/sync-po.md +0 -21
- package/docs/es/benchmark/index.md +0 -3
- package/docs/es/benchmark/nextjs.md +15 -6
- package/docs/es/benchmark/solid.md +155 -0
- package/docs/es/benchmark/svelte.md +148 -0
- package/docs/es/benchmark/tanstack.md +12 -3
- package/docs/es/benchmark/vue.md +160 -0
- package/docs/es/configuration.md +16 -12
- package/docs/es/dictionary/content_file.md +51 -1
- package/docs/es/plugins/sync-po.md +0 -21
- package/docs/fr/benchmark/index.md +0 -3
- package/docs/fr/benchmark/nextjs.md +15 -6
- package/docs/fr/benchmark/solid.md +155 -0
- package/docs/fr/benchmark/svelte.md +148 -0
- package/docs/fr/benchmark/tanstack.md +12 -3
- package/docs/fr/benchmark/vue.md +160 -0
- package/docs/fr/configuration.md +16 -12
- package/docs/fr/dictionary/content_file.md +51 -1
- package/docs/fr/plugins/sync-po.md +0 -21
- package/docs/hi/benchmark/nextjs.md +15 -6
- package/docs/hi/benchmark/solid.md +155 -0
- package/docs/hi/benchmark/svelte.md +148 -0
- package/docs/hi/benchmark/tanstack.md +12 -3
- package/docs/hi/benchmark/vue.md +160 -0
- package/docs/hi/configuration.md +16 -12
- package/docs/hi/dictionary/content_file.md +51 -1
- package/docs/hi/plugins/sync-po.md +0 -21
- package/docs/id/benchmark/index.md +0 -3
- package/docs/id/benchmark/nextjs.md +15 -6
- package/docs/id/benchmark/solid.md +155 -0
- package/docs/id/benchmark/svelte.md +148 -0
- package/docs/id/benchmark/tanstack.md +12 -3
- package/docs/id/benchmark/vue.md +160 -0
- package/docs/id/configuration.md +16 -12
- package/docs/id/dictionary/content_file.md +51 -1
- package/docs/id/plugins/sync-po.md +0 -21
- package/docs/it/benchmark/index.md +1 -4
- package/docs/it/benchmark/nextjs.md +15 -6
- package/docs/it/benchmark/solid.md +155 -0
- package/docs/it/benchmark/svelte.md +148 -0
- package/docs/it/benchmark/tanstack.md +12 -3
- package/docs/it/benchmark/vue.md +160 -0
- package/docs/it/configuration.md +16 -12
- package/docs/it/dictionary/content_file.md +51 -1
- package/docs/it/plugins/sync-po.md +0 -21
- package/docs/ja/benchmark/index.md +5 -5
- package/docs/ja/benchmark/nextjs.md +15 -6
- package/docs/ja/benchmark/solid.md +155 -0
- package/docs/ja/benchmark/svelte.md +148 -0
- package/docs/ja/benchmark/tanstack.md +12 -3
- package/docs/ja/benchmark/vue.md +160 -0
- package/docs/ja/configuration.md +16 -12
- package/docs/ja/dictionary/content_file.md +50 -2
- package/docs/ja/intlayer_with_nextjs_no_locale_path.md +4 -3
- package/docs/ja/plugins/sync-po.md +0 -21
- package/docs/ko/benchmark/nextjs.md +15 -6
- package/docs/ko/benchmark/solid.md +155 -0
- package/docs/ko/benchmark/svelte.md +148 -0
- package/docs/ko/benchmark/tanstack.md +12 -3
- package/docs/ko/benchmark/vue.md +160 -0
- package/docs/ko/configuration.md +16 -12
- package/docs/ko/dictionary/content_file.md +51 -1
- package/docs/ko/intlayer_with_nextjs_no_locale_path.md +3 -2
- package/docs/ko/plugins/sync-po.md +0 -21
- package/docs/nl/configuration.md +16 -12
- package/docs/pl/benchmark/index.md +0 -3
- package/docs/pl/benchmark/nextjs.md +15 -6
- package/docs/pl/benchmark/solid.md +155 -0
- package/docs/pl/benchmark/svelte.md +148 -0
- package/docs/pl/benchmark/tanstack.md +12 -3
- package/docs/pl/benchmark/vue.md +160 -0
- package/docs/pl/configuration.md +16 -12
- package/docs/pl/dictionary/content_file.md +51 -1
- package/docs/pl/plugins/sync-po.md +0 -21
- package/docs/pt/benchmark/index.md +0 -3
- package/docs/pt/benchmark/nextjs.md +16 -7
- package/docs/pt/benchmark/solid.md +155 -0
- package/docs/pt/benchmark/svelte.md +148 -0
- package/docs/pt/benchmark/tanstack.md +13 -4
- package/docs/pt/benchmark/vue.md +160 -0
- package/docs/pt/configuration.md +16 -12
- package/docs/pt/dictionary/content_file.md +51 -1
- package/docs/pt/plugins/sync-po.md +0 -21
- package/docs/ru/benchmark/nextjs.md +15 -6
- package/docs/ru/benchmark/solid.md +155 -0
- package/docs/ru/benchmark/svelte.md +148 -0
- package/docs/ru/benchmark/tanstack.md +12 -3
- package/docs/ru/benchmark/vue.md +160 -0
- package/docs/ru/configuration.md +16 -12
- package/docs/ru/dictionary/content_file.md +52 -2
- package/docs/ru/plugins/sync-po.md +0 -21
- package/docs/tr/benchmark/index.md +0 -3
- package/docs/tr/benchmark/nextjs.md +15 -6
- package/docs/tr/benchmark/solid.md +155 -0
- package/docs/tr/benchmark/svelte.md +148 -0
- package/docs/tr/benchmark/tanstack.md +12 -3
- package/docs/tr/benchmark/vue.md +160 -0
- package/docs/tr/configuration.md +16 -12
- package/docs/tr/dictionary/content_file.md +51 -1
- package/docs/tr/plugins/sync-po.md +0 -21
- package/docs/uk/benchmark/nextjs.md +15 -6
- package/docs/uk/benchmark/solid.md +155 -0
- package/docs/uk/benchmark/svelte.md +148 -0
- package/docs/uk/benchmark/tanstack.md +12 -3
- package/docs/uk/benchmark/vue.md +160 -0
- package/docs/uk/configuration.md +16 -12
- package/docs/uk/dictionary/content_file.md +51 -1
- package/docs/uk/plugins/sync-po.md +0 -21
- package/docs/ur/configuration.md +16 -12
- package/docs/vi/benchmark/index.md +0 -3
- package/docs/vi/benchmark/nextjs.md +15 -6
- package/docs/vi/benchmark/solid.md +155 -0
- package/docs/vi/benchmark/svelte.md +148 -0
- package/docs/vi/benchmark/tanstack.md +12 -3
- package/docs/vi/benchmark/vue.md +160 -0
- package/docs/vi/configuration.md +16 -12
- package/docs/vi/dictionary/content_file.md +51 -1
- package/docs/vi/intlayer_with_nextjs_15.md +10 -57
- package/docs/vi/plugins/sync-po.md +0 -21
- package/docs/zh/benchmark/nextjs.md +15 -6
- package/docs/zh/benchmark/solid.md +155 -0
- package/docs/zh/benchmark/svelte.md +148 -0
- package/docs/zh/benchmark/tanstack.md +12 -3
- package/docs/zh/benchmark/vue.md +160 -0
- package/docs/zh/configuration.md +16 -12
- package/docs/zh/dictionary/content_file.md +51 -3
- package/docs/zh/plugins/sync-po.md +0 -21
- package/frequent_questions/ar/intlayerNode.md +3 -3
- package/frequent_questions/de/intlayerNode.md +3 -3
- package/frequent_questions/en/intlayerNode.md +3 -3
- package/frequent_questions/en-GB/intlayerNode.md +3 -3
- package/frequent_questions/es/intlayerNode.md +3 -3
- package/frequent_questions/fr/intlayerNode.md +3 -3
- package/frequent_questions/hi/intlayerNode.md +3 -3
- package/frequent_questions/id/intlayerNode.md +3 -3
- package/frequent_questions/it/intlayerNode.md +3 -3
- package/frequent_questions/ja/intlayerNode.md +3 -3
- package/frequent_questions/ko/intlayerNode.md +3 -3
- package/frequent_questions/pl/intlayerNode.md +3 -3
- package/frequent_questions/pt/intlayerNode.md +3 -3
- package/frequent_questions/ru/intlayerNode.md +3 -3
- package/frequent_questions/tr/intlayerNode.md +3 -3
- package/frequent_questions/uk/intlayerNode.md +3 -3
- package/frequent_questions/vi/intlayerNode.md +3 -3
- package/frequent_questions/zh/intlayerNode.md +3 -3
- package/package.json +8 -8
package/docs/ko/configuration.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-08-13
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-05-12
|
|
4
4
|
title: 구성 (Configuration)
|
|
5
5
|
description: 애플리케이션에 Intlayer를 구성하는 방법을 알아보세요. 필요에 따라 Intlayer를 맞춤설정하는 데 사용할 수 있는 다양한 설정과 옵션을 이해하세요.
|
|
6
6
|
keywords:
|
|
@@ -14,6 +14,9 @@ slugs:
|
|
|
14
14
|
- concept
|
|
15
15
|
- configuration
|
|
16
16
|
history:
|
|
17
|
+
- version: 8.9.4
|
|
18
|
+
date: 2026-05-12
|
|
19
|
+
changes: "LM Studio 공급자 지원 추가"
|
|
17
20
|
- version: 8.7.0
|
|
18
21
|
date: 2026-04-08
|
|
19
22
|
changes: "빌드 구성에 `prune` 및 `minify` 옵션 추가"
|
|
@@ -350,7 +353,7 @@ const config: IntlayerConfig = {
|
|
|
350
353
|
ai: {
|
|
351
354
|
/**
|
|
352
355
|
* 사용할 AI 프로바이더.
|
|
353
|
-
* 옵션: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai'
|
|
356
|
+
* 옵션: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio'
|
|
354
357
|
* 기본값: 'openai'
|
|
355
358
|
*/
|
|
356
359
|
provider: "openai",
|
|
@@ -916,16 +919,17 @@ Intlayer는 최대의 유연성을 보장하기 위해 다양한 AI 프로바이
|
|
|
916
919
|
- **Groq**
|
|
917
920
|
- **Amazon Bedrock**
|
|
918
921
|
- **Together.ai**
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
|
922
|
-
|
|
|
923
|
-
| `
|
|
924
|
-
| `
|
|
925
|
-
| `
|
|
926
|
-
| `
|
|
927
|
-
| `
|
|
928
|
-
| `
|
|
922
|
+
- **LM Studio**
|
|
923
|
+
|
|
924
|
+
| 필드 | 설명 | 타입 | 기본값 | 예시 | 참고 |
|
|
925
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
926
|
+
| `provider` | Intlayer AI 기능에 사용할 프로바이더. | `'openai'` | <br/> `'anthropic'` | <br/> `'mistral'` | <br/> `'deepseek'` | <br/> `'gemini'` | <br/> `'ollama'` | <br/> `'openrouter'` | <br/> `'alibaba'` | <br/> `'fireworks'` | <br/> `'groq'` | <br/> `'huggingface'` | <br/> `'bedrock'` | <br/> `'googleaistudio'` | <br/> `'googlevertex'` | <br/> `'togetherai'` | <br/> `'lmstudio'` | `undefined` | `'anthropic'` | 여러 프로바이더는 서로 다른 API 키가 필요하며 가격 구조도 다릅니다. |
|
|
927
|
+
| `model` | AI 기능에 사용할 AI 모델. | `string` | 없음 | `'gpt-4o-2024-11-20'` | 특정 모델은 프로바이더에 따라 다릅니다. |
|
|
928
|
+
| `temperature` | AI 응답의 무작위성을 제어합니다. | `number` | 없음 | `0.1` | 온도가 높을수록 창의적이지만 신뢰성이 낮아집니다. |
|
|
929
|
+
| `apiKey` | 선택한 프로바이더의 API 키. | `string` | 없음 | `process.env.OPENAI_API_KEY` | 비밀로 유지해야 하며 환경 변수를 사용하세요. |
|
|
930
|
+
| `applicationContext` | AI가 더 정확한 번역을 생성할 수 있도록 돕는 애플리케이션에 대한 추가 컨텍스트(도메인, 대상 고객, 어조, 용어 등). | `string` | 없음 | `'my custom app context'` | 규칙을 추가하는 데 사용할 수 있습니다 (예: `"URL은 번역하지 마세요"` ). |
|
|
931
|
+
| `baseURL` | AI API에 대한 기본 URL. | `string` | 없음 | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | 로컬 또는 맞춤형 AI API 엔드포인트를 가리킬 수 있습니다. |
|
|
932
|
+
| `dataSerialization` | AI 기능에 대한 데이터 직렬화 형식. | `'json'` | <br/> `'toon'` | `undefined` | `'toon'` | • `'json'`: 기본값, 안정적임; 더 많은 토큰 소비.<br/>• `'toon'`: 더 적은 토큰 소모, 덜 안정적임.<br/>• 모델에 로직 실행을 위한 추가 파라미터(추론 노력(reasoning effort) 등)를 전달합니다. |
|
|
929
933
|
|
|
930
934
|
---
|
|
931
935
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2025-02-07
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-05-12
|
|
4
4
|
title: 콘텐츠 파일
|
|
5
5
|
description: 콘텐츠 선언 파일의 확장자를 사용자 정의하는 방법을 배우세요. 이 문서를 따라 프로젝트에서 조건을 효율적으로 구현하세요.
|
|
6
6
|
keywords:
|
|
@@ -12,6 +12,9 @@ slugs:
|
|
|
12
12
|
- concept
|
|
13
13
|
- content
|
|
14
14
|
history:
|
|
15
|
+
- version: 8.9.0
|
|
16
|
+
date: 2026-05-12
|
|
17
|
+
changes: "`plural` 콘텐츠 노드 유형 추가"
|
|
15
18
|
- version: 8.0.0
|
|
16
19
|
date: 2026-01-28
|
|
17
20
|
changes: "`html` 콘텐츠 노드 타입 추가"
|
|
@@ -63,6 +66,7 @@ import { type ReactNode } from "react";
|
|
|
63
66
|
import {
|
|
64
67
|
t,
|
|
65
68
|
enu,
|
|
69
|
+
plural,
|
|
66
70
|
cond,
|
|
67
71
|
nest,
|
|
68
72
|
md,
|
|
@@ -82,6 +86,7 @@ interface Content {
|
|
|
82
86
|
};
|
|
83
87
|
multilingualContent: string;
|
|
84
88
|
quantityContent: string;
|
|
89
|
+
pluralContent: string;
|
|
85
90
|
conditionalContent: string;
|
|
86
91
|
markdownContent: never;
|
|
87
92
|
htmlContent: never;
|
|
@@ -118,6 +123,10 @@ export default {
|
|
|
118
123
|
">5": "몇 대의 자동차",
|
|
119
124
|
">19": "많은 자동차",
|
|
120
125
|
}),
|
|
126
|
+
pluralContent: plural({
|
|
127
|
+
one: "One car",
|
|
128
|
+
other: "{{count}} cars",
|
|
129
|
+
}),
|
|
121
130
|
conditionalContent: cond({
|
|
122
131
|
true: "검증이 활성화됨",
|
|
123
132
|
false: "검증이 비활성화됨",
|
|
@@ -172,6 +181,13 @@ export default {
|
|
|
172
181
|
">5": "몇 대의 차",
|
|
173
182
|
">19": "많은 차",
|
|
174
183
|
},
|
|
184
|
+
"pluralContent": {
|
|
185
|
+
"nodeType": "plural",
|
|
186
|
+
"plural": {
|
|
187
|
+
"one": "One car",
|
|
188
|
+
"other": "{{count}} cars",
|
|
189
|
+
},
|
|
190
|
+
},
|
|
175
191
|
},
|
|
176
192
|
"conditionalContent": {
|
|
177
193
|
"nodeType": "condition",
|
|
@@ -219,6 +235,7 @@ export default {
|
|
|
219
235
|
- **원시 값**: 문자열, 숫자, 불리언, null, undefined
|
|
220
236
|
- **타입이 지정된 노드**: 번역, 조건, 마크다운 등과 같은 특수 콘텐츠 유형
|
|
221
237
|
- **함수**: 런타임에 평가될 수 있는 동적 콘텐츠 [함수 가져오기 참조](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/function_fetching.md)
|
|
238
|
+
- **복수형 콘텐츠**: 자세한 내용은 복수형 콘텐츠 [자세한 내용은 복수형 콘텐츠](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/plural.md)
|
|
222
239
|
- **중첩 콘텐츠**: 다른 사전에 대한 참조
|
|
223
240
|
|
|
224
241
|
#### 콘텐츠 유형
|
|
@@ -564,6 +581,8 @@ multilingualContent: t({
|
|
|
564
581
|
});
|
|
565
582
|
```
|
|
566
583
|
|
|
584
|
+
> 자세한 내용은 [번역 콘텐츠 (`t`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/translation.md) 를 참조하세요.
|
|
585
|
+
|
|
567
586
|
### 조건 콘텐츠 (`cond`)
|
|
568
587
|
|
|
569
588
|
불리언 조건에 따라 변경되는 콘텐츠:
|
|
@@ -577,6 +596,8 @@ conditionalContent: cond({
|
|
|
577
596
|
});
|
|
578
597
|
```
|
|
579
598
|
|
|
599
|
+
> 자세한 내용은 [조건 콘텐츠 (`cond`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/condition.md) 를 참조하세요.
|
|
600
|
+
|
|
580
601
|
### 열거형 콘텐츠 (`enu`)
|
|
581
602
|
|
|
582
603
|
열거형 값에 따라 달라지는 콘텐츠:
|
|
@@ -591,6 +612,23 @@ statusContent: enu({
|
|
|
591
612
|
});
|
|
592
613
|
```
|
|
593
614
|
|
|
615
|
+
> 자세한 내용은 [열거형 콘텐츠 (`enu`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/enumeration.md) 를 참조하세요.
|
|
616
|
+
|
|
617
|
+
### 복수형 콘텐츠 (`plural`)
|
|
618
|
+
|
|
619
|
+
복수형 규칙에 따라 달라지는 콘텐츠:
|
|
620
|
+
|
|
621
|
+
```typescript
|
|
622
|
+
import { plural } from "intlayer";
|
|
623
|
+
|
|
624
|
+
pluralContent: plural({
|
|
625
|
+
one: "One car",
|
|
626
|
+
other: "{{count}} cars",
|
|
627
|
+
});
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
> 자세한 내용은 [복수형 콘텐츠 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/plural.md) 를 참조하세요.
|
|
631
|
+
|
|
594
632
|
### 삽입 콘텐츠 (`insert`)
|
|
595
633
|
|
|
596
634
|
다른 콘텐츠에 삽입할 수 있는 콘텐츠:
|
|
@@ -601,6 +639,8 @@ import { insert } from "intlayer";
|
|
|
601
639
|
insertionContent: insert("이 텍스트는 어디에나 삽입할 수 있습니다");
|
|
602
640
|
```
|
|
603
641
|
|
|
642
|
+
> 자세한 내용은 [삽입 콘텐츠 (`insert`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/insertion.md) 를 참조하세요.
|
|
643
|
+
|
|
604
644
|
### 중첩 콘텐츠 (`nest`)
|
|
605
645
|
|
|
606
646
|
다른 사전에 대한 참조:
|
|
@@ -611,6 +651,8 @@ import { nest } from "intlayer";
|
|
|
611
651
|
nestedContent: nest("about-page");
|
|
612
652
|
```
|
|
613
653
|
|
|
654
|
+
> 자세한 내용은 [중첩 콘텐츠 (`nest`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/nesting.md) 를 참조하세요.
|
|
655
|
+
|
|
614
656
|
### 마크다운 콘텐츠 (`md`)
|
|
615
657
|
|
|
616
658
|
마크다운 형식의 리치 텍스트 콘텐츠:
|
|
@@ -623,6 +665,8 @@ markdownContent: md(
|
|
|
623
665
|
);
|
|
624
666
|
```
|
|
625
667
|
|
|
668
|
+
> 자세한 내용은 [마크다운 콘텐츠 (`md`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/markdown.md) 를 참조하세요.
|
|
669
|
+
|
|
626
670
|
### HTML 콘텐츠 (`html`)
|
|
627
671
|
|
|
628
672
|
표준 태그 또는 사용자 정의 컴포넌트를 사용할 수 있는 리치 HTML 콘텐츠:
|
|
@@ -640,6 +684,8 @@ localizedHtmlContent: t({
|
|
|
640
684
|
});
|
|
641
685
|
```
|
|
642
686
|
|
|
687
|
+
> 자세한 내용은 [HTML 콘텐츠 (`html`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/html.md) 를 참조하세요.
|
|
688
|
+
|
|
643
689
|
### 성별에 따른 콘텐츠 (`gender`)
|
|
644
690
|
|
|
645
691
|
성별에 따라 달라지는 콘텐츠:
|
|
@@ -654,6 +700,8 @@ genderContent: gender({
|
|
|
654
700
|
});
|
|
655
701
|
```
|
|
656
702
|
|
|
703
|
+
> 자세한 내용은 [성별에 따른 콘텐츠 (`gender`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/gender.md) 를 참조하세요.
|
|
704
|
+
|
|
657
705
|
### 파일 콘텐츠 (`file`)
|
|
658
706
|
|
|
659
707
|
외부 파일에 대한 참조:
|
|
@@ -664,6 +712,8 @@ import { file } from "intlayer";
|
|
|
664
712
|
fileContent: file("./path/to/content.txt");
|
|
665
713
|
```
|
|
666
714
|
|
|
715
|
+
> 자세한 내용은 [파일 콘텐츠 (`file`) 문서](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/dictionary/file.md) 를 참조하세요.
|
|
716
|
+
|
|
667
717
|
## 콘텐츠 파일 생성하기
|
|
668
718
|
|
|
669
719
|
### 기본 콘텐츠 파일 구조
|
|
@@ -625,7 +625,7 @@ Intlayer는 TypeScript의 이점을 얻고 코드베이스를 더욱 견고하
|
|
|
625
625
|
|
|
626
626
|
TypeScript 구성에 자동 생성된 타입들이 포함되어 있는지 확인하세요.
|
|
627
627
|
|
|
628
|
-
|
|
628
|
+
```json5 fileName="tsconfig.json"
|
|
629
629
|
{
|
|
630
630
|
// ... 기존 TypeScript 구성
|
|
631
631
|
"include": [
|
|
@@ -633,6 +633,7 @@ TypeScript 구성에 자동 생성된 타입들이 포함되어 있는지 확인
|
|
|
633
633
|
".intlayer/**/*.ts", // 자동으로 생성된 타입 포함
|
|
634
634
|
],
|
|
635
635
|
}
|
|
636
|
+
```
|
|
636
637
|
|
|
637
638
|
### Git 구성
|
|
638
639
|
|
|
@@ -643,7 +644,7 @@ Intlayer에 의해 생성된 파일을 무시하는 것을 권장합니다. 이
|
|
|
643
644
|
```plaintext fileName=".gitignore"
|
|
644
645
|
# Intlayer에 의해 생성된 파일 무시
|
|
645
646
|
.intlayer
|
|
646
|
-
|
|
647
|
+
```
|
|
647
648
|
|
|
648
649
|
### VS Code 확장
|
|
649
650
|
|
|
@@ -160,30 +160,9 @@ syncPO({
|
|
|
160
160
|
source: ({ key, locale }) => string, // 필수
|
|
161
161
|
location?: string, // 선택적 레이블, 기본값: "sync-po::path/to/source"
|
|
162
162
|
priority?: number, // 충돌 해결을 위한 선택적 우선순위, 기본값: 0
|
|
163
|
-
format?: 'icu' | 'i18next' | 'vue-i18n', // 선택적, msgstr 값이 특정 보간 구문을 사용하는 경우에만 필요
|
|
164
163
|
});
|
|
165
164
|
```
|
|
166
165
|
|
|
167
|
-
#### `format` ('icu' | 'i18next' | 'vue-i18n')
|
|
168
|
-
|
|
169
|
-
PO 파일은 항상 Gettext Portable Object 파일입니다. 이는 고정되어 있습니다. 이 옵션은 `msgstr` 값 내부에서 사용되는 **보간 구문**만 설명합니다. 이를 통해 Intlayer는 파싱 시점(`formatDictionary`를 통해)에 자체 형식으로 변환하고 출력을 쓸 때 다시 변환할 수 있습니다.
|
|
170
|
-
|
|
171
|
-
- `undefined` _(기본값)_: `msgstr` 값은 일반 문자열로 처리되며 변환되지 않습니다. 대부분의 PO 파일에 이를 사용하세요.
|
|
172
|
-
- `'icu'`: `msgstr` 값은 ICU 메시지 구문을 사용합니다(예: `{count, plural, one {# item} other {# items}}`).
|
|
173
|
-
- `'i18next'`: `msgstr` 값은 i18next 보간 구문을 사용합니다(예: `{{variable}}`).
|
|
174
|
-
- `'vue-i18n'`: `msgstr` 값은 Vue I18n 구문을 사용합니다.
|
|
175
|
-
|
|
176
|
-
> 변환은 로드 시 `@intlayer/chokidar`의 `formatDictionary`에 의해 적용되고, 쓰기 시 `formatDictionaryOutput`에 의해 역전됩니다. ICU 복수형과 같은 복잡한 규칙의 경우 라운드 트립 충실도가 보장되지 않습니다.
|
|
177
|
-
|
|
178
|
-
**예 — PO 파일에 i18next 스타일 보간이 포함된 경우:**
|
|
179
|
-
|
|
180
|
-
```ts
|
|
181
|
-
syncPO({
|
|
182
|
-
source: ({ key, locale }) => `./locales/${locale}/${key}.po`,
|
|
183
|
-
format: "i18next",
|
|
184
|
-
}),
|
|
185
|
-
```
|
|
186
|
-
|
|
187
166
|
### 여러 PO 소스 및 우선순위
|
|
188
167
|
|
|
189
168
|
서로 다른 PO 소스를 동기화하기 위해 여러 개의 `syncPO` 플러그인을 추가할 수 있습니다. 이는 프로젝트에 여러 번역 소스가 있거나 서로 다른 PO 구조가 있는 경우에 유용합니다.
|
package/docs/nl/configuration.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-08-13
|
|
3
|
-
updatedAt: 2026-
|
|
3
|
+
updatedAt: 2026-05-12
|
|
4
4
|
title: Configuratie (Configuration)
|
|
5
5
|
description: Leer hoe u Intlayer configureert voor uw applicatie. Begrijp de verschillende instellingen en opties die beschikbaar zijn om Intlayer aan uw behoeften aan te passen.
|
|
6
6
|
keywords:
|
|
@@ -14,6 +14,9 @@ slugs:
|
|
|
14
14
|
- concept
|
|
15
15
|
- configuration
|
|
16
16
|
history:
|
|
17
|
+
- version: 8.9.4
|
|
18
|
+
date: 2026-05-12
|
|
19
|
+
changes: "Ondersteuning voor LM Studio-provider toegevoegd"
|
|
17
20
|
- version: 8.7.0
|
|
18
21
|
date: 2026-04-08
|
|
19
22
|
changes: "Opties `prune` en `minify` toegevoegd aan de buildconfiguratie"
|
|
@@ -350,7 +353,7 @@ const config: IntlayerConfig = {
|
|
|
350
353
|
ai: {
|
|
351
354
|
/**
|
|
352
355
|
* Gebruikte AI-provider.
|
|
353
|
-
* Opties: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai'
|
|
356
|
+
* Opties: 'openai', 'anthropic', 'mistral', 'deepseek', 'gemini', 'ollama', 'openrouter', 'alibaba', 'fireworks', 'groq', 'huggingface', 'bedrock', 'googlevertex', 'togetherai', 'lmstudio'
|
|
354
357
|
* Standaard: 'openai'
|
|
355
358
|
*/
|
|
356
359
|
provider: "openai",
|
|
@@ -916,16 +919,17 @@ Intlayer ondersteunt meerdere AI-providers voor maximale flexibiliteit. Momentee
|
|
|
916
919
|
- **Groq**
|
|
917
920
|
- **Amazon Bedrock**
|
|
918
921
|
- **Together.ai**
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
|
922
|
-
|
|
|
923
|
-
| `
|
|
924
|
-
| `
|
|
925
|
-
| `
|
|
926
|
-
| `
|
|
927
|
-
| `
|
|
928
|
-
| `
|
|
922
|
+
- **LM Studio**
|
|
923
|
+
|
|
924
|
+
| Veld | Beschrijving | Type | Standaard | Voorbeeld | Opmerking |
|
|
925
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
926
|
+
| `provider` | Provider gebruikt voor AI-functies van Intlayer. | `'openai'` | <br/> `'anthropic'` | <br/> `'mistral'` | <br/> `'deepseek'` | <br/> `'gemini'` | <br/> `'ollama'` | <br/> `'openrouter'` | <br/> `'alibaba'` | <br/> `'fireworks'` | <br/> `'groq'` | <br/> `'huggingface'` | <br/> `'bedrock'` | <br/> `'googleaistudio'` | <br/> `'googlevertex'` | <br/> `'togetherai'` | <br/> `'lmstudio'` | `undefined` | `'anthropic'` | Verschillende providers vereisen verschillende API-sleutels en hebben verschillende prijzen. |
|
|
927
|
+
| `model` | Model gebruikt voor AI-functies. | `string` | Geen | `'gpt-4o-2024-11-20'` | Het specifieke model hangt af van de provider. |
|
|
928
|
+
| `temperature` | Regelt de willekeur van de AI-antwoorden. | `number` | Geen | `0.1` | Hogere temperatuur = creatiever en minder voorspelbaar. |
|
|
929
|
+
| `apiKey` | Uw API-sleutel voor de gekozen provider. | `string` | Geen | `process.env.OPENAI_API_KEY` | Moet geheim worden gehouden; gebruik omgevingsvariabelen. |
|
|
930
|
+
| `applicationContext` | Extra context over uw applicatie om de AI te helpen nauwkeurigere vertalingen te genereren (domein, doelgroep, toon, terminologie). | `string` | Geen | `'Mijn eigen applicatiecontext'` | Kan worden gebruikt om regels toe te voegen (bijv.: `"U moet URL's niet transformeren"`). |
|
|
931
|
+
| `baseURL` | Basis URL voor de AI API. | `string` | Geen | `'https://api.openai.com/v1'` <br/> `'http://localhost:5000'` | Kan verwijzen naar een lokaal of aangepast endpoint van de AI API. |
|
|
932
|
+
| `dataSerialization` | Formaat van de dataserialisatie voor AI-functies. | `'json'` | <br/> `'toon'` | `undefined` | `'toon'` | • `'json'`: standaard, betrouwbaar; verbruikt meer tokens.<br/>• `'toon'`: minder tokens, minder stabiel.<br/>• Extra parameters worden als context aan het model doorgegeven (redenaties-inspanning enz.). |
|
|
929
933
|
|
|
930
934
|
---
|
|
931
935
|
|
|
@@ -30,6 +30,3 @@ Poniżej znajdziesz szczegółowe raporty i dokumentację techniczną dla każde
|
|
|
30
30
|
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
31
31
|
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
32
32
|
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
33
|
-
- [**Vue Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/vue.md)
|
|
34
|
-
- [**Solid Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/solid.md)
|
|
35
|
-
- [**Svelte Benchmark Report**](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/benchmark/svelte.md)
|
|
@@ -61,6 +61,13 @@ Ponieważ problem jest trudny, istnieje wiele rozwiązań — niektóre koncentr
|
|
|
61
61
|
|
|
62
62
|
Intlayer stara się optymalizować we wszystkich tych wymiarach.
|
|
63
63
|
|
|
64
|
+
## TL;DR
|
|
65
|
+
|
|
66
|
+
- **Intlayer** i **next-translate**: Najlepsze wybory dla wydajności Next.js, oferujące najmniejszy rozmiar i najlepsze wsparcie dla statycznego renderowania.
|
|
67
|
+
- **next-intl**: Najmodniejsza obecnie opcja, ale ciężka i skomplikowana w optymalizacji dla dużych aplikacji.
|
|
68
|
+
- **next-i18next**: Popularna i bogata w pluginy, ale niesie ze sobą znaczny ciężar pakietu (~3× Intlayer).
|
|
69
|
+
- **Unikaj**: **gt-next** i **lingo.dev** ze względu na poważne problemy z wydajnością, uzależnienie od dostawcy (vendor lock-in) i błędy blokujące budowanie.
|
|
70
|
+
|
|
64
71
|
## Przetestuj swoją aplikację
|
|
65
72
|
|
|
66
73
|
Aby ujawnić te problemy, zbudowałem darmowy skaner, który możesz wypróbować [tutaj](https://intlayer.org/i18n-seo-scanner).
|
|
@@ -99,14 +106,14 @@ Wreszcie, `Intlayer` stosuje optymalizację w czasie budowania, dzięki czemu `u
|
|
|
99
106
|
W tym benchmarku porównaliśmy następujące biblioteki:
|
|
100
107
|
|
|
101
108
|
- `Base App` (Brak biblioteki i18n)
|
|
102
|
-
- `next-intlayer` (v8.7.
|
|
109
|
+
- `next-intlayer` (v8.7.12)
|
|
103
110
|
- `next-i18next` (v16.0.5)
|
|
104
111
|
- `next-intl` (v4.9.1)
|
|
105
112
|
- `@lingui/core` (v5.3.0)
|
|
106
113
|
- `next-translate` (v3.1.2)
|
|
107
114
|
- `next-international` (v1.3.1)
|
|
108
115
|
- `@inlang/paraglide-js` (v2.15.1)
|
|
109
|
-
-
|
|
116
|
+
- `@tolgee/react` (v7.0.0)
|
|
110
117
|
- `@lingo.dev/compiler` (v0.4.0)
|
|
111
118
|
- `wuchale` (v0.22.11)
|
|
112
119
|
- `gt-next` (v6.16.5)
|
|
@@ -161,10 +168,10 @@ Napotkane problemy:
|
|
|
161
168
|
|
|
162
169
|
**(General Translation)** (`gt-next@6.16.5`):
|
|
163
170
|
|
|
164
|
-
- W przypadku aplikacji o rozmiarze 110 KB, `gt-
|
|
171
|
+
- W przypadku aplikacji o rozmiarze 110 KB, `gt-next` dodaje ponad 440 KB ekstra.
|
|
165
172
|
- Komunikat `Quota Exceeded, please upgrade your plan` przy pierwszej próbie budowania z General Translation.
|
|
166
173
|
- Tłumaczenia nie są renderowane; otrzymuję błąd `Error: <T> used on the client-side outside of <GTProvider>`, co wydaje się być błędem w bibliotece.
|
|
167
|
-
- Podczas wdrażania **gt-
|
|
174
|
+
- Podczas wdrażania **gt-next** napotkałem również [problem](https://github.com/generaltranslation/gt/issues/1210#event-24510646961) z biblioteką: błąd `does not provide an export named 'printAST' - @formatjs/icu-messageformat-parser`, który powodował awarię aplikacji. Po zgłoszeniu tego problemu opiekun naprawił go w ciągu 24 godzin.
|
|
168
175
|
- Biblioteka blokuje statyczne renderowanie stron Next.js.
|
|
169
176
|
|
|
170
177
|
**(Lingo.dev)** (`@lingo.dev/compiler@0.4.0`):
|
|
@@ -186,9 +193,11 @@ Idea stojąca za `Wuchale` jest interesująca, ale nie jest to jeszcze opłacaln
|
|
|
186
193
|
Osobiście nie podoba mi się konieczność regenerowania plików JS przed każdym przesłaniem kodu (push), co stwarza ciągłe ryzyko konfliktów scalania (merge conflicts) przy Pull Requestach. Narzędzie wydaje się również bardziej skoncentrowane na Vite niż na Next.js.
|
|
187
194
|
Wreszcie, w porównaniu z innymi rozwiązaniami, Paraglide nie używa magazynu (np. React context) do pobierania bieżącej lokalizacji w celu renderowania treści. Dla każdego przeanalizowanego węzła żąda lokalizacji z localStorage / cookie itp. Prowadzi to do wykonywania niepotrzebnej logiki, co wpływa na reaktywność komponentu.
|
|
188
195
|
|
|
196
|
+
> Notatka o paraglide: rozwiązanie to wstrzykuje kod do Twojej bazy kodu w celu importu, w wyniku czego metryka 'rozmiar biblioteki' w raporcie benchmarka wynosi prawie 0. Generowanie kodu to dobra rzecz, ponieważ używana funkcja będzie zawierać tylko niezbędną logikę (wszystkie prefiksy vs brak prefiksów, ciasteczka vs storage itp.). Dla porównania, Intlayer wykonuje to filtrowanie poprzez wstrzykiwanie zmiennych środowiskowych w procesie budowania, aby wymusić na bundlerze usunięcie treści (tree-shake) w zależności od logiki. Dzięki temu paraglide i intlayer okazują się być od 6 do 10 razy lżejszymi rozwiązaniami niż i18next czy next-intl.
|
|
197
|
+
|
|
189
198
|
### 3 — Akceptowalne rozwiązania
|
|
190
199
|
|
|
191
|
-
**(Tolgee)** (
|
|
200
|
+
**(Tolgee)** (`@tolgee/react@7.0.0`):
|
|
192
201
|
|
|
193
202
|
`Tolgee` rozwiązuje wiele z wymienionych wcześniej problemów. Uznałem jednak, że trudniej go wdrożyć niż podobne narzędzia. Nie zapewnia on bezpieczeństwa typów (type safety), co utrudnia również wyłapywanie brakujących kluczy w czasie kompilacji. Musiałem opakować funkcje Tolgee we własne funkcje, aby dodać wykrywanie brakujących kluczy.
|
|
194
203
|
|
|
@@ -216,7 +225,7 @@ Różnią się również formaty komunikatów: `next-intl` używa ICU MessageFor
|
|
|
216
225
|
|
|
217
226
|
`next-translate` to moja główna rekomendacja, jeśli lubisz API w stylu `t()`. Działa on elegancko poprzez `next-translate-plugin`, ładując przestrzenie nazw przez `getStaticProps` za pomocą loadera Webpack / Turbopack. Jest to również najlżejsza opcja w tym zestawieniu (~2.5 KB). Jeśli chodzi o przestrzenie nazw, definiowanie ich na poziomie strony lub trasy w konfiguracji jest przemyślane i łatwiejsze w utrzymaniu niż w przypadku głównych alternatyw, takich jak **next-intl** czy **next-i18next**. W wersji `3.1.2` zauważyłem, że statyczne renderowanie nie działało; Next.js powracał do renderowania dynamicznego.
|
|
218
227
|
|
|
219
|
-
**(Intlayer)** (`next-intlayer@8.7.
|
|
228
|
+
**(Intlayer)** (`next-intlayer@8.7.12`):
|
|
220
229
|
|
|
221
230
|
Nie będę osobiście oceniał `next-intlayer` ze względu na obiektywizm, ponieważ jest to moje własne rozwiązanie.
|
|
222
231
|
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-04-20
|
|
3
|
+
updatedAt: 2026-04-21
|
|
4
|
+
title: Najlepsze rozwiązanie i18n dla Solid w 2026 r. — raport z benchmarku
|
|
5
|
+
description: Porównaj biblioteki internacjonalizacji (i18n) dla Solid, takie jak solid-primitives, solid-i18next i Intlayer. Szczegółowy raport wydajności dotyczący rozmiaru paczki, wycieków i reaktywności.
|
|
6
|
+
keywords:
|
|
7
|
+
- benchmark
|
|
8
|
+
- i18n
|
|
9
|
+
- intl
|
|
10
|
+
- solid
|
|
11
|
+
- wydajność
|
|
12
|
+
- intlayer
|
|
13
|
+
slugs:
|
|
14
|
+
- doc
|
|
15
|
+
- benchmark
|
|
16
|
+
- solid
|
|
17
|
+
author: Aymeric PINEAU
|
|
18
|
+
applicationTemplate: https://github.com/intlayer-org/benchmark-i18n-solid-template
|
|
19
|
+
history:
|
|
20
|
+
- version: 8.7.12
|
|
21
|
+
date: 2026-01-06
|
|
22
|
+
changes: "Inicjalizacja benchmarku"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Biblioteki i18n dla Solid — raport z benchmarku 2026
|
|
26
|
+
|
|
27
|
+
Ta strona zawiera raport z benchmarku rozwiązań i18n dla Solid.
|
|
28
|
+
|
|
29
|
+
## Spis treści
|
|
30
|
+
|
|
31
|
+
<Toc/>
|
|
32
|
+
|
|
33
|
+
## Interaktywny benchmark
|
|
34
|
+
|
|
35
|
+
<I18nBenchmark framework="vite-solid" vertical/>
|
|
36
|
+
|
|
37
|
+
## Referencja wyników:
|
|
38
|
+
|
|
39
|
+
<iframe
|
|
40
|
+
src="https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md"
|
|
41
|
+
width="100%"
|
|
42
|
+
height="600px"
|
|
43
|
+
style="border:none;">
|
|
44
|
+
</iframe>
|
|
45
|
+
|
|
46
|
+
> https://intlayer.org/markdown?url=https%3A%2F%2Fraw.githubusercontent.com%2Fintlayer-org%2Fbenchmark-i18n%2Fmain%2Freport%2Fscripts%2Fsummarize-vite_solid.md
|
|
47
|
+
|
|
48
|
+
Pełne repozytorium benchmarku znajdziesz [tutaj](https://github.com/intlayer-org/benchmark-i18n/tree/main).
|
|
49
|
+
|
|
50
|
+
## Wstęp
|
|
51
|
+
|
|
52
|
+
Rozwiązania do internacjonalizacji należą do najcięższych zależności w aplikacji Solid. Głównym ryzykiem jest wysyłanie niepotrzebnych treści: tłumaczeń dla innych stron i innych lokalizacji w paczce (bundle) pojedynczej trasy.
|
|
53
|
+
|
|
54
|
+
W miarę rozwoju aplikacji problem ten może szybko zwiększyć ilość JavaScriptu wysyłanego do klienta i spowolnić nawigację.
|
|
55
|
+
|
|
56
|
+
W praktyce, w przypadku najmniej zoptymalizowanych implementacji, strona zinternacjonalizowana może okazać się kilkukrotnie cięższa niż wersja bez i18n.
|
|
57
|
+
|
|
58
|
+
Innym skutkiem jest wpływ na doświadczenie programisty (DX): sposób deklarowania treści, typy, organizacja przestrzeni nazw (namespaces), dynamiczne ładowanie i reaktywność przy zmianie lokalizacji.
|
|
59
|
+
|
|
60
|
+
## TL;DR
|
|
61
|
+
|
|
62
|
+
- **Intlayer**: Zalecany wybór dla profesjonalnych aplikacji Solid wymagających zaawansowanych funkcji i optymalizacji (v8.7.12).
|
|
63
|
+
- **@solid-primitives/i18n**: Doskonała lekka alternatywa dla prostych projektów, choć brakuje jej zaawansowanych funkcji, takich jak lazy loading.
|
|
64
|
+
- **solid-i18next**: Standardowa, ale ciężka opcja (~4.7x Intlayer) z tymi samymi wadami co React i18next.
|
|
65
|
+
- **Paraglide**: Innowacyjne podejście, ale złożone DX i problemy z tree-shakingiem w niektórych konfiguracjach.
|
|
66
|
+
|
|
67
|
+
## Przetestuj swoją aplikację
|
|
68
|
+
|
|
69
|
+
Aby szybko wykryć problemy z wyciekami i18n, przygotowałem darmowy skaner dostępny [tutaj](https://intlayer.org/i18n-seo-scanner).
|
|
70
|
+
|
|
71
|
+
<iframe src="https://intlayer.org/i18n-seo-scanner" width="100%" height="600px" style="border:none;"/>
|
|
72
|
+
|
|
73
|
+
## Problem
|
|
74
|
+
|
|
75
|
+
Dwa dźwignie są kluczowe dla ograniczenia kosztów aplikacji wielojęzycznej:
|
|
76
|
+
|
|
77
|
+
- Dzielenie treści według stron / przestrzeni nazw, aby nie ładować całych słowników, gdy nie są potrzebne.
|
|
78
|
+
- Dynamiczne ładowanie odpowiedniej lokalizacji tylko wtedy, gdy jest potrzebna.
|
|
79
|
+
|
|
80
|
+
Zrozumienie technicznych ograniczeń tych podejść:
|
|
81
|
+
|
|
82
|
+
**Dynamiczne ładowanie**
|
|
83
|
+
|
|
84
|
+
Bez dynamicznego ładowania większość rozwiązań przechowuje komunikaty w pamięci od pierwszego renderowania, co dodaje znaczny narzut w przypadku aplikacji z wieloma trasami i lokalizacjami.
|
|
85
|
+
|
|
86
|
+
Dzięki dynamicznemu ładowaniu akceptujesz kompromis: mniej początkowego JS, ale czasami dodatkowe zapytanie przy zmianie języka.
|
|
87
|
+
|
|
88
|
+
**Dzielenie treści (Splitting)**
|
|
89
|
+
|
|
90
|
+
Składnie zbudowane wokół `t('a.b.c')` są bardzo wygodne, ale często zachęcają do utrzymywania dużych obiektów JSON w czasie wykonywania. Ten model utrudnia tree-shaking, chyba że biblioteka oferuje rzeczywistą strategię dzielenia na poszczególne strony.
|
|
91
|
+
|
|
92
|
+
## Metodologia badań
|
|
93
|
+
|
|
94
|
+
W tym benchmarku porównaliśmy następujące biblioteki:
|
|
95
|
+
|
|
96
|
+
- `Base App` (Brak biblioteki i18n)
|
|
97
|
+
- `solid-intlayer` (v8.7.12)
|
|
98
|
+
- `@solid-primitives/i18n` (v2.2.1)
|
|
99
|
+
- `solid-i18next` (v17.0.2)
|
|
100
|
+
- `@inlang/paraglide-js` (v2.17.0)
|
|
101
|
+
|
|
102
|
+
Framework to `Solid` z aplikacją wielojęzyczną składającą się z **10 stron** i **10 języków**.
|
|
103
|
+
|
|
104
|
+
Porównaliśmy **cztery strategie ładowania**:
|
|
105
|
+
|
|
106
|
+
| Strategia | Brak przestrzeni nazw (globalna) | Z przestrzeniami nazw (scoped) |
|
|
107
|
+
| :----------------------- | :------------------------------------------------ | :------------------------------------------------------------------------------- |
|
|
108
|
+
| **Ładowanie statyczne** | **Static**: Wszystko w pamięci przy starcie. | **Scoped static**: Podział na przestrzenie nazw; wszystko ładowane przy starcie. |
|
|
109
|
+
| **Ładowanie dynamiczne** | **Dynamic**: Ładowanie na żądanie na lokalizację. | **Scoped dynamic**: Szczegółowe ładowanie na przestrzeń nazw i lokalizację. |
|
|
110
|
+
|
|
111
|
+
## Podsumowanie strategii
|
|
112
|
+
|
|
113
|
+
- **Static**: Proste; brak opóźnień sieciowych po początkowym załadowaniu. Minus: duży rozmiar paczki.
|
|
114
|
+
- **Dynamic**: Zmniejsza początkową wagę (lazy-loading). Idealne, gdy masz wiele lokalizacji.
|
|
115
|
+
- **Scoped static**: Utrzymuje porządek w kodzie (logiczna separacja) bez skomplikowanych dodatkowych zapytań sieciowych.
|
|
116
|
+
- **Scoped dynamic**: Najlepsze podejście dla _code splittingu_ i wydajności. Minimalizuje zużycie pamięci, ładując tylko to, czego potrzebuje bieżący widok i aktywna lokalizacja.
|
|
117
|
+
|
|
118
|
+
## Wyniki szczegółowe
|
|
119
|
+
|
|
120
|
+
### 1 — Rozwiązania, których należy unikać
|
|
121
|
+
|
|
122
|
+
> W ekosystemie Solid nie ma jednoznacznego rozwiązania, którego należy unikać.
|
|
123
|
+
|
|
124
|
+
### 2 — Rozwiązania akceptowalne
|
|
125
|
+
|
|
126
|
+
**(solid-i18next)** (`solid-i18next@17.0.2`):
|
|
127
|
+
|
|
128
|
+
`solid-i18next` jest prawdopodobnie najpopularniejszą opcją, ponieważ był jednym z pierwszych rozwiązań zaspokajających potrzeby i18n aplikacji JavaScript. Posiada również szeroki zestaw wtyczek społecznościowych dla konkretnych problemów.
|
|
129
|
+
|
|
130
|
+
Paczka jest ciężka (~14.6kb, co stanowi około 4.7x `solid-intlayer`).
|
|
131
|
+
|
|
132
|
+
Mimo to dzieli te same główne wady co stosy technologiczne zbudowane na `t('a.b.c')`: optymalizacje są możliwe, ale bardzo czasochłonne, a duże projekty niosą ze sobą ryzyko złych praktyk (przestrzenie nazw + dynamiczne ładowanie + typy).
|
|
133
|
+
|
|
134
|
+
**(@solid-primitives/i18n)** (`@solid-primitives/i18n@2.2.1`):
|
|
135
|
+
|
|
136
|
+
Solid primitive jest niezwykle lekki i wydajny. Polecam to rozwiązanie dla lekkich projektów, ale może w nim szybko zabraknąć funkcji dla profesjonalnych rozwiązań, w tym zarządzania plikami cookie, przekierowań proxy, formaterów itp.
|
|
137
|
+
Brakuje mu również lazy loadingu i scopingu przestrzeni nazw w celu optymalizacji rozmiaru strony.
|
|
138
|
+
|
|
139
|
+
**(Paraglide)** (`@inlang/paraglide-js@2.17.0`):
|
|
140
|
+
|
|
141
|
+
`Paraglide` oferuje innowacyjne, przemyślane podejście. Mimo to w tym benchmarku reklamowany przez nich tree-shaking nie zadziałał w mojej implementacji. Workflow i DX są również bardziej złożone niż w przypadku innych opcji.
|
|
142
|
+
Osobiście nie lubię konieczności regeneracji plików JS przed każdym pushem, co stwarza ciągłe ryzyko konfliktów przy mergowaniu poprzez PR-y.
|
|
143
|
+
Wreszcie, w porównaniu z innymi rozwiązaniami, Paraglide nie używa store'a (np. Solid signal) do pobierania aktualnej lokalizacji w celu renderowania treści. Dla każdego sparsowanego węzła będzie żądać lokalizacji z localStorage / cookie itp. Prowadzi to do wykonywania niepotrzebnej logiki, która wpływa na reaktywność komponentu.
|
|
144
|
+
|
|
145
|
+
### 3 — Rekomendacje
|
|
146
|
+
|
|
147
|
+
**(Intlayer)** (`solid-intlayer@8.7.12`):
|
|
148
|
+
|
|
149
|
+
Nie będę osobiście oceniać `solid-intlayer` ze względu na obiektywizm, ponieważ jest to moje własne rozwiązanie.
|
|
150
|
+
|
|
151
|
+
### Notatka osobista
|
|
152
|
+
|
|
153
|
+
Ta notatka jest osobista i nie wpływa na wyniki benchmarku. Mimo to w świecie i18n często widać konsensus wokół wzorca takiego jak `const t = useTranslation('xx')` + `<>{t('xx.xx')}</>` dla treści przetłumaczonych.
|
|
154
|
+
|
|
155
|
+
W aplikacjach Solid wstrzykiwanie funkcji jako `JSX.Element` jest moim zdaniem antywzorcem. Dodaje to również złożoność, której można uniknąć, oraz narzut na wykonywanie JavaScriptu (nawet jeśli jest on ledwo zauważalny).
|