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