0
# ICU Message Format Support
1
2
React i18next provides compile-time ICU message format support through Babel macros, offering both template literal functions and React components for pluralization, selection, and formatting.
3
4
## Package Import
5
6
```typescript
7
import { Plural, Select, plural, select, date, time, number } from "react-i18next/icu.macro";
8
```
9
10
## Capabilities
11
12
### Template Literal Functions
13
14
Compile-time template literal functions that transform ICU syntax into i18next-compatible translations.
15
16
```typescript { .api }
17
/**
18
* Date formatting with ICU syntax (compile-time transformation)
19
* @param strings - Template string array
20
* @param variable - Date value to format
21
* @returns Formatted date string
22
*/
23
function date(strings: TemplateStringsArray, variable: Date): string;
24
25
/**
26
* Time formatting with ICU syntax (compile-time transformation)
27
* @param strings - Template string array
28
* @param variable - Date value to format time from
29
* @returns Formatted time string
30
*/
31
function time(strings: TemplateStringsArray, variable: Date): string;
32
33
/**
34
* Number formatting with ICU syntax (compile-time transformation)
35
* @param strings - Template string array
36
* @param variable - Number value to format
37
* @returns Formatted number string
38
*/
39
function number(strings: TemplateStringsArray, variable: number): string;
40
41
/**
42
* Pluralization with ICU syntax (compile-time transformation)
43
* @param strings - Template string array with plural forms
44
* @param variable - Count value for pluralization
45
* @param args - Additional interpolation values
46
* @returns Pluralized string
47
*/
48
function plural(
49
strings: TemplateStringsArray,
50
variable: number,
51
...args: ValidInterpolations[]
52
): string;
53
54
/**
55
* Ordinal selection with ICU syntax (compile-time transformation)
56
* @param strings - Template string array with ordinal forms
57
* @param variable - Number value for ordinal selection
58
* @param args - Additional interpolation values
59
* @returns Ordinal string
60
*/
61
function selectOrdinal(
62
strings: TemplateStringsArray,
63
variable: number,
64
...args: ValidInterpolations[]
65
): string;
66
67
/**
68
* Value selection with ICU syntax (compile-time transformation)
69
* @param strings - Template string array with selection options
70
* @param variable - String value for selection
71
* @param args - Additional interpolation values
72
* @returns Selected string
73
*/
74
function select(
75
strings: TemplateStringsArray,
76
variable: string,
77
...args: ValidInterpolations[]
78
): string;
79
80
type ValidInterpolations = React.ReactElement | string;
81
```
82
83
**Usage Examples:**
84
85
```typescript
86
import { plural, select, date, time, number } from "react-i18next/icu.macro";
87
88
// Pluralization
89
function ItemCounter({ count }) {
90
const message = plural`You have ${count} {count, plural,
91
=0 {no items}
92
one {# item}
93
other {# items}
94
}`;
95
96
return <p>{message}</p>;
97
}
98
99
// Selection
100
function GenderGreeting({ person }) {
101
const greeting = select`Hello ${person.name}, {${person.gender}, select,
102
male {Mr. ${person.name}}
103
female {Ms. ${person.name}}
104
other {${person.name}}
105
}`;
106
107
return <span>{greeting}</span>;
108
}
109
110
// Date formatting
111
function EventDate({ event }) {
112
const formatted = date`Event date: ${event.date}`;
113
return <time>{formatted}</time>;
114
}
115
116
// Time formatting
117
function CurrentTime({ now }) {
118
const timeStr = time`Current time: ${now}`;
119
return <span>{timeStr}</span>;
120
}
121
122
// Number formatting
123
function Price({ amount }) {
124
const price = number`Price: ${amount}`;
125
return <span className="price">{price}</span>;
126
}
127
128
// Ordinal numbers
129
function Position({ rank }) {
130
const position = selectOrdinal`You finished ${rank} {${rank}, selectordinal,
131
one {#st}
132
two {#nd}
133
few {#rd}
134
other {#th}
135
}`;
136
137
return <div>{position}</div>;
138
}
139
140
// Complex example with multiple interpolations
141
function OrderStatus({ order, customer }) {
142
const status = plural`Order for ${customer} has ${order.itemCount} {${order.itemCount}, plural,
143
=0 {no items}
144
one {# item}
145
other {# items}
146
} and costs ${number`${order.total}`}`;
147
148
return <p>{status}</p>;
149
}
150
```
151
152
### React Components
153
154
React components providing runtime ICU message format support without compile-time transformation.
155
156
```typescript { .api }
157
/**
158
* Pluralization component with props-based configuration
159
* @param props - Plural component properties
160
*/
161
function Plural<
162
T,
163
Key extends ParseKeys<Ns, {}, ''>,
164
Ns extends Namespace = TypeOptions['defaultNS']
165
>(props: PluralProps<T, Key, Ns> & NoChildren): ReactElement;
166
167
/**
168
* Ordinal selection component with props-based configuration
169
* @param props - SelectOrdinal component properties
170
*/
171
function SelectOrdinal<
172
T,
173
Key extends ParseKeys<Ns, {}, ''>,
174
Ns extends Namespace = TypeOptions['defaultNS']
175
>(props: PluralProps<T, Key, Ns> & NoChildren): ReactElement;
176
177
/**
178
* Value selection component with props-based configuration
179
* @param props - Select component properties
180
*/
181
function Select<
182
Key extends ParseKeys<Ns, {}, ''>,
183
Ns extends Namespace = TypeOptions['defaultNS']
184
>(props: SelectProps<Key, Ns>): ReactElement;
185
186
// Component prop interfaces
187
interface PluralSubProps<Key, Ns> {
188
children?: never;
189
i18nKey?: Key;
190
i18n?: i18n;
191
ns?: Ns;
192
count: number;
193
values?: {};
194
zero?: string | ReactElement;
195
one?: string | ReactElement;
196
two?: string | ReactElement;
197
few?: string | ReactElement;
198
many?: string | ReactElement;
199
other: string | ReactElement; // Required
200
}
201
202
type PluralProps<T, Key, Ns> = {
203
[P in keyof T]: P extends keyof PluralSubProps<Key, Ns>
204
? PluralSubProps<Key, Ns>[P]
205
: P extends `$${number}`
206
? string | ReactElement
207
: never;
208
};
209
210
interface SelectProps<Key, Ns> {
211
[key: string]: string | ReactElement;
212
i18nKey?: Key;
213
i18n?: i18n;
214
ns?: Ns;
215
other: string | ReactElement; // Required
216
children?: never;
217
}
218
219
interface NoChildren {
220
children?: never;
221
}
222
```
223
224
**Usage Examples:**
225
226
```typescript
227
import { Plural, Select, SelectOrdinal } from "react-i18next/icu.macro";
228
229
// Plural component
230
function MessageCount({ count }) {
231
return (
232
<Plural
233
i18nKey="messageCount"
234
count={count}
235
zero="No messages"
236
one="One message"
237
other="{{count}} messages"
238
/>
239
);
240
}
241
242
// Select component
243
function UserRole({ user }) {
244
return (
245
<Select
246
i18nKey="userGreeting"
247
role={user.role}
248
admin="Welcome, Administrator!"
249
user="Hello, User!"
250
guest="Welcome, Guest!"
251
other="Welcome!"
252
/>
253
);
254
}
255
256
// SelectOrdinal component
257
function RankDisplay({ position }) {
258
return (
259
<SelectOrdinal
260
i18nKey="ranking"
261
count={position}
262
one="{{count}}st place"
263
two="{{count}}nd place"
264
few="{{count}}rd place"
265
other="{{count}}th place"
266
/>
267
);
268
}
269
270
// Complex plural with custom values
271
function OrderSummary({ order }) {
272
return (
273
<div>
274
<Plural
275
i18nKey="orderItems"
276
count={order.items.length}
277
values={{
278
customerName: order.customer,
279
orderDate: order.date
280
}}
281
zero="Order for {{customerName}} on {{orderDate}} has no items"
282
one="Order for {{customerName}} on {{orderDate}} has {{count}} item"
283
other="Order for {{customerName}} on {{orderDate}} has {{count}} items"
284
/>
285
</div>
286
);
287
}
288
289
// Dynamic select options
290
function StatusBadge({ status, options }) {
291
const selectProps = {
292
i18nKey: "status",
293
status: status,
294
other: "Unknown status",
295
...options // Dynamic options like { active: "Active", inactive: "Inactive" }
296
};
297
298
return <Select {...selectProps} />;
299
}
300
301
// With namespace
302
function LocalizedPlural({ count }) {
303
return (
304
<Plural
305
ns="commerce"
306
i18nKey="cartItems"
307
count={count}
308
zero="Empty cart"
309
one="{{count}} item in cart"
310
other="{{count}} items in cart"
311
/>
312
);
313
}
314
```
315
316
### Runtime Fallback Functions
317
318
Dummy functions exported from main package for runtime fallback when macros aren't processed.
319
320
```typescript { .api }
321
/**
322
* Runtime fallback functions (return empty strings when macros not processed)
323
* Available from main react-i18next import
324
*/
325
const date: () => string;
326
const time: () => string;
327
const number: () => string;
328
const select: () => string;
329
const plural: () => string;
330
const selectOrdinal: () => string;
331
```
332
333
**Usage Examples:**
334
335
```typescript
336
import { date, time, number, plural } from "react-i18next";
337
338
// These return empty strings at runtime if macros aren't processed
339
function Fallbacks() {
340
return (
341
<div>
342
<p>{date()}</p> {/* Returns "" */}
343
<p>{time()}</p> {/* Returns "" */}
344
<p>{number()}</p> {/* Returns "" */}
345
<p>{plural()}</p> {/* Returns "" */}
346
</div>
347
);
348
}
349
```
350
351
## Babel Configuration
352
353
The ICU macro requires Babel configuration to process template literals at compile time:
354
355
```javascript
356
// babel.config.js
357
module.exports = {
358
plugins: [
359
'macros', // or 'babel-plugin-macros'
360
],
361
};
362
363
// .babelrc
364
{
365
"plugins": ["macros"]
366
}
367
```
368
369
## Translation File Generation
370
371
ICU macros can generate corresponding translation files:
372
373
```typescript
374
// Source code with ICU macro
375
const message = plural`You have ${count} {count, plural,
376
=0 {no items}
377
one {# item}
378
other {# items}
379
}`;
380
381
// Generated translation entry
382
{
383
"generated_plural_key": "You have {{count}} {{count, plural, =0{no items} one{# item} other{# items}}}"
384
}
385
```
386
387
## Advanced Usage
388
389
### Mixed ICU and i18next
390
391
```typescript
392
import { useTranslation } from "react-i18next";
393
import { plural, select } from "react-i18next/icu.macro";
394
395
function MixedExample({ user, itemCount }) {
396
const { t } = useTranslation();
397
398
// Regular i18next
399
const welcome = t('welcome', { name: user.name });
400
401
// ICU macro
402
const items = plural`You have ${itemCount} {${itemCount}, plural,
403
=0 {no items}
404
one {# item}
405
other {# items}
406
}`;
407
408
const greeting = select`{${user.type}, select,
409
premium {Welcome, Premium Member!}
410
standard {Hello, Member!}
411
other {Welcome!}
412
}`;
413
414
return (
415
<div>
416
<h1>{welcome}</h1>
417
<p>{greeting}</p>
418
<p>{items}</p>
419
</div>
420
);
421
}
422
```
423
424
### Conditional ICU Usage
425
426
```typescript
427
// Feature detection for ICU support
428
const hasICUSupport = typeof Intl !== 'undefined' && Intl.PluralRules;
429
430
function AdaptiveComponent({ count }) {
431
if (hasICUSupport) {
432
return (
433
<Plural
434
count={count}
435
zero="No items"
436
one="One item"
437
other="{{count}} items"
438
/>
439
);
440
}
441
442
// Fallback to simple conditional
443
const { t } = useTranslation();
444
return <span>{t('itemCount', { count })}</span>;
445
}
446
```
447
448
## Type Safety
449
450
```typescript { .api }
451
// Type definitions for ICU macro components
452
type ICUInterpolation = string | React.ReactElement;
453
454
interface ICUPluralForms {
455
zero?: ICUInterpolation;
456
one?: ICUInterpolation;
457
two?: ICUInterpolation;
458
few?: ICUInterpolation;
459
many?: ICUInterpolation;
460
other: ICUInterpolation; // Always required
461
}
462
463
interface ICUSelectOptions {
464
[key: string]: ICUInterpolation;
465
other: ICUInterpolation; // Always required
466
}
467
```
468
469
The ICU macro system provides both compile-time optimization through Babel transformation and runtime components for dynamic ICU message format support in React applications.