Complete Guide to ICU Parameter Types for AI Translation
When importing translation strings via the API, each placeholder in your text must be defined with an ICU parameter type. This guide explains all 8 supported parameter types with examples.
@{paramName} - Placeholders use this syntax in content
| Type | Use Case | Required Fields | Optional Fields | Documentation |
|---|---|---|---|---|
| simple | Simple text replacement | paramName, type | — | Details → |
| number | Number formatting (currency, percent, decimal) | paramName, type | numberFormat | Details → |
| select | Gender, category selection | paramName, type, list | — | Details → |
| plural | Pluralization (items, count) | paramName, type, list | — | Details → ⚠️ Complex |
| selectordinal | Ordinal numbers (1st, 2nd, 3rd) | paramName, type, list | — | Details → ⚠️ Complex |
| date | Date formatting | paramName, type | style, format, zoneId | Details → ⚠️ Complex |
| time | Time formatting | paramName, type | style, format, zoneId | Details → |
| duration | Duration formatting (seconds to human readable) | paramName, type | style | Details → |
The most basic parameter type. Replaces @{paramName} with a string value.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "simple" |
Content: "Hello @{name}, welcome!"
Params:
{
"paramName": "name",
"type": "simple"
}
Usage: t.greeting("John") → "Hello John, welcome!"
Formats numbers with locale-aware styles like currency, percent, or decimal. Uses numberFormat for options.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "number" |
| numberFormat | object | Formatting options (see below) |
| Field | Type | Description | Example Values |
|---|---|---|---|
| style | string | Number style | "decimal", "currency", "percent", "integer" |
| currency | string | Currency code (when style=currency) | "USD", "CNY", "EUR" |
| precisionMode | string | Decimal precision mode | "fixed", "max" |
| precisionLength | number | Decimal places | 2 |
| compact | string | Compact notation | "short", "long" |
| percent | string | Percent style (multiply by 100 or 1000) | "percent" (×100, appends %), "permille" (×1000, appends ‰) |
| unit | string | Unit label | "kilogram", "meter", "byte" |
Content: "Price: @{price}"
Params:
{
"paramName": "price",
"type": "number",
"numberFormat": {
"style": "currency",
"currency": "CNY"
}
}
Usage: t.product.price(42) → "Price: CNY42.00"
Content: "Completion: @{progress}"
Params:
{
"paramName": "progress",
"type": "number",
"numberFormat": {
"style": "percent"
}
}
Usage: t.task.progress(0.42) → "Completion: 42%"
Content: "Population: @{pop}"
Params:
{
"paramName": "pop",
"type": "number",
"numberFormat": {
"style": "decimal",
"compact": "short",
"precisionLength": 1
}
}
Usage: t.stats.population(4200000) → "Population: 4.2M"
Selects one of several predefined options based on a string value. Ideal for gender-specific translations or category branching.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "select" |
| list | array | Array of value/text pairs |
{
"value": string, // The key to match (e.g., "male", "female")
"text": string // The display text when this value matches
}
Content: "@{name} is @{gender}"
Params:
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "a man" },
{ "value": "female", "text": "a woman" },
{ "value": "other", "text": "someone" }
]
}
Usage: t.person.gender("Alice", "female") → "Alice is a woman"
Content: "Order status: @{status}"
Params:
{
"paramName": "status",
"type": "select",
"list": [
{ "value": "pending", "text": "Pending" },
{ "value": "processing", "text": "Processing" },
{ "value": "completed", "text": "Completed" },
{ "value": "cancelled", "text": "Cancelled" }
]
}
Usage: t.order.status("pending") → "Order status: Pending"
Selects appropriate text based on numeric value following ICU plural rules. Essential for grammatically correct plurals across languages.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "plural" |
| list | array | Array of plural options |
| Value | Languages Using Differently | Description |
|---|---|---|
"zero" |
Arabic, Polish, Russian | For 0 items |
"one" |
English, French, German | For 1 item |
"two" |
Arabic, Slovenian | For 2 items |
"few" |
Russian, Polish, Czech | For small groups |
"many" |
Polish, Russian | For large numbers |
"other" |
Fallback for all languages | Default/fallback option |
Content: "You have @{count} @{itemCount}"
Params:
{
"paramName": "count",
"type": "simple"
},
{
"paramName": "itemCount",
"type": "plural",
"options": { "type": "cardinal" },
"list": [
{ "value": "one", "text": "item" },
{ "value": "other", "text": "items" }
]
}
Usage:
t.cart.items(1) → "You have 1 item"t.cart.items(5) → "You have 5 items"Content: "You have @{count} @{itemCount}"
Params:
{
"paramName": "count",
"type": "simple"
},
{
"paramName": "itemCount",
"type": "plural",
"options": { "type": "cardinal" },
"list": [
{ "value": "one", "text": "товар" },
{ "value": "few", "text": "товара" },
{ "value": "many", "text": "товаров" },
{ "value": "other", "text": "товара" }
]
}
Similar to plural but for ordinal numbers (1st, 2nd, 3rd, etc.). Follows ICU ordinal rules.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "selectordinal" |
| list | array | Array of ordinal options |
Same categories as plural: zero, one, two, few, many, other
Note: Most languages only use one and other for ordinals.
Content: "You are @{position}th in line"
Params:
{
"paramName": "position",
"type": "selectordinal",
"list": [
{ "value": "one", "text": "#st" },
{ "value": "two", "text": "#nd" },
{ "value": "few", "text": "#rd" },
{ "value": "other", "text": "#th" }
]
}
Usage:
t.queue.position(1) → "You are 1st in line"t.queue.position(2) → "You are 2nd in line"t.queue.position(3) → "You are 3rd in line"t.queue.position(4) → "You are 4th in line"Formats date values with locale-aware styles or custom ICU skeleton patterns.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "date" |
| Field | Type | Description | Example Values |
|---|---|---|---|
| style | string | Predefined date style | "short", "medium", "long", "full" |
| format | string | ICU skeleton pattern | "yyyy-MM-dd", "MM/dd/yyyy" |
| zoneId | string | Timezone identifier | "Asia/Shanghai", "America/New_York" |
| Pattern | Description | Example Output |
|---|---|---|
yyyy-MM-dd |
4-digit year, 2-digit month, 2-digit day | 2024-12-25 |
MM/dd/yyyy |
US format | 12/25/2024 |
dd.MM.yyyy |
European format | 25.12.2024 |
MMMM d, yyyy |
Full month name | December 25, 2024 |
Content: "Delivery date: @{date}"
Params:
{
"paramName": "date",
"type": "date",
"style": "short",
"zoneId": "Asia/Shanghai"
}
Usage: t.order.deliveryDate(new Date("2024-12-25")) → "Delivery date: 2024-12-25"
Content: "Check-in: @{checkin}"
Params:
{
"paramName": "checkin",
"type": "date",
"format": "yyyy-MM-dd HH:mm",
"zoneId": "Asia/Shanghai"
}
Usage: t.hotel.checkin(someDate) → "Check-in: 2024-12-25 14:30"
Formats time values with locale-aware styles or custom patterns.
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "time" |
| Field | Type | Description | Example Values |
|---|---|---|---|
| style | string | Predefined time style | "short" (HH:mm), "medium" (HH:mm:ss), "long" |
| format | string | ICU skeleton pattern | "HH:mm", "hh:mm a" |
| zoneId | string | Timezone identifier | "Asia/Shanghai" |
| Pattern | Description | Example Output |
|---|---|---|
HH:mm |
24-hour format, minutes only | 14:30 |
HH:mm:ss |
24-hour with seconds | 14:30:45 |
hh:mm a |
12-hour format with AM/PM | 02:30 PM |
Content: "Start time: @{start}"
Params:
{
"paramName": "start",
"type": "time",
"style": "short",
"zoneId": "Asia/Shanghai"
}
Usage: t.meeting.start(someTime) → "Start time: 14:30"
Content: "Meeting at @{time}"
Params:
{
"paramName": "time",
"type": "time",
"format": "hh:mm a",
"zoneId": "America/New_York"
}
Usage: t.meeting.at(someTime) → "Meeting at 02:30 PM"
Converts a duration in seconds to a human-readable format (e.g., "2h 30m", "1h 15m 30s").
| Field | Type | Description |
|---|---|---|
| paramName | string | Name matching the placeholder in content |
| type | string | Must be "duration" |
| Field | Type | Description | Example Values |
|---|---|---|---|
| style | string | Duration format style | "short" (2h 30m), "digital" (02:30:00) |
Content: "Duration: @{dur}"
Params:
{
"paramName": "dur",
"type": "duration",
"style": "short"
}
Usage:
t.video.duration(90) → "Duration: 1m 30s"t.video.duration(3600) → "Duration: 1h"t.video.duration(7200) → "Duration: 2h"Content: "Elapsed: @{elapsed}"
Params:
{
"paramName": "elapsed",
"type": "duration",
"style": "digital"
}
Usage: t.timer.elapsed(3723) → "Elapsed: 01:02:03"
Here's a complete example showing how to import strings with multiple parameter types:
{
"strings": [
{
"key": "user.greeting",
"translations": {
"zh-CN": {
"content": "你好 @{name},@{gender}",
"params": [
{ "paramName": "name", "type": "simple" },
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "欢迎先生" },
{ "value": "female", "text": "欢迎女士" },
{ "value": "other", "text": "欢迎您" }
]
}
]
},
"en-US": {
"content": "Hello @{name}, @{gender}",
"params": [
{ "paramName": "name", "type": "simple" },
{
"paramName": "gender",
"type": "select",
"list": [
{ "value": "male", "text": "welcome sir" },
{ "value": "female", "text": "welcome madam" },
{ "value": "other", "text": "welcome" }
]
}
]
}
}
},
{
"key": "product.stock",
"translations": {
"zh-CN": {
"content": "库存 @{count}",
"params": [
{
"paramName": "count",
"type": "plural",
"list": [
{ "value": "one", "text": "# 件" },
{ "value": "other", "text": "# 件" }
]
}
]
}
}
},
{
"key": "order.deadline",
"translations": {
"zh-CN": {
"content": "截止时间: @{deadline}",
"params": [
{
"paramName": "deadline",
"type": "date",
"style": "long",
"zoneId": "Asia/Shanghai"
}
]
}
}
}
]
}
Placeholders in content use simple @{paramName} syntax:
@{name} - Simple placeholder@{count} - Number placeholder@{itemCount} - Plural form placeholder (references a plural param)@{genderText} - Select placeholder (references a select param)Note: string.fit uses separate parameter definitions in the params array. There is no inline parameter syntax like ICU MessageFormat.
In plural/selectordinal text fields, # is replaced with the numeric value:
{ "value": "other", "text": "@{count} items" }
Usage: t.cart.items(5) → "5 items"
The generated code will validate parameter types. If a parameter expects a number but receives a string, it may cause runtime errors or unexpected output.