11cb0ef41Sopenharmony_ci# Internationalization support 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci<!--introduced_in=v8.2.0--> 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci<!-- type=misc --> 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciNode.js has many features that make it easier to write internationalized 81cb0ef41Sopenharmony_ciprograms. Some of them are: 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci* Locale-sensitive or Unicode-aware functions in the [ECMAScript Language 111cb0ef41Sopenharmony_ci Specification][ECMA-262]: 121cb0ef41Sopenharmony_ci * [`String.prototype.normalize()`][] 131cb0ef41Sopenharmony_ci * [`String.prototype.toLowerCase()`][] 141cb0ef41Sopenharmony_ci * [`String.prototype.toUpperCase()`][] 151cb0ef41Sopenharmony_ci* All functionality described in the [ECMAScript Internationalization API 161cb0ef41Sopenharmony_ci Specification][ECMA-402] (aka ECMA-402): 171cb0ef41Sopenharmony_ci * [`Intl`][] object 181cb0ef41Sopenharmony_ci * Locale-sensitive methods like [`String.prototype.localeCompare()`][] and 191cb0ef41Sopenharmony_ci [`Date.prototype.toLocaleString()`][] 201cb0ef41Sopenharmony_ci* The [WHATWG URL parser][]'s [internationalized domain names][] (IDNs) support 211cb0ef41Sopenharmony_ci* [`require('node:buffer').transcode()`][] 221cb0ef41Sopenharmony_ci* More accurate [REPL][] line editing 231cb0ef41Sopenharmony_ci* [`require('node:util').TextDecoder`][] 241cb0ef41Sopenharmony_ci* [`RegExp` Unicode Property Escapes][] 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciNode.js and the underlying V8 engine use 271cb0ef41Sopenharmony_ci[International Components for Unicode (ICU)][ICU] to implement these features 281cb0ef41Sopenharmony_ciin native C/C++ code. The full ICU data set is provided by Node.js by default. 291cb0ef41Sopenharmony_ciHowever, due to the size of the ICU data file, several 301cb0ef41Sopenharmony_cioptions are provided for customizing the ICU data set either when 311cb0ef41Sopenharmony_cibuilding or running Node.js. 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci## Options for building Node.js 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciTo control how ICU is used in Node.js, four `configure` options are available 361cb0ef41Sopenharmony_ciduring compilation. Additional details on how to compile Node.js are documented 371cb0ef41Sopenharmony_ciin [BUILDING.md][]. 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci* `--with-intl=none`/`--without-intl` 401cb0ef41Sopenharmony_ci* `--with-intl=system-icu` 411cb0ef41Sopenharmony_ci* `--with-intl=small-icu` 421cb0ef41Sopenharmony_ci* `--with-intl=full-icu` (default) 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciAn overview of available Node.js and JavaScript features for each `configure` 451cb0ef41Sopenharmony_cioption: 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci| Feature | `none` | `system-icu` | `small-icu` | `full-icu` | 481cb0ef41Sopenharmony_ci| ---------------------------------------- | --------------------------------- | ---------------------------- | ---------------------- | ---------- | 491cb0ef41Sopenharmony_ci| [`String.prototype.normalize()`][] | none (function is no-op) | full | full | full | 501cb0ef41Sopenharmony_ci| `String.prototype.to*Case()` | full | full | full | full | 511cb0ef41Sopenharmony_ci| [`Intl`][] | none (object does not exist) | partial/full (depends on OS) | partial (English-only) | full | 521cb0ef41Sopenharmony_ci| [`String.prototype.localeCompare()`][] | partial (not locale-aware) | full | full | full | 531cb0ef41Sopenharmony_ci| `String.prototype.toLocale*Case()` | partial (not locale-aware) | full | full | full | 541cb0ef41Sopenharmony_ci| [`Number.prototype.toLocaleString()`][] | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full | 551cb0ef41Sopenharmony_ci| `Date.prototype.toLocale*String()` | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full | 561cb0ef41Sopenharmony_ci| [Legacy URL Parser][] | partial (no IDN support) | full | full | full | 571cb0ef41Sopenharmony_ci| [WHATWG URL Parser][] | partial (no IDN support) | full | full | full | 581cb0ef41Sopenharmony_ci| [`require('node:buffer').transcode()`][] | none (function does not exist) | full | full | full | 591cb0ef41Sopenharmony_ci| [REPL][] | partial (inaccurate line editing) | full | full | full | 601cb0ef41Sopenharmony_ci| [`require('node:util').TextDecoder`][] | partial (basic encodings support) | partial/full (depends on OS) | partial (Unicode-only) | full | 611cb0ef41Sopenharmony_ci| [`RegExp` Unicode Property Escapes][] | none (invalid `RegExp` error) | full | full | full | 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ciThe "(not locale-aware)" designation denotes that the function carries out its 641cb0ef41Sopenharmony_cioperation just like the non-`Locale` version of the function, if one 651cb0ef41Sopenharmony_ciexists. For example, under `none` mode, `Date.prototype.toLocaleString()`'s 661cb0ef41Sopenharmony_cioperation is identical to that of `Date.prototype.toString()`. 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci### Disable all internationalization features (`none`) 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciIf this option is chosen, ICU is disabled and most internationalization 711cb0ef41Sopenharmony_cifeatures mentioned above will be **unavailable** in the resulting `node` binary. 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci### Build with a pre-installed ICU (`system-icu`) 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ciNode.js can link against an ICU build already installed on the system. In fact, 761cb0ef41Sopenharmony_cimost Linux distributions already come with ICU installed, and this option would 771cb0ef41Sopenharmony_cimake it possible to reuse the same set of data used by other components in the 781cb0ef41Sopenharmony_ciOS. 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ciFunctionalities that only require the ICU library itself, such as 811cb0ef41Sopenharmony_ci[`String.prototype.normalize()`][] and the [WHATWG URL parser][], are fully 821cb0ef41Sopenharmony_cisupported under `system-icu`. Features that require ICU locale data in 831cb0ef41Sopenharmony_ciaddition, such as [`Intl.DateTimeFormat`][] _may_ be fully or partially 841cb0ef41Sopenharmony_cisupported, depending on the completeness of the ICU data installed on the 851cb0ef41Sopenharmony_cisystem. 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci### Embed a limited set of ICU data (`small-icu`) 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ciThis option makes the resulting binary link against the ICU library statically, 901cb0ef41Sopenharmony_ciand includes a subset of ICU data (typically only the English locale) within 911cb0ef41Sopenharmony_cithe `node` executable. 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ciFunctionalities that only require the ICU library itself, such as 941cb0ef41Sopenharmony_ci[`String.prototype.normalize()`][] and the [WHATWG URL parser][], are fully 951cb0ef41Sopenharmony_cisupported under `small-icu`. Features that require ICU locale data in addition, 961cb0ef41Sopenharmony_cisuch as [`Intl.DateTimeFormat`][], generally only work with the English locale: 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci```js 991cb0ef41Sopenharmony_ciconst january = new Date(9e8); 1001cb0ef41Sopenharmony_ciconst english = new Intl.DateTimeFormat('en', { month: 'long' }); 1011cb0ef41Sopenharmony_ciconst spanish = new Intl.DateTimeFormat('es', { month: 'long' }); 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ciconsole.log(english.format(january)); 1041cb0ef41Sopenharmony_ci// Prints "January" 1051cb0ef41Sopenharmony_ciconsole.log(spanish.format(january)); 1061cb0ef41Sopenharmony_ci// Prints either "M01" or "January" on small-icu, depending on the user’s default locale 1071cb0ef41Sopenharmony_ci// Should print "enero" 1081cb0ef41Sopenharmony_ci``` 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ciThis mode provides a balance between features and binary size. 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci#### Providing ICU data at runtime 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciIf the `small-icu` option is used, one can still provide additional locale data 1151cb0ef41Sopenharmony_ciat runtime so that the JS methods would work for all ICU locales. Assuming the 1161cb0ef41Sopenharmony_cidata file is stored at `/some/directory`, it can be made available to ICU 1171cb0ef41Sopenharmony_cithrough either: 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci* The [`NODE_ICU_DATA`][] environment variable: 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci ```bash 1221cb0ef41Sopenharmony_ci env NODE_ICU_DATA=/some/directory node 1231cb0ef41Sopenharmony_ci ``` 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci* The [`--icu-data-dir`][] CLI parameter: 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci ```bash 1281cb0ef41Sopenharmony_ci node --icu-data-dir=/some/directory 1291cb0ef41Sopenharmony_ci ``` 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci(If both are specified, the `--icu-data-dir` CLI parameter takes precedence.) 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ciICU is able to automatically find and load a variety of data formats, but the 1341cb0ef41Sopenharmony_cidata must be appropriate for the ICU version, and the file correctly named. 1351cb0ef41Sopenharmony_ciThe most common name for the data file is `icudt6X[bl].dat`, where `6X` denotes 1361cb0ef41Sopenharmony_cithe intended ICU version, and `b` or `l` indicates the system's endianness. 1371cb0ef41Sopenharmony_ciCheck ["ICU Data"][] article in the ICU User Guide for other supported formats 1381cb0ef41Sopenharmony_ciand more details on ICU data in general. 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ciThe [full-icu][] npm module can greatly simplify ICU data installation by 1411cb0ef41Sopenharmony_cidetecting the ICU version of the running `node` executable and downloading the 1421cb0ef41Sopenharmony_ciappropriate data file. After installing the module through `npm i full-icu`, 1431cb0ef41Sopenharmony_cithe data file will be available at `./node_modules/full-icu`. This path can be 1441cb0ef41Sopenharmony_cithen passed either to `NODE_ICU_DATA` or `--icu-data-dir` as shown above to 1451cb0ef41Sopenharmony_cienable full `Intl` support. 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci### Embed the entire ICU (`full-icu`) 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ciThis option makes the resulting binary link against ICU statically and include 1501cb0ef41Sopenharmony_cia full set of ICU data. A binary created this way has no further external 1511cb0ef41Sopenharmony_cidependencies and supports all locales, but might be rather large. This is 1521cb0ef41Sopenharmony_cithe default behavior if no `--with-intl` flag is passed. The official binaries 1531cb0ef41Sopenharmony_ciare also built in this mode. 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci## Detecting internationalization support 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ciTo verify that ICU is enabled at all (`system-icu`, `small-icu`, or 1581cb0ef41Sopenharmony_ci`full-icu`), simply checking the existence of `Intl` should suffice: 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci```js 1611cb0ef41Sopenharmony_ciconst hasICU = typeof Intl === 'object'; 1621cb0ef41Sopenharmony_ci``` 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ciAlternatively, checking for `process.versions.icu`, a property defined only 1651cb0ef41Sopenharmony_ciwhen ICU is enabled, works too: 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci```js 1681cb0ef41Sopenharmony_ciconst hasICU = typeof process.versions.icu === 'string'; 1691cb0ef41Sopenharmony_ci``` 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ciTo check for support for a non-English locale (i.e. `full-icu` or 1721cb0ef41Sopenharmony_ci`system-icu`), [`Intl.DateTimeFormat`][] can be a good distinguishing factor: 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci```js 1751cb0ef41Sopenharmony_ciconst hasFullICU = (() => { 1761cb0ef41Sopenharmony_ci try { 1771cb0ef41Sopenharmony_ci const january = new Date(9e8); 1781cb0ef41Sopenharmony_ci const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); 1791cb0ef41Sopenharmony_ci return spanish.format(january) === 'enero'; 1801cb0ef41Sopenharmony_ci } catch (err) { 1811cb0ef41Sopenharmony_ci return false; 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci})(); 1841cb0ef41Sopenharmony_ci``` 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ciFor more verbose tests for `Intl` support, the following resources may be found 1871cb0ef41Sopenharmony_cito be helpful: 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci* [btest402][]: Generally used to check whether Node.js with `Intl` support is 1901cb0ef41Sopenharmony_ci built correctly. 1911cb0ef41Sopenharmony_ci* [Test262][]: ECMAScript's official conformance test suite includes a section 1921cb0ef41Sopenharmony_ci dedicated to ECMA-402. 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci["ICU Data"]: http://userguide.icu-project.org/icudata 1951cb0ef41Sopenharmony_ci[BUILDING.md]: https://github.com/nodejs/node/blob/HEAD/BUILDING.md 1961cb0ef41Sopenharmony_ci[ECMA-262]: https://tc39.github.io/ecma262/ 1971cb0ef41Sopenharmony_ci[ECMA-402]: https://tc39.github.io/ecma402/ 1981cb0ef41Sopenharmony_ci[ICU]: http://site.icu-project.org/ 1991cb0ef41Sopenharmony_ci[Legacy URL parser]: url.md#legacy-url-api 2001cb0ef41Sopenharmony_ci[REPL]: repl.md#repl 2011cb0ef41Sopenharmony_ci[Test262]: https://github.com/tc39/test262/tree/HEAD/test/intl402 2021cb0ef41Sopenharmony_ci[WHATWG URL parser]: url.md#the-whatwg-url-api 2031cb0ef41Sopenharmony_ci[`--icu-data-dir`]: cli.md#--icu-data-dirfile 2041cb0ef41Sopenharmony_ci[`Date.prototype.toLocaleString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString 2051cb0ef41Sopenharmony_ci[`Intl.DateTimeFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat 2061cb0ef41Sopenharmony_ci[`Intl`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl 2071cb0ef41Sopenharmony_ci[`NODE_ICU_DATA`]: cli.md#node_icu_datafile 2081cb0ef41Sopenharmony_ci[`Number.prototype.toLocaleString()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString 2091cb0ef41Sopenharmony_ci[`RegExp` Unicode Property Escapes]: https://github.com/tc39/proposal-regexp-unicode-property-escapes 2101cb0ef41Sopenharmony_ci[`String.prototype.localeCompare()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare 2111cb0ef41Sopenharmony_ci[`String.prototype.normalize()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 2121cb0ef41Sopenharmony_ci[`String.prototype.toLowerCase()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase 2131cb0ef41Sopenharmony_ci[`String.prototype.toUpperCase()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase 2141cb0ef41Sopenharmony_ci[`require('node:buffer').transcode()`]: buffer.md#buffertranscodesource-fromenc-toenc 2151cb0ef41Sopenharmony_ci[`require('node:util').TextDecoder`]: util.md#class-utiltextdecoder 2161cb0ef41Sopenharmony_ci[btest402]: https://github.com/srl295/btest402 2171cb0ef41Sopenharmony_ci[full-icu]: https://www.npmjs.com/package/full-icu 2181cb0ef41Sopenharmony_ci[internationalized domain names]: https://en.wikipedia.org/wiki/Internationalized_domain_name 219