Stage 3
- Advanced into Stage 3 in TC39 2019-10-2.
- Advanced into Stage 2 in TC39 2019-6-5.
- Advanced into Stage 1 in TC39 2019-1-31.
- Discussed within ECMA402 members since July 2017.
Main motivation for Intl.DisplayNames project was to enable developers to get translation of language, region or script display names on the client. 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. These display name translations also carry steep data size penalty for developers. This API will allow web developers to shrink the size of their HTML and/ or ECMA script code without the need to include the human readble form of display names and therefore reduce the download size to decrease latency. Also, this API will reduce the localization cost for the web developers. Our goal is to expose this data through Intl API for use in e.g. language, region and script pickers, etc.
- Reduce download size of apps and therefore improve latency.
- Easy for users to build internationalized language, region or script selection UI components (drop down menu or other kinds).
- Reduce translation cost for developers.
- Consistent translation of language, region and script display name on the web.
This proposal is intended to provide translation for strings of particular items which are application-independent, rather than translation for all kinds of strings. There are two classes of strings we're considering here:
- Strings that are already available because they're needed for other APIs. For example, names for the days of the week are necessary to provide Intl.DateTimeFormat capabilities. In the absence of a direct API, we see programs parsing the output of Intl.DateTimeFormat to find these names, which is an unreliable/unstable technique.
- Strings that are universally standardized and are likely necessary for any multilingual JavaScript application. For example language/region names.
For example, for language/region names, W3C recommends users to use a locale selector when handling multilingual content, and currently that means shipping a long list of translated language/region names with every such website. Such data may potentially be time and politically sensitive and is unlikely to be specific to any particular website (i.e., it's unlikely that website A will want a different translation of any language name from website B). For that reason, providing this data in the engine lowers the cost of shipping multilingual websites with locale selectors and move the responsibility for keeping the mapping of BCP47 language/region codes to display names with the engine which is in a better position to keep it up to date.
The set of strings included may grow over time, but we expect to restrict the growth according to pragmatic requirements, including:
- Strings which are included should be generically useful across multiple application types.
- The inclusion of strings should not be too much of a burden on implementations in terms of data size.
- There should be an open data source that implementations can use for the string values, e.g., CLDR.
- Strings that rarely (never) change, and thus don't need to be dynamically generated.
- Sets of strings that have so few items that it's more of a burden to expose Web API and maintain it forever than it would be for a website to just include those strings directly.
Additional strings included in Intl.DisplayNames should be added to the specification through a future ECMA-402 proposal, to be presented in the ECMA-402 Task Group and TC39 as part of its standardization through TC39 processes.
To get localized names of language, script or region, create a Intl.DisplayName object and call the method by passing in appropriate standard code.
The parameter for Intl.DisplayNames constructor follow other Intl Objects in ECMA402 Standard. The first parameter is locales, which is either a BCP 47 language tag or an array of such language tags (more information); the second parameter is an option Object.
Intl.DisplayNames([ locales [ , options ]])
Intl.DisplayNames.prototype.of( code )
- options may have "localeMatcher", "style", and "type" properties.
- The value of style could be either "narrow", "short" or "long" to indicate the length of the display names. For example, ofLanguage("en-US") will return "English (United States)" under "long" style, but "English (US)" under "short" style. The default is "long".
- The value of type could be either "region", "script", "language", "currency", "month", "weekday", "quarter", "dayPeriod", or "dateTimeField".
- code is a String.
- Intl.DisplayNames.prototype.of( code ) function take a String as input and return a String, the display name of the code.
- If the type is "region", the code should be either an ISO-3166 two letters region code, or a three digits UN M49 Geographic Regions.
- If the type is "script", the code should be an ISO-15924 four letters script code.
- If the type is "language", the code should be a languageCode ["-" scriptCode] ["-" regionCode ] *("-" variant ) subsequence of the unicode_language_id grammar in UTS 35's Unicode Language and Locale Identifiers grammar. languageCode is either a two letters ISO 639-1 language code or a three letters ISO 639-2 language code.
- If the type is "currency", the code should be a 3-letter ISO 4217 currency code.
- If the type is "dateTimeField", the code should be one of the following:
- "era", "year", "quarter", "month", "weekOfYear", "weekday", "day", "dayPeriod", "hour", "minute", "second", "timeZoneName".
- If the type is "month", the code should be one of the following:
- "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13".
- If the type is "weekday", the code should be one of the following:
- "1", "2", "3", "4", "5", "6", "7".
- If the type is "quarter", the code should be one of the following:
- "1", "2", "3", "4".
- If the type is "dayPeriod", the code should be one of the following:
- "am", "pm".
- Frank Tang (@FrankYFTang)
- Zibi Braniecki (@zbraniecki)
- Sascha Brawer (@brawer)
- Nebojša Ćirić (@nciric)
- Reviewers
- Daniel Ehrenberg (@littledan)
- Bradley Farias (@mbeck)
- Editors
- Jordan Harband (@ljharb)
- Kevin Smith (@zenparsing)
Mozilla already has vendor specific implementation.
To create an Intl.DisplayNames for a locale and get the display name for a region code.
// Get display names of region in English
var 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 region in Traditional Chinese
regionNames = new Intl.DisplayNames(['zh-Hant'], {type: 'region'});
console.log(regionNames.of('419')); // "拉丁美洲"
console.log(regionNames.of('BZ')); // "貝里斯"
console.log(regionNames.of('US')); // "美國"
console.log(regionNames.of('BA')); // "波士尼亞與赫塞哥維納"
console.log(regionNames.of('MM')); // "緬甸"
To create an Intl.DisplayNames for a locale and get the display name for a language-script-region sequence.
// Get display names of language in English
var languageNames = new Intl.DisplayNames(['en'], {type: 'language'});
console.log(languageNames.of('fr')); // "French"
console.log(languageNames.of('de')); // "German"
console.log(languageNames.of('fr-CA')); // "Canadian French"
console.log(languageNames.of('zh-Hant')); // "Traditional Chinese"
console.log(languageNames.of('en-US')); // "American English"
console.log(languageNames.of('zh-TW')); // "Chinese (Taiwan)"]
// Get display names of language in Traditional Chinese
languageNames = new Intl.DisplayNames(['zh-Hant'], {type: 'language'});
console.log(languageNames.of('fr')); // "法文"
console.log(languageNames.of('zh')); // "中文"
console.log(languageNames.of('de')); // "德文"
To create an Intl.DisplayNames for a locale and get the display name for a script code.
// Get display names of script in English
var scriptNames = new Intl.DisplayNames(['en'], {type: 'script'});
// Get script names
console.log(scriptNames.of('Latn')); // "Latin"
console.log(scriptNames.of('Arab')); // "Arabic"
console.log(scriptNames.of('Kana')); // "Katakana"
// Get display names of script in Traditional Chinese
scriptNames = new Intl.DisplayNames(['zh-Hant'], {type: 'script'});
console.log(scriptNames.of('Latn')); // "拉丁文"
console.log(scriptNames.of('Arab')); // "阿拉伯文"
console.log(scriptNames.of('Kana')); // "片假名"
To create an Intl.DisplayNames for a locale and get the display name for currency code.
// Get display names of currency code in English
var currencyNames = new Intl.DisplayNames(['en'], {type: 'currency'});
// Get currency names
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"
// Get display names of currency code in Traditional Chinese
currencyNames = new Intl.DisplayNames(['zh-Hant'], {type: 'currency'});
console.log(currencyNames.of('USD')); // "美元"
console.log(currencyNames.of('EUR')); // "歐元"
console.log(currencyNames.of('TWD')); // "新台幣"
console.log(currencyNames.of('CNY')); // "人民幣"
To create an Intl.DisplayNames for a locale and get the display name for date time field.
// Get display names of date time field in English
var dateTimeFieldNames = new Intl.DisplayNames(['en'], {type: 'dateTimeField'});
console.log(dateTimeFieldNames.of('year')); // "year"
console.log(dateTimeFieldNames.of('quarter')); // "quarter"
console.log(dateTimeFieldNames.of('weekOfYear')); // "weekOfYear"
console.log(dateTimeFieldNames.of('hour')); // "hour"
// Get display names of date time field in Traditional Chinese
dateTimeFieldNames = new Intl.DisplayNames(['zh-Hant'], {type: 'dateTimeField'});
console.log(dateTimeFieldNames.of('year')); // "年"
console.log(dateTimeFieldNames.of('quarter')); // "季"
console.log(dateTimeFieldNames.of('weekOfYear')); // "週"
console.log(dateTimeFieldNames.of('hour')); // "小時"
To create an Intl.DisplayNames for a locale and get the display name for month.
// Get display names of month in English
var monthNames = new Intl.DisplayNames(['en'], {type: 'dateTime'});
console.log(monthNames.of('4')); // "April"
// Get display names of month in Traditional Chinese
monthNames = new Intl.DisplayNames(['zh-Hant'], {type: 'dateTime'});
console.log(monthNames.of('4')); // "4月"
To create an Intl.DisplayNames for a locale and get the display name for weekday.
// Get display names of weekday in English
var weekdayNames = new Intl.DisplayNames(['en'], {type: 'dateTime'});
console.log(dateTimeNames.of('1')); // "Monday"
// Get display names of weekday in Traditional Chinese
weekdayNames = new Intl.DisplayNames(['zh-Hant'], {type: 'dateTime'});
console.log(weekdayNames.of('1')); // "星期一"
To create an Intl.DisplayNames for a locale and get the display name for quarter.
// Get display names of quarter in English
var quarterNames = new Intl.DisplayNames(['en'], {type: 'dateTime'});
console.log(quarterNames.of('3')); // "3rd quarter"
// Get display names of quarter in Traditional Chinese
quarterNames = new Intl.DisplayNames(['zh-Hant'], {type: 'dateTime'});
console.log(quarterNames.of('3')); // "第3季"
To create an Intl.DisplayNames for a locale and get the display name for day period.
// Get display names of day period in English
var dayPeriodNames = new Intl.DisplayNames(['en'], {type: 'dateTime'});
console.log(dayPeriodNames.of('pm')); // "PM"
// Get display names of day period in Traditional Chinese
dayPeriodNames = new Intl.DisplayNames(['zh-Hant'], {type: 'dateTime'});
console.log(dayPeriodNames.of('pm')); // "下午"