@intlayer/docs 5.7.8 → 5.8.0-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/blog/ar/intlayer_with_next-i18next.md +3 -4
- package/blog/ar/intlayer_with_next-intl.md +3 -4
- package/blog/ar/intlayer_with_react-i18next.md +1 -1
- package/blog/ar/intlayer_with_react-intl.md +1 -1
- package/blog/de/intlayer_with_next-i18next.md +3 -4
- package/blog/de/intlayer_with_react-intl.md +1 -1
- package/blog/en/intlayer_with_next-i18next.md +3 -4
- package/blog/en/intlayer_with_next-intl.md +3 -4
- package/blog/en/intlayer_with_react-i18next.md +1 -1
- package/blog/en/intlayer_with_react-intl.md +1 -1
- package/blog/en-GB/intlayer_with_next-i18next.md +3 -4
- package/blog/en-GB/intlayer_with_next-intl.md +3 -4
- package/blog/en-GB/intlayer_with_react-i18next.md +1 -1
- package/blog/en-GB/intlayer_with_react-intl.md +1 -1
- package/blog/es/intlayer_with_next-i18next.md +3 -4
- package/blog/es/intlayer_with_next-intl.md +3 -4
- package/blog/es/intlayer_with_react-i18next.md +1 -1
- package/blog/es/intlayer_with_react-intl.md +1 -1
- package/blog/fr/intlayer_with_next-i18next.md +3 -4
- package/blog/fr/intlayer_with_next-intl.md +3 -4
- package/blog/fr/intlayer_with_react-i18next.md +1 -1
- package/blog/fr/intlayer_with_react-intl.md +1 -1
- package/blog/hi/intlayer_with_next-i18next.md +3 -4
- package/blog/hi/intlayer_with_next-intl.md +3 -4
- package/blog/hi/intlayer_with_react-i18next.md +1 -1
- package/blog/hi/intlayer_with_react-intl.md +1 -1
- package/blog/it/intlayer_with_next-i18next.md +3 -4
- package/blog/it/intlayer_with_next-intl.md +3 -4
- package/blog/it/intlayer_with_react-i18next.md +1 -1
- package/blog/it/intlayer_with_react-intl.md +1 -1
- package/blog/ja/intlayer_with_next-i18next.md +3 -4
- package/blog/ja/intlayer_with_next-intl.md +3 -4
- package/blog/ja/intlayer_with_react-intl.md +1 -1
- package/blog/ko/intlayer_with_next-i18next.md +3 -4
- package/blog/ko/intlayer_with_next-intl.md +3 -4
- package/blog/ko/intlayer_with_react-intl.md +1 -1
- package/blog/pt/intlayer_with_next-i18next.md +3 -4
- package/blog/pt/intlayer_with_next-intl.md +3 -4
- package/blog/pt/intlayer_with_react-intl.md +1 -1
- package/blog/ru/intlayer_with_next-i18next.md +3 -4
- package/blog/ru/intlayer_with_next-intl.md +3 -4
- package/blog/ru/intlayer_with_react-i18next.md +1 -1
- package/blog/ru/intlayer_with_react-intl.md +1 -1
- package/blog/zh/intlayer_with_next-i18next.md +3 -4
- package/blog/zh/intlayer_with_next-intl.md +3 -4
- package/blog/zh/intlayer_with_react-i18next.md +1 -1
- package/blog/zh/intlayer_with_react-intl.md +1 -1
- package/dist/cjs/generated/docs.entry.cjs +41 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +41 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/formatters.md +239 -0
- package/docs/ar/interest_of_intlayer.md +162 -49
- package/docs/ar/introduction.md +3 -3
- package/docs/ar/packages/intlayer/index.md +3 -3
- package/docs/ar/packages/next-intlayer/index.md +3 -3
- package/docs/de/formatters.md +239 -0
- package/docs/de/interest_of_intlayer.md +161 -47
- package/docs/de/introduction.md +3 -3
- package/docs/de/packages/intlayer/index.md +3 -3
- package/docs/de/packages/next-intlayer/index.md +3 -3
- package/docs/de/packages/react-intlayer/index.md +3 -3
- package/docs/en/formatters.md +250 -0
- package/docs/en/interest_of_intlayer.md +159 -46
- package/docs/en/introduction.md +3 -3
- package/docs/en/packages/intlayer/index.md +3 -3
- package/docs/en/packages/next-intlayer/index.md +3 -3
- package/docs/en/packages/react-intlayer/index.md +3 -3
- package/docs/en-GB/formatters.md +239 -0
- package/docs/en-GB/interest_of_intlayer.md +160 -53
- package/docs/en-GB/packages/intlayer/index.md +3 -3
- package/docs/en-GB/packages/next-intlayer/index.md +3 -3
- package/docs/en-GB/packages/react-intlayer/index.md +3 -3
- package/docs/es/formatters.md +239 -0
- package/docs/es/interest_of_intlayer.md +159 -47
- package/docs/es/introduction.md +3 -3
- package/docs/es/packages/intlayer/index.md +3 -3
- package/docs/es/packages/next-intlayer/index.md +3 -3
- package/docs/fr/formatters.md +239 -0
- package/docs/fr/interest_of_intlayer.md +160 -46
- package/docs/fr/introduction.md +3 -3
- package/docs/fr/packages/intlayer/index.md +3 -3
- package/docs/fr/packages/next-intlayer/index.md +3 -3
- package/docs/fr/packages/react-intlayer/index.md +3 -3
- package/docs/hi/formatters.md +239 -0
- package/docs/hi/interest_of_intlayer.md +158 -42
- package/docs/hi/introduction.md +3 -3
- package/docs/hi/packages/intlayer/index.md +3 -3
- package/docs/hi/packages/next-intlayer/index.md +3 -3
- package/docs/hi/packages/react-intlayer/index.md +3 -3
- package/docs/it/formatters.md +239 -0
- package/docs/it/interest_of_intlayer.md +160 -46
- package/docs/it/introduction.md +3 -3
- package/docs/it/packages/intlayer/index.md +3 -3
- package/docs/it/packages/next-intlayer/index.md +3 -3
- package/docs/it/packages/react-intlayer/index.md +3 -3
- package/docs/ja/formatters.md +261 -0
- package/docs/ja/interest_of_intlayer.md +157 -48
- package/docs/ja/introduction.md +3 -3
- package/docs/ja/packages/intlayer/index.md +3 -3
- package/docs/ja/packages/next-intlayer/index.md +3 -3
- package/docs/ja/packages/react-intlayer/index.md +3 -3
- package/docs/ko/formatters.md +258 -0
- package/docs/ko/interest_of_intlayer.md +160 -48
- package/docs/ko/introduction.md +3 -3
- package/docs/ko/packages/intlayer/index.md +3 -3
- package/docs/ko/packages/next-intlayer/index.md +3 -3
- package/docs/ko/packages/react-intlayer/index.md +3 -3
- package/docs/pt/formatters.md +239 -0
- package/docs/pt/interest_of_intlayer.md +162 -47
- package/docs/pt/introduction.md +3 -3
- package/docs/pt/packages/intlayer/index.md +3 -3
- package/docs/pt/packages/next-intlayer/index.md +3 -3
- package/docs/pt/packages/react-intlayer/index.md +3 -3
- package/docs/ru/formatters.md +239 -0
- package/docs/ru/interest_of_intlayer.md +168 -50
- package/docs/ru/introduction.md +3 -3
- package/docs/ru/packages/intlayer/index.md +3 -3
- package/docs/ru/packages/next-intlayer/index.md +3 -3
- package/docs/ru/packages/react-intlayer/index.md +3 -3
- package/docs/zh/formatters.md +239 -0
- package/docs/zh/interest_of_intlayer.md +158 -48
- package/docs/zh/introduction.md +3 -3
- package/docs/zh/packages/intlayer/index.md +3 -3
- package/docs/zh/packages/next-intlayer/index.md +3 -3
- package/docs/zh/packages/react-intlayer/index.md +3 -3
- package/package.json +12 -12
- package/src/generated/docs.entry.ts +41 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2024-08-13
|
|
3
|
+
updatedAt: 2025-08-20
|
|
4
|
+
title: 포매터
|
|
5
|
+
description: 숫자, 백분율, 통화, 날짜, 상대 시간, 단위 및 축약 표기법에 대해 Intl 기반의 로케일 인식 포매팅 유틸리티. 캐시된 Intl 헬퍼 포함.
|
|
6
|
+
keywords:
|
|
7
|
+
- 포매터
|
|
8
|
+
- Intl
|
|
9
|
+
- 숫자
|
|
10
|
+
- 통화
|
|
11
|
+
- 백분율
|
|
12
|
+
- 날짜
|
|
13
|
+
- 상대 시간
|
|
14
|
+
- 단위
|
|
15
|
+
- 축약
|
|
16
|
+
- 국제화
|
|
17
|
+
slugs:
|
|
18
|
+
- doc
|
|
19
|
+
- formatters
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Intlayer 포매터
|
|
23
|
+
|
|
24
|
+
## 개요
|
|
25
|
+
|
|
26
|
+
Intlayer는 네이티브 `Intl` API 위에 구축된 가벼운 헬퍼 세트와, 무거운 포매터를 반복 생성하지 않도록 캐시된 `Intl` 래퍼를 제공합니다. 이 유틸리티들은 완전히 로케일 인식이 가능하며, 메인 `intlayer` 패키지에서 사용할 수 있습니다.
|
|
27
|
+
|
|
28
|
+
### 임포트
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import {
|
|
32
|
+
Intl,
|
|
33
|
+
number,
|
|
34
|
+
percentage,
|
|
35
|
+
currency,
|
|
36
|
+
date,
|
|
37
|
+
relativeTime,
|
|
38
|
+
units,
|
|
39
|
+
compact,
|
|
40
|
+
} from "intlayer";
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
React를 사용하는 경우, 훅도 제공됩니다; `react-intlayer/format`을 참조하세요.
|
|
44
|
+
|
|
45
|
+
## 캐시된 Intl
|
|
46
|
+
|
|
47
|
+
내보내진 `Intl`은 전역 `Intl`을 감싼 얇은 캐시 래퍼입니다. `NumberFormat`, `DateTimeFormat`, `RelativeTimeFormat` 인스턴스를 메모이제이션하여 동일한 포매터를 반복 생성하는 것을 방지합니다.
|
|
48
|
+
|
|
49
|
+
포매터 생성은 비교적 비용이 크기 때문에, 이 캐싱은 동작을 변경하지 않으면서 성능을 향상시킵니다. 이 래퍼는 네이티브 `Intl`과 동일한 API를 제공하므로 사용법도 동일합니다.
|
|
50
|
+
|
|
51
|
+
- 캐싱은 프로세스 단위로 이루어지며 호출자에게 투명합니다.
|
|
52
|
+
|
|
53
|
+
> 환경에 `Intl.DisplayNames`가 없으면, 개발자 전용 경고가 한 번 출력됩니다 (폴리필 사용을 고려하세요).
|
|
54
|
+
|
|
55
|
+
예시:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { Intl } from "intlayer";
|
|
59
|
+
|
|
60
|
+
const numberFormat = new Intl.NumberFormat("en-GB", {
|
|
61
|
+
style: "currency",
|
|
62
|
+
currency: "GBP",
|
|
63
|
+
});
|
|
64
|
+
numberFormat.format(1234.5); // "£1,234.50"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 포매터
|
|
68
|
+
|
|
69
|
+
아래 모든 헬퍼들은 `intlayer`에서 내보내집니다.
|
|
70
|
+
|
|
71
|
+
### `number(value, options?)`
|
|
72
|
+
|
|
73
|
+
로케일에 맞는 그룹화와 소수점 처리를 사용하여 숫자 값을 포맷합니다.
|
|
74
|
+
|
|
75
|
+
- **value**: `number | string`
|
|
76
|
+
- **options**: `Intl.NumberFormatOptions & { locale?: LocalesValues }`
|
|
77
|
+
|
|
78
|
+
예시:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { number } from "intlayer";
|
|
82
|
+
|
|
83
|
+
number(123456.789); // "123,456.789" (en-US 기준)
|
|
84
|
+
number("1000000", { locale: "fr" }); // "1 000 000"
|
|
85
|
+
number(1234.5, { minimumFractionDigits: 2 }); // "1,234.50"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `percentage(value, options?)`
|
|
89
|
+
|
|
90
|
+
숫자를 백분율 문자열로 포맷합니다.
|
|
91
|
+
|
|
92
|
+
동작: 1보다 큰 값은 전체 백분율로 해석되어 정규화됩니다(예: `25` → `25%`, `0.25` → `25%`).
|
|
93
|
+
|
|
94
|
+
- **value**: `number | string`
|
|
95
|
+
- **options**: `Intl.NumberFormatOptions & { locale?: LocalesValues }`
|
|
96
|
+
|
|
97
|
+
예시:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { percentage } from "intlayer";
|
|
101
|
+
|
|
102
|
+
percentage(0.25); // "25%"
|
|
103
|
+
percentage(25); // "25%"
|
|
104
|
+
percentage(0.237, { minimumFractionDigits: 1 }); // "23.7%"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `currency(value, options?)`
|
|
108
|
+
|
|
109
|
+
값을 현지화된 통화 형식으로 포맷합니다. 기본값은 소수점 두 자리의 `USD`입니다.
|
|
110
|
+
|
|
111
|
+
- **value**: `number | string`
|
|
112
|
+
- **options**: `Intl.NumberFormatOptions & { locale?: LocalesValues }`
|
|
113
|
+
- 공통 필드: `currency` (예: `"EUR"`), `currencyDisplay` (`"symbol" | "code" | "name"`)
|
|
114
|
+
|
|
115
|
+
예시:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { currency } from "intlayer";
|
|
119
|
+
|
|
120
|
+
currency(1234.5, { currency: "EUR" }); // "€1,234.50"
|
|
121
|
+
currency("5000", { locale: "fr", currency: "CAD", currencyDisplay: "code" }); // "5 000,00 CAD"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `date(date, optionsOrPreset?)`
|
|
125
|
+
|
|
126
|
+
`Intl.DateTimeFormat`을 사용하여 날짜/시간 값을 포맷합니다.
|
|
127
|
+
|
|
128
|
+
- **date**: `Date | string | number`
|
|
129
|
+
- **optionsOrPreset**: `Intl.DateTimeFormatOptions & { locale?: LocalesValues }` 또는 다음 프리셋 중 하나:
|
|
130
|
+
- 프리셋: `"short" | "long" | "dateOnly" | "timeOnly" | "full"`
|
|
131
|
+
|
|
132
|
+
예시:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { date } from "intlayer";
|
|
136
|
+
|
|
137
|
+
date(new Date(), "short"); // 예: "08/02/25, 14:30"
|
|
138
|
+
date("2025-08-02T14:30:00Z", { locale: "fr", month: "long", day: "numeric" }); // "2 août"
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### `relativeTime(from, to = new Date(), options?)`
|
|
142
|
+
|
|
143
|
+
`Intl.RelativeTimeFormat`을 사용하여 두 시점 간의 상대 시간을 포맷합니다.
|
|
144
|
+
|
|
145
|
+
- 자연스러운 표현을 위해 첫 번째 인수로 "now"를 전달하고 두 번째 인수로 대상 시간을 전달하세요.
|
|
146
|
+
- **from**: `Date | string | number`
|
|
147
|
+
- **to**: `Date | string | number` (기본값은 `new Date()`)
|
|
148
|
+
- **options**: `{ locale?: LocalesValues; unit?: Intl.RelativeTimeFormatUnit; numeric?: Intl.RelativeTimeFormatNumeric; style?: Intl.RelativeTimeFormatStyle }`
|
|
149
|
+
- 기본 `unit`은 `"second"`입니다.
|
|
150
|
+
|
|
151
|
+
예시:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { relativeTime } from "intlayer";
|
|
155
|
+
|
|
156
|
+
const now = new Date();
|
|
157
|
+
const in3Days = new Date(now.getTime() + 3 * 864e5);
|
|
158
|
+
relativeTime(now, in3Days, { unit: "day" }); // "3일 후"
|
|
159
|
+
|
|
160
|
+
const twoHoursAgo = new Date(now.getTime() - 2 * 3600e3);
|
|
161
|
+
relativeTime(now, twoHoursAgo, { unit: "hour", numeric: "auto" }); // "2시간 전"
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `units(value, options?)`
|
|
165
|
+
|
|
166
|
+
`Intl.NumberFormat`의 `style: 'unit'`을 사용하여 숫자 값을 현지화된 단위 문자열로 형식화합니다.
|
|
167
|
+
|
|
168
|
+
- **value**: `number | string`
|
|
169
|
+
- **options**: `Intl.NumberFormatOptions & { locale?: LocalesValues }`
|
|
170
|
+
- 공통 필드: `unit` (예: `"kilometer"`, `"byte"`), `unitDisplay` (`"short" | "narrow" | "long"`)
|
|
171
|
+
- 기본값: `unit: 'day'`, `unitDisplay: 'short'`, `useGrouping: false`
|
|
172
|
+
|
|
173
|
+
예시:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import { units } from "intlayer";
|
|
177
|
+
|
|
178
|
+
units(5, { unit: "kilometer", unitDisplay: "long", locale: "en-GB" }); // "5 kilometers"
|
|
179
|
+
units(1024, { unit: "byte", unitDisplay: "narrow" }); // "1,024B" (로케일에 따라 다름)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### `compact(value, options?)`
|
|
183
|
+
|
|
184
|
+
숫자를 축약 표기법으로 형식화합니다 (예: `1.2K`, `1M`).
|
|
185
|
+
|
|
186
|
+
- **value**: `number | string`
|
|
187
|
+
- **options**: `Intl.NumberFormatOptions & { locale?: LocalesValues }` (내부적으로 `notation: 'compact'` 사용)
|
|
188
|
+
|
|
189
|
+
예시:
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { compact } from "intlayer";
|
|
193
|
+
|
|
194
|
+
compact(1200); // "1.2K"
|
|
195
|
+
compact("1000000", { locale: "fr", compactDisplay: "long" }); // "1 million"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 참고 사항
|
|
199
|
+
|
|
200
|
+
- 모든 헬퍼는 `string` 입력을 허용하며 내부적으로 숫자나 날짜로 변환됩니다.
|
|
201
|
+
- 로케일이 제공되지 않으면 구성된 `internationalization.defaultLocale`이 기본값으로 사용됩니다.
|
|
202
|
+
- 이 유틸리티들은 얇은 래퍼이며, 고급 포맷팅이 필요할 경우 표준 `Intl` 옵션을 직접 전달하세요.
|
|
203
|
+
|
|
204
|
+
## 진입점 및 재내보내기 (`@index.ts`)
|
|
205
|
+
|
|
206
|
+
포맷터들은 코어 패키지에 위치하며, 런타임 전반에 걸쳐 임포트를 편리하게 하기 위해 상위 패키지에서 재내보내기 됩니다:
|
|
207
|
+
|
|
208
|
+
예시:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { compact } from "intlayer";
|
|
212
|
+
|
|
213
|
+
compact(1200); // "1.2K"
|
|
214
|
+
compact("1000000", { locale: "fr", compactDisplay: "long" }); // "1 million"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 참고 사항
|
|
218
|
+
|
|
219
|
+
- 모든 헬퍼는 `string` 입력을 허용하며 내부적으로 숫자나 날짜로 변환됩니다.
|
|
220
|
+
- 로케일이 제공되지 않으면 구성된 `internationalization.defaultLocale`가 기본값으로 사용됩니다.
|
|
221
|
+
- 이 유틸리티들은 얇은 래퍼이며, 고급 포맷팅이 필요할 경우 표준 `Intl` 옵션을 직접 전달하세요.
|
|
222
|
+
|
|
223
|
+
## 진입점 및 재내보내기 (`@index.ts`)
|
|
224
|
+
|
|
225
|
+
포맷터들은 코어 패키지에 위치하며, 런타임 전반에 걸쳐 임포트가 편리하도록 상위 패키지에서 재내보내기 됩니다:
|
|
226
|
+
|
|
227
|
+
예시:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
// 앱 코드 (권장)
|
|
231
|
+
import { number, currency, date, Intl } from "intlayer";
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### React
|
|
235
|
+
|
|
236
|
+
클라이언트 컴포넌트:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
import { useNumber, useCurrency, useDate } from "react-intlayer/format";
|
|
240
|
+
// 또는 Next.js 앱에서는
|
|
241
|
+
import { useNumber, useCurrency, useDate } from "next-intlayer/client/format";
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
서버 컴포넌트 (또는 React 서버 런타임):
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import { useNumber, useCurrency, useDate } from "intlayer/server/format";
|
|
248
|
+
// 또는 Next.js 앱에서는
|
|
249
|
+
import { useNumber, useCurrency, useDate } from "next-intlayer/server/format";
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
> 해당 훅들은 `IntlayerProvider` 또는 `IntlayerServerProvider`에서 로케일을 참조합니다.
|
|
253
|
+
|
|
254
|
+
## 문서 이력
|
|
255
|
+
|
|
256
|
+
| 버전 | 날짜 | 변경 사항 |
|
|
257
|
+
| ----- | ---------- | ---------------- |
|
|
258
|
+
| 5.8.0 | 2025-08-18 | 포맷터 문서 추가 |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-08-14
|
|
3
|
-
updatedAt: 2025-
|
|
4
|
-
title: Intlayer의
|
|
3
|
+
updatedAt: 2025-08-20
|
|
4
|
+
title: Intlayer의 중요성
|
|
5
5
|
description: 프로젝트에서 Intlayer를 사용할 때의 이점과 장점을 알아보세요. Intlayer가 다른 프레임워크와 차별화되는 이유를 이해하세요.
|
|
6
6
|
keywords:
|
|
7
7
|
- 이점
|
|
@@ -11,41 +11,104 @@ keywords:
|
|
|
11
11
|
- 비교
|
|
12
12
|
slugs:
|
|
13
13
|
- doc
|
|
14
|
-
-
|
|
15
|
-
- interest
|
|
14
|
+
- why
|
|
16
15
|
---
|
|
17
16
|
|
|
18
|
-
# Intlayer
|
|
17
|
+
# 왜 Intlayer를 고려해야 하나요?
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
## Intlayer란 무엇인가요?
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
**Intlayer**는 자바스크립트 개발자를 위해 특별히 설계된 국제화 라이브러리입니다. 코드 어디에서나 콘텐츠를 선언할 수 있게 해줍니다. 다국어 콘텐츠 선언을 구조화된 사전으로 변환하여 코드에 쉽게 통합할 수 있습니다. TypeScript를 사용하여 **Intlayer**는 개발을 더욱 견고하고 효율적으로 만듭니다.
|
|
22
|
+
|
|
23
|
+
## Intlayer는 왜 만들어졌나요?
|
|
24
|
+
|
|
25
|
+
Intlayer는 `next-intl`, `react-i18next`, `react-intl`, `next-i18next`, `react-intl`, `vue-i18n`과 같은 모든 일반적인 i18n 라이브러리에 영향을 미치는 공통 문제를 해결하기 위해 만들어졌습니다.
|
|
26
|
+
|
|
27
|
+
이 모든 솔루션은 콘텐츠를 나열하고 관리하기 위해 중앙 집중식 방식을 채택합니다. 예를 들어:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
.
|
|
31
|
+
├── locales
|
|
32
|
+
│ ├── en.json
|
|
33
|
+
│ ├── fr.json
|
|
34
|
+
│ └── es.json
|
|
35
|
+
├── i18n.ts
|
|
36
|
+
└── src
|
|
37
|
+
└── components
|
|
38
|
+
└── MyComponent
|
|
39
|
+
└── index.tsx
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
또는 네임스페이스를 사용하는 경우:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
.
|
|
46
|
+
├── locales
|
|
47
|
+
│ ├── en
|
|
48
|
+
│ │ ├── footer.json
|
|
49
|
+
│ │ └── navbar.json
|
|
50
|
+
│ ├── fr
|
|
51
|
+
│ │ ├── footer.json
|
|
52
|
+
│ │ └── navbar.json
|
|
53
|
+
│ └── es
|
|
54
|
+
│ ├── footer.json
|
|
55
|
+
│ └── navbar.json
|
|
56
|
+
├── i18n.ts
|
|
57
|
+
└── src
|
|
58
|
+
└── components
|
|
59
|
+
└── MyComponent
|
|
60
|
+
└── index.tsx
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
이러한 유형의 아키텍처는 개발 속도를 늦추고 코드베이스를 유지보수하기 더 복잡하게 만듭니다. 그 이유는 다음과 같습니다:
|
|
64
|
+
|
|
65
|
+
1. **새로운 컴포넌트를 생성할 때마다 해야 할 일:**
|
|
66
|
+
- `locales` 폴더에 새로운 리소스/네임스페이스를 생성해야 합니다.
|
|
67
|
+
- 페이지에서 새로운 네임스페이스를 임포트하는 것을 잊지 말아야 합니다.
|
|
68
|
+
- 콘텐츠를 번역해야 합니다 (종종 AI 제공자로부터 복사/붙여넣기로 수동으로 수행됨).
|
|
69
|
+
|
|
70
|
+
2. **컴포넌트에 변경 사항이 있을 때마다 해야 할 일:**
|
|
71
|
+
- 관련 리소스/네임스페이스를 찾아야 합니다 (컴포넌트와 멀리 떨어져 있음).
|
|
72
|
+
- 콘텐츠를 번역해야 합니다.
|
|
73
|
+
- 모든 로케일에 대해 콘텐츠가 최신 상태인지 확인해야 합니다.
|
|
74
|
+
- 네임스페이스에 사용하지 않는 키/값이 포함되어 있지 않은지 검증해야 합니다.
|
|
75
|
+
- 모든 로케일에 대해 JSON 파일의 구조가 동일한지 확인해야 합니다.
|
|
76
|
+
|
|
77
|
+
이러한 솔루션을 사용하는 전문 프로젝트에서는 콘텐츠 번역 관리를 돕기 위해 로컬라이제이션 플랫폼을 자주 사용합니다. 하지만 대규모 프로젝트에서는 비용이 빠르게 증가할 수 있습니다.
|
|
78
|
+
|
|
79
|
+
이 문제를 해결하기 위해 Intlayer는 콘텐츠를 컴포넌트별로 범위를 지정하고, CSS(`styled-components`), 타입, 문서(`storybook`), 단위 테스트(`jest`)와 같이 컴포넌트 가까이에 콘텐츠를 유지하는 방식을 채택합니다.
|
|
23
80
|
|
|
24
81
|
```bash codeFormat="typescript"
|
|
25
82
|
.
|
|
26
|
-
└──
|
|
83
|
+
└── components
|
|
27
84
|
└── MyComponent
|
|
28
|
-
├── index.content.
|
|
85
|
+
├── index.content.tsx
|
|
86
|
+
├── index.test.tsx
|
|
87
|
+
├── index.stories.tsx
|
|
29
88
|
└── index.tsx
|
|
30
89
|
```
|
|
31
90
|
|
|
32
91
|
```bash codeFormat="commonjs"
|
|
33
92
|
.
|
|
34
|
-
└──
|
|
93
|
+
└── components
|
|
35
94
|
└── MyComponent
|
|
36
95
|
├── index.content.cjs
|
|
37
|
-
|
|
96
|
+
├── index.test.mjs
|
|
97
|
+
├── index.stories.mjs
|
|
98
|
+
└── index.tsx
|
|
38
99
|
```
|
|
39
100
|
|
|
40
101
|
```bash codeFormat="esm"
|
|
41
102
|
.
|
|
42
|
-
└──
|
|
103
|
+
└── components
|
|
43
104
|
└── MyComponent
|
|
44
105
|
├── index.content.mjs
|
|
45
|
-
|
|
106
|
+
├── index.test.mjs
|
|
107
|
+
├── index.stories.mjs
|
|
108
|
+
└── index.tsx
|
|
46
109
|
```
|
|
47
110
|
|
|
48
|
-
```tsx fileName="./
|
|
111
|
+
```tsx fileName="./components/MyComponent/index.content.ts" codeFormat="typescript"
|
|
49
112
|
import { t, type Dictionary } from "intlayer";
|
|
50
113
|
|
|
51
114
|
const componentExampleContent = {
|
|
@@ -53,8 +116,8 @@ const componentExampleContent = {
|
|
|
53
116
|
content: {
|
|
54
117
|
myTranslatedContent: t({
|
|
55
118
|
en: "Hello World",
|
|
56
|
-
fr: "Bonjour le monde",
|
|
57
119
|
es: "Hola Mundo",
|
|
120
|
+
fr: "Bonjour le monde",
|
|
58
121
|
}),
|
|
59
122
|
},
|
|
60
123
|
} satisfies Dictionary;
|
|
@@ -62,18 +125,18 @@ const componentExampleContent = {
|
|
|
62
125
|
export default componentExampleContent;
|
|
63
126
|
```
|
|
64
127
|
|
|
65
|
-
```jsx fileName="./
|
|
128
|
+
```jsx fileName="./components/MyComponent/index.mjx" codeFormat="esm"
|
|
66
129
|
import { t } from "intlayer";
|
|
67
130
|
|
|
68
131
|
/** @type {import('intlayer').Dictionary} */
|
|
69
|
-
// 다국어 콘텐츠를 포함하는 컴포넌트 예제 내용 정의
|
|
70
132
|
const componentExampleContent = {
|
|
71
133
|
key: "component-example",
|
|
72
134
|
content: {
|
|
73
135
|
myTranslatedContent: t({
|
|
74
136
|
en: "Hello World",
|
|
75
|
-
fr: "Bonjour le monde",
|
|
76
137
|
es: "Hola Mundo",
|
|
138
|
+
fr: "Bonjour le monde",
|
|
139
|
+
ko: "안녕하세요 세계",
|
|
77
140
|
}),
|
|
78
141
|
},
|
|
79
142
|
};
|
|
@@ -81,18 +144,18 @@ const componentExampleContent = {
|
|
|
81
144
|
export default componentExampleContent;
|
|
82
145
|
```
|
|
83
146
|
|
|
84
|
-
```jsx fileName="./
|
|
147
|
+
```jsx fileName="./components/MyComponent/index.csx" codeFormat="commonjs"
|
|
85
148
|
const { t } = require("intlayer");
|
|
86
149
|
|
|
87
150
|
/** @type {import('intlayer').Dictionary} */
|
|
88
|
-
// 다국어 콘텐츠를 포함하는 컴포넌트 예제 내용 정의
|
|
89
151
|
const componentExampleContent = {
|
|
90
152
|
key: "component-example",
|
|
91
153
|
content: {
|
|
92
154
|
myTranslatedContent: t({
|
|
93
155
|
en: "Hello World",
|
|
94
|
-
fr: "Bonjour le monde",
|
|
95
156
|
es: "Hola Mundo",
|
|
157
|
+
fr: "Bonjour le monde",
|
|
158
|
+
ko: "안녕하세요 세계",
|
|
96
159
|
}),
|
|
97
160
|
},
|
|
98
161
|
};
|
|
@@ -100,10 +163,9 @@ const componentExampleContent = {
|
|
|
100
163
|
module.exports = componentExampleContent;
|
|
101
164
|
```
|
|
102
165
|
|
|
103
|
-
```tsx fileName="./
|
|
166
|
+
```tsx fileName="./components/MyComponent/index.tsx" codeFormat="typescript"
|
|
104
167
|
import { useIntlayer } from "react-intlayer";
|
|
105
168
|
|
|
106
|
-
// 컴포넌트 예제 정의
|
|
107
169
|
export const ComponentExample = () => {
|
|
108
170
|
const { myTranslatedContent } = useIntlayer("component-example");
|
|
109
171
|
|
|
@@ -111,10 +173,9 @@ export const ComponentExample = () => {
|
|
|
111
173
|
};
|
|
112
174
|
```
|
|
113
175
|
|
|
114
|
-
```jsx fileName="./
|
|
176
|
+
```jsx fileName="./components/MyComponent/index.mjx" codeFormat="esm"
|
|
115
177
|
import { useIntlayer } from "react-intlayer";
|
|
116
178
|
|
|
117
|
-
// 컴포넌트 예제 정의
|
|
118
179
|
const ComponentExample = () => {
|
|
119
180
|
const { myTranslatedContent } = useIntlayer("component-example");
|
|
120
181
|
|
|
@@ -122,10 +183,9 @@ const ComponentExample = () => {
|
|
|
122
183
|
};
|
|
123
184
|
```
|
|
124
185
|
|
|
125
|
-
```jsx fileName="./
|
|
186
|
+
```jsx fileName="./components/MyComponent/index.csx" codeFormat="commonjs"
|
|
126
187
|
const { useIntlayer } = require("react-intlayer");
|
|
127
188
|
|
|
128
|
-
// 컴포넌트 예제 정의
|
|
129
189
|
const ComponentExample = () => {
|
|
130
190
|
const { myTranslatedContent } = useIntlayer("component-example");
|
|
131
191
|
|
|
@@ -133,27 +193,79 @@ const ComponentExample = () => {
|
|
|
133
193
|
};
|
|
134
194
|
```
|
|
135
195
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
196
|
+
이 접근 방식은 다음을 가능하게 합니다:
|
|
197
|
+
|
|
198
|
+
1. **개발 속도 향상**
|
|
199
|
+
- `.content.{{ts|mjs|cjs|json}}` 파일은 VSCode 확장 기능을 사용하여 생성할 수 있습니다.
|
|
200
|
+
- IDE 내 자동완성 AI 도구(예: GitHub Copilot)가 콘텐츠 선언을 도와 복사/붙여넣기 작업을 줄여줍니다.
|
|
201
|
+
|
|
202
|
+
2. **코드베이스의 복잡성 감소**
|
|
203
|
+
|
|
204
|
+
3. **코드베이스의 유지보수성 향상**
|
|
205
|
+
|
|
206
|
+
4. **컴포넌트와 관련 콘텐츠를 더 쉽게 복제하기 (예: 로그인/회원가입 컴포넌트 등)**
|
|
207
|
+
- 다른 컴포넌트의 콘텐츠에 영향을 미칠 위험을 제한하여
|
|
208
|
+
- 외부 의존성 없이 한 애플리케이션에서 다른 애플리케이션으로 콘텐츠를 복사/붙여넣기 가능
|
|
209
|
+
|
|
210
|
+
5. **사용하지 않는 컴포넌트의 키/값으로 코드베이스를 오염시키지 않음**
|
|
211
|
+
- 컴포넌트를 사용하지 않는다면, 해당 콘텐츠를 임포트할 필요가 없습니다.
|
|
212
|
+
- 컴포넌트를 삭제하면 관련 콘텐츠가 동일한 폴더에 존재하기 때문에 관련 콘텐츠를 더 쉽게 제거할 수 있습니다.
|
|
213
|
+
|
|
214
|
+
6. **AI 에이전트가 다국어 콘텐츠를 선언하는 데 드는 추론 비용 감소**
|
|
215
|
+
- AI 에이전트가 콘텐츠를 구현할 위치를 알기 위해 전체 코드베이스를 스캔할 필요가 없습니다.
|
|
216
|
+
- IDE 내 자동완성 AI 도구(예: GitHub Copilot)를 통해 번역 작업을 쉽게 수행할 수 있습니다.
|
|
217
|
+
|
|
218
|
+
7. **로딩 성능 최적화**
|
|
219
|
+
- 컴포넌트가 지연 로드(lazy-loaded)되는 경우, 관련 콘텐츠도 동시에 로드됩니다.
|
|
220
|
+
|
|
221
|
+
## Intlayer의 추가 기능
|
|
222
|
+
|
|
223
|
+
| 기능 | 설명 |
|
|
224
|
+
| ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
225
|
+
|  | **크로스 프레임워크 지원**<br><br>Intlayer는 Next.js, React, Vite, Vue.js, Nuxt, Preact, Express 등 주요 프레임워크와 라이브러리를 모두 지원합니다. |
|
|
226
|
+
|  | **자바스크립트 기반 콘텐츠 관리**<br><br>자바스크립트의 유연성을 활용하여 콘텐츠를 효율적으로 정의하고 관리하세요. <br><br> - [콘텐츠 선언](https://intlayer.org/doc/concept/content) |
|
|
227
|
+
|  | **로케일별 콘텐츠 선언 파일**<br><br>자동 생성 전에 콘텐츠를 한 번 선언하여 개발 속도를 높이세요.<br><br> - [로케일별 콘텐츠 선언 파일](https://intlayer.org/doc/concept/per-locale-file) |
|
|
228
|
+
|  | **타입 안전 환경**<br><br>TypeScript를 활용하여 콘텐츠 정의와 코드에 오류가 없도록 보장하고, IDE 자동 완성 기능도 함께 누리세요.<br><br> - [TypeScript 설정](https://intlayer.org/doc/environment/vite-and-react#configure-typescript) |
|
|
229
|
+
|  | **간소화된 설정**<br><br>최소한의 구성으로 빠르게 시작하세요. 국제화, 라우팅, AI, 빌드 및 콘텐츠 처리 설정을 손쉽게 조정할 수 있습니다.<br><br> - [Next.js 통합 탐색](https://intlayer.org/doc/environment/nextjs) |
|
|
230
|
+
|  | **간소화된 콘텐츠 조회**<br><br>각 콘텐츠마다 `t` 함수를 호출할 필요가 없습니다. 단일 훅을 사용하여 모든 콘텐츠를 직접 조회하세요.<br><br> - [React 통합](https://intlayer.org/doc/environment/create-react-app) |
|
|
231
|
+
|  | **일관된 서버 컴포넌트 구현**<br><br>Next.js 서버 컴포넌트에 완벽하게 적합하며, 클라이언트와 서버 컴포넌트 모두에 동일한 구현을 사용할 수 있습니다. 각 서버 컴포넌트마다 `t` 함수를 전달할 필요가 없습니다. <br><br> - [서버 컴포넌트](https://intlayer.org/doc/environment/nextjs#step-7-utilize-content-in-your-code) |
|
|
232
|
+
|  | **체계적인 코드베이스**<br><br>코드베이스를 더 체계적으로 유지하세요: 1 컴포넌트 = 같은 폴더 내 1 사전. 각 컴포넌트에 가까운 번역은 유지보수성과 명확성을 향상시킵니다. <br><br> - [Intlayer 작동 방식](https://intlayer.org/doc/concept/how-works-intlayer) |
|
|
233
|
+
|  | **향상된 라우팅**<br><br>Next.js, React, Vite, Vue.js 등 복잡한 애플리케이션 구조에 원활하게 적응하는 앱 라우팅을 완벽하게 지원합니다.<br><br> - [Next.js 통합 탐색하기](https://intlayer.org/doc/environment/nextjs) |
|
|
234
|
+
|  | **마크다운 지원**<br><br>개인정보 처리방침, 문서 등 다국어 콘텐츠를 위해 로케일 파일과 원격 마크다운을 가져와 해석합니다. 마크다운 메타데이터를 해석하여 코드에서 접근할 수 있도록 합니다.<br><br> - [콘텐츠 파일](https://intlayer.org/doc/concept/content/file) |
|
|
235
|
+
|  | **무료 비주얼 에디터 및 CMS**<br><br>콘텐츠 작성자를 위해 무료 비주얼 에디터와 CMS가 제공되어 로컬라이제이션 플랫폼이 필요 없습니다. Git을 사용하여 콘텐츠를 동기화 상태로 유지하거나 CMS를 통해 콘텐츠를 완전히 또는 부분적으로 외부화할 수 있습니다.<br><br> - [Intlayer 에디터](https://intlayer.org/doc/concept/editor) <br> - [Intlayer CMS](https://intlayer.org/doc/concept/cms) |
|
|
236
|
+
|  | **트리 쉐이커블 콘텐츠**<br><br>최종 번들의 크기를 줄이는 트리 쉐이커블 콘텐츠입니다. 각 컴포넌트별로 콘텐츠를 로드하며, 사용하지 않는 콘텐츠는 번들에서 제외합니다. 앱 로딩 효율을 높이기 위해 지연 로딩도 지원합니다. <br><br> - [앱 빌드 최적화](https://intlayer.org/doc/concept/how-works-intlayer#app-build-optimization) |
|
|
237
|
+
|  | **정적 렌더링**<br><br>정적 렌더링을 차단하지 않습니다. <br><br> - [Next.js 통합](https://intlayer.org/doc/environment/nextjs) |
|
|
238
|
+
|  | **AI 기반 번역**<br><br>Intlayer의 고급 AI 기반 번역 도구를 사용하여 자신의 AI 제공자/API 키로 단 한 번의 클릭만으로 웹사이트를 231개 언어로 변환하세요. <br><br> - [CI/CD 통합](https://intlayer.org/doc/concept/ci-cd) <br> - [Intlayer CLI](https://intlayer.org/doc/concept/cli) <br> - [자동 채우기](https://intlayer.org/doc/concept/auto-fill) |
|
|
239
|
+
|  | **MCP 서버 통합**<br><br>IDE 자동화를 위한 MCP(모델 컨텍스트 프로토콜) 서버를 제공하여 개발 환경 내에서 원활한 콘텐츠 관리 및 국제화(i18n) 워크플로우를 가능하게 합니다. <br><br> - [MCP 서버](https://github.com/aymericzip/intlayer/blob/main/docs/docs/ko/mcp_server.md) |
|
|
240
|
+
|  | **VSCode 확장 기능**<br><br>Intlayer는 콘텐츠 및 번역 관리를 돕기 위해 VSCode 확장 기능을 제공합니다. 사전을 구축하고, 콘텐츠를 번역하는 등 다양한 작업을 지원합니다. <br><br> - [VSCode 확장 기능](https://intlayer.org/doc/vs-code-extension) |
|
|
241
|
+
|  | **상호 운용성**<br><br>react-i18next, next-i18next, next-intl, react-intl과의 상호 운용성을 지원합니다. <br><br> - [Intlayer와 react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer와 next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer와 next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) |
|
|
242
|
+
|
|
243
|
+
## Intlayer와 다른 솔루션 비교
|
|
244
|
+
|
|
245
|
+
| 기능 | Intlayer | React-i18next / i18next | React-Intl (FormatJS) | LinguiJS | next-intl | next-i18next | vue-i18n |
|
|
246
|
+
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------- |
|
|
247
|
+
| **컴포넌트 근처 번역** | 예, 각 컴포넌트와 함께 배치된 콘텐츠 | 아니요 | 아니요 | 아니요 | 아니요 | 아니요 | 예 - `Single File Components` (SFCs) 사용 |
|
|
248
|
+
| **TypeScript 통합** | 고급, 자동 생성 엄격한 타입 | 기본; 안전을 위한 추가 구성 필요 | 좋음, 하지만 덜 엄격함 | 타입 정의, 구성 필요 | 좋음 | 기본 | 좋음 (타입 사용 가능; 키 안전성 설정 필요) |
|
|
249
|
+
| **누락된 번역 감지** | 빌드 시 오류/경고 | 대부분 런타임 시 대체 문자열 사용 | 대체 문자열 사용 | 추가 설정 필요 | 런타임 대체 문자열 사용 | 런타임 대체 문자열 사용 | 런타임 대체 문자열/경고 (설정 가능) |
|
|
250
|
+
| **리치 콘텐츠 (JSX/마크다운/컴포넌트)** | React 노드까지 직접 지원 | 제한적 / 보간법만 지원 | ICU 문법, 실제 JSX 아님 | 제한적 | 리치 노드를 위해 설계되지 않음 | 제한적 | 제한적 (`<i18n-t>`를 통한 컴포넌트, 플러그인을 통한 마크다운) |
|
|
251
|
+
| **AI 기반 번역** | 예, 여러 AI 제공업체를 지원합니다. 자체 API 키를 사용하여 사용할 수 있습니다. 애플리케이션 및 콘텐츠 범위의 컨텍스트를 고려합니다. | 아니요 | 아니요 | 아니요 | 아니요 | 아니요 | 아니요 |
|
|
252
|
+
| **비주얼 에디터** | 예, 로컬 비주얼 에디터 + 선택적 CMS; 코드베이스 콘텐츠 외부화 가능; 임베드 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 | 아니요 / 외부 현지화 플랫폼을 통해 사용 가능 |
|
|
253
|
+
| **로컬라이즈된 라우팅** | 내장, 미들웨어 지원 | 플러그인 또는 수동 구성 | 내장되어 있지 않음 | 플러그인/수동 구성 | 내장 | 내장 | Vue Router를 통한 수동 구성 (Nuxt i18n이 처리함) |
|
|
254
|
+
| **동적 라우트 생성** | 예 | 플러그인/에코시스템 또는 수동 설정 | 제공되지 않음 | 플러그인/수동 | 예 | 예 | 제공되지 않음 (Nuxt i18n에서 제공) |
|
|
255
|
+
| **복수형 처리(Pluralization)** | 열거 기반 패턴; 문서 참조 | 구성 가능 (i18next-icu와 같은 플러그인) | 고급 (ICU) | 고급 (ICU/messageformat) | 우수 | 우수 | 고급 (내장된 복수형 규칙) |
|
|
256
|
+
| **형식 지정(날짜, 숫자, 통화)** | 최적화된 포매터(Intl 기반) | 플러그인 또는 맞춤 Intl 사용을 통해 | 고급 ICU 포매터 | ICU/CLI 도우미 | 우수함 (Intl 도우미) | 우수함 (Intl 도우미) | 내장 날짜/숫자 포매터(Intl) |
|
|
257
|
+
| **콘텐츠 형식** | .tsx, .ts, .js, .json, .md, .txt | .json | .json, .js | .po, .json | .json, .js, .ts | .json | .json, .js |
|
|
258
|
+
| **ICU 지원** | 진행 중 (네이티브 ICU) | 플러그인 사용 (i18next-icu) | 예 | 예 | 예 | 플러그인 사용 (i18next-icu) | 맞춤 포매터/컴파일러 사용 |
|
|
259
|
+
| **SEO 도우미 (hreflang, 사이트맵)** | 내장 도구: 사이트맵, **robots.txt**, 메타데이터 도우미 | 커뮤니티 플러그인/수동 | 핵심 아님 | 핵심 아님 | 우수 | 우수 | 핵심 아님 (Nuxt i18n이 도우미 제공) |
|
|
260
|
+
| **에코시스템 / 커뮤니티** | 작지만 빠르게 성장하고 반응성이 뛰어남 | 가장 크고 가장 성숙함 | 대규모, 엔터프라이즈 | 성장 중, 작음 | 중간 규모, Next.js 중심 | 중간 규모, Next.js 중심 | Vue 에코시스템 내 대규모 |
|
|
261
|
+
| **서버 사이드 렌더링 및 서버 컴포넌트** | 예, SSR / React 서버 컴포넌트에 최적화되어 있음 | 지원되나 일부 설정 필요 | Next.js에서 지원됨 | 지원됨 | 완전 지원 | 완전 지원 | Nuxt/Vue SSR을 통한 SSR (RSC는 없음) |
|
|
262
|
+
| **트리 쉐이킹 (사용된 콘텐츠만 로드)** | 예, Babel/SWC 플러그인을 통한 빌드 시 컴포넌트별로 | 보통 모두 로드됨 (네임스페이스/코드 분할로 개선 가능) | 보통 모두 로드됨 | 기본값 아님 | 부분 지원 | 부분 지원 | 부분 지원 (코드 분할/수동 설정 필요) |
|
|
263
|
+
| **지연 로딩** | 예, 로케일별/컴포넌트별 | 예 (예: 백엔드/네임스페이스 필요 시 로딩) | 예 (로케일 번들 분할) | 예 (동적 카탈로그 임포트) | 예 (경로별/로케일별) | 예 (경로별/로케일별) | 예 (비동기 로케일 메시지) |
|
|
264
|
+
| **대규모 프로젝트 관리** | 모듈화 권장, 디자인 시스템에 적합 | 파일 관리 규율 필요 | 중앙 카탈로그가 커질 수 있음 | 복잡해질 수 있음 | 설정과 함께 모듈화 | 설정과 함께 모듈화 | Vue Router/Nuxt i18n 설정과 함께 모듈화 |
|
|
156
265
|
|
|
157
266
|
## 문서 이력
|
|
158
267
|
|
|
159
|
-
|
|
268
|
+
| 버전 | 날짜 | 변경 사항 |
|
|
269
|
+
| ------ | ---------- | ---------------- |
|
|
270
|
+
| 5.8.0 | 2025-08-19 | 비교 표 업데이트 |
|
|
271
|
+
| 5.5.10 | 2025-06-29 | 이력 초기화 |
|
package/docs/ko/introduction.md
CHANGED
|
@@ -44,8 +44,8 @@ const componentContent = {
|
|
|
44
44
|
content: {
|
|
45
45
|
myTranslatedContent: t({
|
|
46
46
|
en: "Hello World",
|
|
47
|
-
fr: "Bonjour le monde",
|
|
48
47
|
es: "Hola Mundo",
|
|
48
|
+
fr: "Bonjour le monde",
|
|
49
49
|
}),
|
|
50
50
|
},
|
|
51
51
|
} satisfies Dictionary;
|
|
@@ -63,8 +63,8 @@ const componentContent = {
|
|
|
63
63
|
content: {
|
|
64
64
|
myTranslatedContent: t({
|
|
65
65
|
en: "Hello World",
|
|
66
|
-
fr: "Bonjour le monde",
|
|
67
66
|
es: "Hola Mundo",
|
|
67
|
+
fr: "Bonjour le monde",
|
|
68
68
|
}),
|
|
69
69
|
},
|
|
70
70
|
};
|
|
@@ -82,8 +82,8 @@ const componentContent = {
|
|
|
82
82
|
content: {
|
|
83
83
|
myTranslatedContent: t({
|
|
84
84
|
en: "Hello World",
|
|
85
|
-
fr: "Bonjour le monde",
|
|
86
85
|
es: "Hola Mundo",
|
|
86
|
+
fr: "Bonjour le monde",
|
|
87
87
|
}),
|
|
88
88
|
},
|
|
89
89
|
};
|