Number formatting
The formatting of numbers can vary depending on the user's locale and may include different rules such as:
- Decimal separators (e.g. "12.3" in
en-US
vs. "12,3" inde-DE
) - Digit grouping (e.g. "120,000" in
en-US
vs. "1,20,000" inhi-IN
) - Currency sign position (e.g. "12 €" in
de-DE
vs. "€ 12" inde-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();
// Renders "$499.90"
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 the number
function or try the interactive explorer for Intl.NumberFormat
(opens in a new tab).
Numbers within messages
Numbers can be embedded within messages by using the ICU syntax.
{
"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.
{
"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.