Skip to main content

Language Switcher

Detection order: URL prefix → Cookie → Base locale (English)

Current language: English (en)
Formatting locale: en-US

Translated Messages

m.greeting({ name: 'World' }) Hello, World!
m.welcome_message() Welcome to the internationalization showcase
m.sample_text() This text is translated based on the current locale.

Pluralization

ICU MessageFormat handles pluralization rules per language.

m.items_count({ count: 0 }) 0 items
m.items_count({ count: 1 }) 1 items
m.items_count({ count: 2 }) 2 items
m.items_count({ count: 5 }) 5 items
m.items_count({ count: 42 }) 42 items

Date & Number Formatting

Formatting uses the browser's Intl API, decoupled from the translation locale.

Formatted date Jan 15, 2025
Formatted date (long) Wednesday, January 15, 2025
Formatted number 1,234,567.89
Formatted currency (EUR) €1,234.50
Formatted currency (USD) $1,234.50
Formatted percentage 85.4%
Relative time 2 days ago

Content Translation (Database)

The tc() helper translates JSON fields from the database, falling back through: current locale → English → first available.

tc(post.title, post.titleI18n, locale) Hello World
tc(post.description, post.descriptionI18n, locale) This content is stored in the database as JSON.

Error Codes

Domain error codes resolve to localized strings via errorMessage(code).

errorMessage(ErrorCode.AUTH_INVALID) Invalid credentials.
errorMessage(ErrorCode.VALIDATION_REQUIRED) This field is required.
errorMessage(ErrorCode.RATE_LIMITED) Too many requests. Please slow down.
errorMessage(ErrorCode.RESOURCE_NOT_FOUND) We couldn't find what you're looking for.

Type Safety

Message keys are compile-time checked — a missing key or wrong parameter fails the build, not the runtime.

← Back to Showcases

Think this pattern could be better? Tell us how.

Leave feedback