Formatting localized currency

Currencies are formatted differently in different countries and languages.

Orbit provides a currency formatting framework to:

  • Help teams build products for a global audience
  • Localize currency formatting for people everywhere
  • Unify the display of mixed currencies when an interface works with more than one currency
  • Implement the formatting through shared APIs

Definitions

An interface can present more than one type of currency and currency format.

Primary currency

The main currency of the experience and the Orbit default. Totals and summaries are shown in the primary currency unless a specific context calls for another.

Secondary currency

Any other type of currency is called a “secondary currency”. Common examples include:

  • Presentment currency: the currency shown to the person viewing the interface. In multi-currency experiences, it can differ from the primary currency.
  • Payout currency: the currency used to pay out for transactions. It can differ from the primary currency.
  • Billing currency: the currency used to bill for subscriptions and purchases. It may include local currencies for tax purposes.

Short format

Includes the currency symbol and currency value. Use it for currencies people are familiar with.

Examples: $12.50; 12,50 €

Explicit format

Includes the currency symbol, currency value, and ISO code (for example, “USD” and “CAD”). Best for currencies people aren’t familiar with and don’t expect to see.

Examples: $12.50 CAD; 12,50 € EUR

Aligning with global standards

Orbit uses the Common Locale Data Repository (CLDR) for localization formatting of currency, date, time, and amount.

  • It’s the recognized international standard
  • It automatically formats numbers and currency based on the person’s locale
  • The repository is maintained by a third party

CLDR determines:

  • Whether the currency symbol appears before or after the amount (for example, $250, 250 USD, 250 $)
  • Whether decimals are used (for example, there are no “cents” in Japanese yen)
  • Whether the decimal sign is a period or a comma (for example, 37,50 or 37.50)
  • How to group numbers (for example, 10,000 or 1,0000, or using spaces)

CLDR doesn’t determine the appropriate level of detail shown in different contexts. For example, it can’t determine when to show the currency symbol and value (short format), or the currency symbol, value, and ISO code (explicit format). Though short format is more efficient, it’s important to provide clarity for people who deal with unfamiliar currencies in multi-currency experiences. In those cases, use explicit format.

Design guidelines

Because CLDR formatting is limited, these guidelines will help you choose the appropriate level of currency detail to display in a multi-currency context.

Primary currency

Do

Short format in a summary card

Default to short format.

Don’t

Explicit format in a summary card

Use explicit format except when presenting the primary currency within a mixed-currency context.

Secondary currency

  • Use explicit format when showing total amounts, an amount within a button, or in a paragraph
  • Use short format when showing non-total amounts alongside total amounts

Presentment currency example: non-total amounts in short format, totals in explicit format

This example shows a scenario where the presentment currency differs from the primary currency. The non-total amounts are in short format, and the total amounts are in explicit format.

Refunding an amount in a secondary currency

This example shows a scenario refunding an amount that’s in a secondary currency.

Short format for non-total amounts in a data table

This example illustrates the use of short format for non-total amounts and explicit format for total amounts in a data table.

Negative amount display

Always place the negative symbol before the currency and amount in either format.

Do

  • -$4.20
  • -12,50 €

Don’t

  • $-4.20
  • 12,50 €-

Bidder-facing amounts

  • Default to explicit format whenever amounts are bidder-facing. Use short format for individual bids, lot estimates, and line items on an invoice.
  • If there are enough indicators to let people know which currency they’re looking at, short format may be sufficient. When using short format, always use explicit format for the final hammer price, invoice total, and notification totals.

Short format for current bid amounts

Short format for lot estimates

Short format for invoice line items

Guiding questions when making design decisions

Use the following questions to guide you when making decisions about currency formatting.

Does the person know which currency they’re looking at?

  • Which currency do they expect to see?
  • Do they know which currency they’re working with in a multi-currency experience?

Does the currency format support the main task?

  • Is the main task scanning, comparing and analyzing, or taking an action (for example, a refund)?

Are there enough details to make an informed decision?

  • For example, do they know the currency of a secondary-currency refund?
  • Can they distinguish between different summaries if the primary and payout currencies differ?

Can the UI be simplified without creating confusion?

We don’t want to show explicit format everywhere and for every task. How can we make currency formatting both simple and accurate?

Design tips

Mock up a scenario where the primary, presentment, payout, and billing currencies are different. This scenario is increasingly common as more teams build for a global audience.

Use currencies that share the same symbol to test for clarity

USD, CAD, AUD, HKD, and SGD are just a few of the many currencies that share the same symbol “$”.

Use Japanese Yen (JPY) amounts to test length and space constraints

1 USD is approximately 100 JPY. If there’s enough space for the JPY amount, it should work for most other major currencies.

When in doubt, let the guiding questions help you decide

The guiding questions are meant to help make people-focused decisions about which format to use when the use case is unclear.

Major currencies in their local formats

This table shows commonly-used currencies in short and explicit formats.

CurrencyLocaleShort formatExplicit format
US Dollar ($, USD)en-US$12.50$12.50 USD
Canadian Dollar ($, CAD)en-CA$12.50$12.50 CAD
fr-CA12,50 $12,50 $ CAD
Australian Dollar ($, AUD)en-AU$12.50$12.50 AUD
Euro (€, EUR)de-DE, fr-FR12,50 €12,50 € EUR
en-IE€12.50€12.50 EUR
nl-NL€12,50€12,50 EUR
British Pounds (£, GBP)en-GB£12.50£12.50 GBP
Japanese Yen (¥, JPY)ja-JP¥1250¥1250 JPY
New Zealand Dollar ($, NZD)en-NZ$12.50$12.50 NZD
Hong Kong Dollar ($, HKD)zh-HK$12.50$12.50 HKD
Singapore Dollar ($, SGD)zh-SG$12.50$12.50 SGD
Danish Krone (Kr, DKK)da-DK12,50 kr.12,50 kr. DKK

Implementation

To format currency in a React component, use a locale-aware helper built on the platform-native Intl.NumberFormat API. Select either short or explicit formatting by setting the form option as shown below.

// Orbit relies on the platform-native Intl.NumberFormat API for
// locale-aware currency formatting. Choose "short" or "explicit"
// by toggling currencyDisplay.

function formatCurrency(
  amount: number,
  currency: string,
  locale: string,
  form: "short" | "explicit" = "short"
) {
  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
    // "symbol" → short format ($12.50); "code" → explicit format ($12.50 USD)
    currencyDisplay: form === "explicit" ? "code" : "symbol",
  }).format(amount)
}

formatCurrency(12.5, "EUR", "de-AT", "short")
// => "€ 12,50"

formatCurrency(12.5, "EUR", "de-AT", "explicit")
// => "EUR 12,50"