Docs
Usage guide
Numbers

Number formatting

The formatting of numbers can vary depending on the user's locale and may include different rules such as:

  1. Decimal separators (e.g. "12.3" in en-US vs. "12,3" in de-DE)
  2. Digit grouping (e.g. "120,000" in en-US vs. "1,20,000" in hi-IN)
  3. Currency sign position (e.g. "12 €" in de-DE vs. "€ 12" in de-AT)

By using the formatting capabilities provided by next-intl, you can adjust to these variations and ensure that numbers are displayed accurately across your Next.js app for all users.

Formatting plain numbers

When you're formatting plain numbers that are not part of a message, you can use a separate hook:

import {useFormatter} from 'next-intl';
 
function Component() {
  const format = useFormatter();
 
  format.number(499.9, {style: 'currency', currency: 'USD'});
}

See the MDN docs about NumberFormat (opens in a new tab) to learn more about the options you can pass to number (interactive explorer (opens in a new tab)).

Numbers within messages

Numbers can be embedded within messages by using the ICU syntax.

en.json
{
  "basic": "Basic formatting: {value, number}",
  "percentage": "Displayed as a percentage: {value, number, percent}",
  "custom": "At most 2 fraction digits: {value, number, ::.##}"
}

Note the leading :: that is used to indicate that a skeleton should be used. See the ICU docs about number skeletons (opens in a new tab) to learn more about this.

💡

If you work with translators, it can be helpful for them to use an editor that supports the ICU syntax for numbers (e.g. the Crowdin Editor (opens in a new tab)).

Custom number formats

To use custom formats in messages, you can provide formatters that can be referenced by name.

en.json
{
  "price": "This product costs {price, number, currency}"
}
t(
  'price',
  {price: 32000.99},
  {
    number: {
      currency: {
        style: 'currency',
        currency: 'EUR'
      }
    }
  }
);
💡

To reuse number formats for multiple components, you can configure global formats.