20

If I run this code in the browser and node I obtain two different results:

const moneyFormatter = new Intl.NumberFormat('it-IT', {
    style: 'currency',
    currency: 'EUR',
    minimumFractionDigits: 2
});

moneyFormatter.format(1);

Browser: 1,00 €

Node: €1.00

lifeisfoo
  • 15,478
  • 6
  • 74
  • 115

1 Answers1

21

ICU and Node

This problem is caused by the missing ICU data in the default Node build.

Nodejs docs explains well how the Internationalization feature works:

Node.js (and its underlying V8 engine) uses ICU to implement these features in native C/C++ code. However, some of them require a very large ICU data file in order to support all locales of the world.

At the same time, it explains the limitations you have in the default Node build:

Because it is expected that most Node.js users will make use of only a small portion of ICU functionality, only a subset of the full ICU data set is provided by Node.js by default.

And so:

Several options are provided for customizing and expanding the ICU data set either when building or running Node.js.

Quick solution

Install the full-icu npm package and you're done: every locale will be installed and will be available in your code. Just start you app with a dedicated env var pointing to the icu dataset installation path:

NODE_ICU_DATA=node_modules/full-icu node YOURAPP.js

Or, using the specific Node option:

node --icu-data-dir=node_modules/full-icu YOURAPP.js

The only disadvantage of this solution is the space required for the full icu dataset: ~27Mb.

Slow, but space optimized solution

Compile Node from sources bundling it with a specific ICU only.

Checking available locales

Intl.NumberFormat.supportedLocalesOf('it')

It returns an empty array [] if the locale is not supported. It returns an array with the locale id ['it'] if the locale is supported.

lifeisfoo
  • 15,478
  • 6
  • 74
  • 115
  • I am having problems making the quick solution work. is YOURAPP.js e.g. server.js or src/server.js? None of those works for me. NODE_ICU_DATA is to be defined in the .env file right? – Lull May 26 '20 at 06:47
  • @Lull you need to check where is your main js file in your app sources. It could be called index, app, or anything else. Try looking for it inside your package.json scripts. Yes, NODE_ICU_DATA is an environment variable but probably you need to pass it in the command because it must be read by node and not from your app (node starts, then load and execute your app). Usually .env files are parsed by libs during your app start but after node start. – lifeisfoo May 26 '20 at 08:22