Skip to content

Formatting

Principle

Formatting is locale-aware at runtime, not baked into translation strings. Translations contain text; formatting logic lives in code.

Currency

All prices use Intl.NumberFormat with the locale and currency code:

new Intl.NumberFormat('nl-NL', {
style: 'currency',
currency: 'EUR',
}).format(29.95);
// → "€ 29,95"
LocaleExample
nl-NL€ 29,95
de-DE29,95 €
fr-FR29,95 €
en€29.95

Currency codes come from the store configuration, not from translations.

Dates

Use Intl.DateTimeFormat with locale-appropriate patterns:

new Intl.DateTimeFormat('nl-NL', {
dateStyle: 'long',
}).format(date);
// → "28 februari 2026"
LocaleLong format
nl-NL28 februari 2026
de-DE28. Februar 2026
fr-FR28 février 2026
enFebruary 28, 2026

Numbers

Use Intl.NumberFormat for decimal and grouping separators:

Locale1234.5
nl-NL1.234,5
de-DE1.234,5
en1,234.5
fr-FR1 234,5

What NOT to put in translation strings

  • Currency symbols or formatted amounts — use Intl.NumberFormat
  • Date formats — use Intl.DateTimeFormat
  • Pluralization logic — use Intl.PluralRules or a lightweight plural helper
  • Number formatting — use Intl.NumberFormat

Translation strings should only contain text and placeholders:

{
"cart.total": "Total: {amount}",
"shipping.estimate": "Estimated delivery: {date}"
}

The {amount} and {date} placeholders receive pre-formatted values from code.