Implementing Internationalization
1. Using Accept-Language Header
| Header | Server Selects |
|---|---|
en-US | US English |
fr,en;q=0.8 | French preferred, English fallback |
zh-Hans | Simplified Chinese |
| None / unsupported | Fallback to API default locale |
2. Providing Localized Error Messages
Example: Localized Error
// Accept-Language: es
{
"code": "VALIDATION_FAILED",
"title": "Validación fallida",
"errors": [
{"field": "email", "message": "El correo electrónico es obligatorio"}
]
}
3. Implementing Currency Formatting
| Approach | Recommendation |
|---|---|
| API returns raw amount + ISO 4217 code | {"amount": 1234.56, "currency": "USD"} |
| Client formats per locale | Intl.NumberFormat (JS) |
| Decimals as string | Avoid float precision loss |
4. Implementing Date/Time Formatting
| Field | Recommendation |
|---|---|
| API representation | ISO 8601 UTC: 2026-05-15T10:30:00Z |
| Client formats | Intl.DateTimeFormat |
| Avoid | Locale-specific strings in API responses |
5. Using ISO 639 Language Codes
| Standard | Example |
|---|---|
| ISO 639-1 (2-letter) | en, fr, de |
| ISO 639-2 (3-letter) | eng, fra |
| BCP 47 (region) | en-US, zh-Hans-CN |
| API recommendation | BCP 47 (RFC 5646) |
6. Implementing Number Formatting
| Locale | 1234567.89 |
|---|---|
| en-US | 1,234,567.89 |
| de-DE | 1.234.567,89 |
| fr-FR | 1 234 567,89 |
| API rule | Send raw number; client formats |
7. Handling Right-to-Left Languages
| Language | Direction |
|---|---|
| Arabic, Hebrew, Persian, Urdu | RTL |
| API field | Optional "direction": "rtl" hint |
| Client | Apply dir="rtl" on HTML |
8. Providing Translated Resource Content
| Pattern | Example |
|---|---|
| Single field per request locale | {"title": "Hola"} based on Accept-Language |
| Multi-locale object | {"title": {"en": "Hello", "es": "Hola"}} |
| Locale param | ?locale=es override |
9. Using Content-Language Header
| Header | Meaning |
|---|---|
Content-Language: en-US | Response is in US English |
Content-Language: en, fr | Multi-language content |
| Use with | Vary: Accept-Language for caching |
10. Documenting Supported Locales
| Doc Element | Content |
|---|---|
| Supported locales list | BCP 47 codes |
| Default locale | Used when none requested or unsupported |
| Per-field translation status | Which fields are localized |
| Fallback chain | e.g. es-MX → es → en |