ESNext: Get localized language, currency, and region names with Intl.DisplayNames

An ECMAScript Internationalization API Feature that currently is in Stage-3 and that has already landed in V8 version 8.1 is Intl.DisplayNames. It’s a way to get localized display names for languages, scripts, regions and others.

πŸ€” Note that this proposal is part of ECMA-402 (the ECMAScript Internationalization API Specification) and not ECMA-262 (The ECMAScript Language Specification). Therefore this proposal will not be part of the yearly "ES20XX”, as that term only applies to ECMA-262.

To advance proposals in ECMA-402, TC39 uses the same 5-stage-process as they use in ECMA-262.

πŸ’β€β™‚οΈ Stage-3?

The Technical Committee which is concerned with the standardization of ECMAScript (e.g. TC39) has a 5 stage process in place, ranging from stage-0 to stage-4, by which it develops a new language feature.

Stage-3 is the Candidate Stage where the feature is considered complete and only critical changes will happen based on implementation experience. If all goes well the proposal will advance to Stage 4 without any changes, after which it will to become part of the ECMAScript Specification.

The idea is that you as a developer should not build your own list of localized strings for languages, regions, etc. but that the JavaScript runtime should provide if for you:

Translation of languages, regions or script display names requires large amount of data to transmit on the network, which is already available in most browsers. The Intl.DisplayNames API will allow web developers to shrink the size of their HTML and/or ECMA script code without the need to include the human readable form of display names and therefore reduce the download size to decrease latency.

πŸ’β€β™‚οΈ Another nice API exposed on Intl is Intl.RelativeTimeFormat which allows you to relatively format time in JavaScript.



// Get display names of region in English
const regionNames = new Intl.DisplayNames(['en'], {type: 'region'});
console.log(regionNames.of('419')); // "Latin America"
console.log(regionNames.of('BZ')); // "Belize"
console.log(regionNames.of('US')); // "United States"
console.log(regionNames.of('BA')); // "Bosnia & Herzegovina"
console.log(regionNames.of('MM')); // "Myanmar (Burma)"

// Get display names of language in Traditional Chinese
const languageNames = new Intl.DisplayNames(['zh-Hant'], {type: 'language'});
console.log(languageNames.of('fr')); // "法文"
console.log(languageNames.of('zh')); // "中文"
console.log(languageNames.of('de')); // "德文"

// Get display names of script in Traditional Chinese
const scriptNames = new Intl.DisplayNames(['zh-Hant'], {type: 'script'});
console.log(scriptNames.of('Latn')); // "拉丁文"
console.log(scriptNames.of('Arab')); // "阿拉伯文"
console.log(scriptNames.of('Kana')); // "片假名"

// Get display names of currency code in English
const currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'});
console.log(currencyNames.of('USD')); // "US Dollar"
console.log(currencyNames.of('EUR')); // "Euro"
console.log(currencyNames.of('TWD')); // "New Taiwan Dollar"
console.log(currencyNames.of('CNY')); // "Chinese Yuan"



The constructor takes two arguments: locales and options. Both are optional:

new Intl.DisplayNames([locales[, options]]);

Once you have a Intl.DisplayNames instance, you use its .of method to request a localised string



Constructor Arguments


The locales argument is a BCP 47 language tag which identifies the locale to use. The main parts, amongst others, of a BCP 47 language tag are language, script, and region

  • The language part is a 2/3 character long ISO 639-1 code
  • The (optional) script part is a 4 character long ISO 15924 code
  • The (optional) region part is a 2 alpha or 3 digit long ISO 3166-1 code

When more than one part is present, they are separated by a dash (-)


  • "nl": Dutch (language).
  • "nl-BE": Dutch as used in Belgium (language + region).
  • "zh-Hans-CN": Chinese written in simplified characters as used in China (language + script + region).

When locales is omitted, it will default to the language-setting of the browser/system.


The options object allows you to tweak how Intl.DisplayNames behaves. It has the following properties:

  • localeMatcher

    The locale matching algorithm to use. Possible values are "lookup" and "best fit" (default)

  • style

    The length of the output message, e.g. "English (United States)" vs. "English (US)". Possible values are "long" (default) and "short", or “narrow” (which mostly yields the same result as "short", depending on the language)

  • type

    What you want to display. Possible values are "region", "script", "language", or "currency".


Intl.DisplayNames.prototype.of Arguments


Depending on the type you passed into the constructor, you pass in a different value for code:


JS/Browser Support

Intl.DisplayNames already shipped in V8 v8.1 (included in the upcoming Chrome 81) and will be available in Node 14. Other JS runtimes / browsers don’t support it at the time of writing.


The future: More types to come!

When looking at the open issues listed on the proposal’s repository you can see that there’s more to come in a future version of Intl.DisplayNames: support for units, timezones, emoji names, date parts (such as months, weekdays, etc).

For this first release the scope was limited to supporting the types "region", "script", "language", and "currency".


Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

β˜•οΈ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

Published by Bramus!

Bramus is a Freelance Web Developer from Belgium. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.