06 / 07

How to format numbers in next-intl?

next-intl provides two approaches for number formatting: using the useFormatter hook for numbers outside translation messages, and embedding ICU number syntax directly within message strings for integrated formatting [citation:1].

next-intl handles number formatting in a way that respects the user's locale, automatically adapting decimal separators, digit grouping, and currency symbol placement [citation:1][citation:3]. The library offers two distinct methods to format numbers, depending on whether the number is part of a larger translated string or a standalone UI element.

For formatting numbers that are not part of a translated message (e.g., a price display, a chart label, or a statistic), you use the useFormatter hook. This gives you access to a format object containing a number method [citation:1][citation:4]. This method is a wrapper around the browser's native Intl.NumberFormat and accepts the same standard options [citation:1][citation:6].

Formatting a currency using useFormatter

If you have global formats defined in your i18n/request.ts configuration, you can reference them by name as the second argument [citation:1][citation:3]. This allows you to maintain a consistent number style across your application. For example, if you have a global format named 'precise' with maximumFractionDigits: 5, you can use format.number(3.14159, 'precise') [citation:1][citation:2].

When numbers are part of a translated sentence (e.g., "You have {count} new messages"), you should format them using the ICU Message Syntax directly within your message string. This keeps all the text for a sentence in one place, which is much easier for translators to work with [citation:1][citation:3].

Message File (e.g., messages/en.json)
Using the formatted number in a component
Understanding ICU Number Syntax
  1. 1

    Basic Formatting: {value, number} formats the number with default locale settings [citation:1][citation:6].

  2. 2

    Currency: {value, number, currency} requires you to define the currency type via the currency option in the third argument of the t() function [citation:3].

  3. 3

    Percent: {value, number, percent} multiplies the value by 100 and appends the percent sign [citation:1].

  4. 4

    Number Skeletons: {value, number, ::.##} uses a 'skeleton' (denoted by ::) for precise control over the format, such as setting the number of fraction digits [citation:1][citation:3].

For complex or reusable number formats inside messages, you can pass custom number options as the third argument to the t function. This is especially useful for defining the currency when using {value, number, currency} [citation:1][citation:6].

Passing number formatting options to t()

For formatting numbers in Server Components, you can use the getFormatter function. This is the asynchronous equivalent of the client-side useFormatter hook [citation:4]. The pattern remains the same: you call format.number() with the value and options. This ensures consistent formatting on the server before the HTML is sent to the client.

Share

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.