DEV Community

Cover image for Mastering Internationalization and Localization in JavaScript: A Comprehensive Guide
sahra πŸ’«
sahra πŸ’«

Posted on • Originally published at dev.to

 

Mastering Internationalization and Localization in JavaScript: A Comprehensive Guide

Introduction

As a developer, you need to be aware of the power of internalization and localization. By understanding how to collate and format text, numbers, currencies and dates for different locales, you can create a truly global application.

This article will explain how to localize and internalize with JavaScript. It's a very common question that comes up often in the JavaScript community. I will go through some of the most common scenarios where localization is needed, and also provide some tips for working with collation, currency and date formatting in your JavaScript applications.

Table Of Contents (TOC)

What is Internalization and Localization?

Internalization and localization are two important concepts in software development that allow your application to adapt to different languages and cultures.

Internalization, also known as "i18n" (because there are 18 letters between the "i" and the "n" in "internationalization"), is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. This means that the application's code and user interface are separated from the language and cultural elements, making it easier to translate and adapt the application for different locales.

The ECMAScript Internationalization API (Intl) provides a set of JavaScript objects and methods for internationalization, this is a built-in feature of JavaScript. These objects and methods provide support for formatting and parsing numbers, currencies, and dates, as well as support for localized string comparison and collation.
Additionally, there are also Some popular JavaScript libraries built for the sole purpose of internationalization (i18n) in JavaScript which include:

  • i18next - a full-featured i18n library for JavaScript. It gives you the option to separate translations into multiple files and to load them on demand.
  • react-intl - a React-specific library for internationalization
  • format-message - provides a way to write your default (often English) message patterns as literals in your source, and then lookup translations at runtime.
  • polyglot.js - a tiny I18n helper library written in JavaScript, made to work both in the browser and in CommonJS environments (Node)

Localization, also known as "l10n" (10 letters between "l" and "n"), is the process of adapting a software application for a specific locale or market. This includes translating the user interface, formatting dates and numbers, and even adjusting images and icons to better suit the culture.

Collation: Sorting Strings for Different Languages

Collation is the process of arranging characters in a specific order for a given language and region. It refers to the rules and algorithms used to define the sort order of characters in a given language.

First, it's important to understand that JavaScript uses the Unicode Collation Algorithm (UCI) to sort strings. This algorithm is based on the Unicode Character Set, which assigns a unique number to every character in every script in the world. However, the default UCI sorting behavior may not always produce the desired results when sorting strings in different languages. For example, the default UCI sorting order may not correctly sort accented characters in French or Spanish.

To address this issue, JavaScript provides the Intl.Collator() object, which allows you to specify a specific locale and options for sorting strings. The locale is a string that indicates the language and region for which the sorting should be tailored. For example, 'fr-FR' would indicate French as used in France, and 'es-ES' would indicate Spanish as used in Spain.

Here is an example of how to use the Intl.Collator() object to sort an array of strings in French:

const words = ["pomme", "poire", "banane", "orange"];
const collator = new Intl.Collator("fr", { sensitivity: "base" });
const sortedWords = words.sort(collator.compare);
console.log(sortedWords); 
// Output: ["banane", "orange", "poire", "pomme"]
Enter fullscreen mode Exit fullscreen mode

In this example, we first define an array of strings containing the words "pomme", "poire", "banane", "orange", which are the French words for "apple", "pear", "banana", "orange", respectively.

We then create a new Intl.Collator object, passing in the locale "fr" for French and options{ sensitivity: "base" }. The sensitivity option determines how sensitive the sorting should be to differences in characters. base means that only the basic letters and digits are considered, ignoring any diacritical marks.

Finally, we use the sort() method on the words array and pass in the collator.compare function as the comparator. This sorts the words array based on the collation rules for French. The output is the sorted words array.

You can also use Intl.Collator() object to compare two words or strings without sorting the array, here is an example:

const word1 = "pomme";
const word2 = "Poire";
const collator = new Intl.Collator("fr", { sensitivity: "base" });
console.log(collator.compare(word1, word2));
// Output: 1
Enter fullscreen mode Exit fullscreen mode

In this example, we use the compare() method of the Intl.Collator object to compare the two words "pomme" and "Poire" in French, this method returns -1 if the left-hand operand is less than the right-hand operand, 0if they are the same and 1 if the left-hand operand is greater than the right-hand operand. The output is 1, meaning that "Poire" comes after "pomme" in the French sorting order.

Another way to sort strings for different languages in JavaScript is by using the localeCompare() method. This method compares two strings in the context of the current locale and returns a number indicating whether the first string comes before, after, or is the same as the second string in the sort order.

Here is an example of how to use the localeCompare() method to sort an array of strings in German:

const words = ["Apfel", "Birne", "Banane", "Orange"];
const sortedWords = words.sort((a, b) => a.localeCompare(b, 'de'));
console.log(sortedWords);
// Output: ["Apfel", "Banane", "Birne", "Orange"]
Enter fullscreen mode Exit fullscreen mode

In this example, we first define an array of strings containing the words "Apfel", "Birne", "Banane", "Orange", which are the German words for "apple", "pear", "banana", "orange", respectively.

Then we use the sort() method on the words array and pass in a comparator function that uses the localeCompare() method to compare the two words, passing the locale 'de' for German as the second argument. This sorts the words array based on the collation rules for German. The output is the sorted words array.

It's also possible to use the this method without sorting the array, here is an example:

const word1 = "Apfel";
const word2 = "Birne";
console.log(word1.localeCompare(word2, 'de'));
// Output: -1
Enter fullscreen mode Exit fullscreen mode

In this example, we use the localeCompare() method to compare the two words "Apfel" and "Birne" in German. This method returns -1 if the left-hand operand is less than the right-hand operand, 0 if they are the same and 1 if the left-hand operand is greater than the right-hand operand. The output is -1, meaning that "Apfel" comes before "Birne" in the German sorting order.

It's worth noting that using Intl.Collator() and localeCompare() is not the only way to sort the strings for different languages, you can also use other libraries like lodash or ramda .

Number Formatting in JavaScript

Number formatting refers to the process of converting a number to a string representation in a specific format. This can include things like decimal places, currency symbols, and thousands separators. The process of number formatting is important because it allows you to present numbers in a way that is easy for users to understand and interpret.

JavaScript provides built-in methods like toFixed() for number formatting, as well as libraries like numeral.js, which provides advanced formatting options. These methods and libraries can be used to format numbers in a variety of ways, including currency, percentages, and time. It's important to note that the way numbers are formatted can vary depending on the locale and currency, so it's important to be mindful of these considerations when formatting numbers in JavaScript.

First and foremost, let's discuss the toFixed() method. This method is a built-in JavaScript function that can be used to format a number to a specific number of decimal places. The function takes an integer as an argument, which represents the number of decimal places you want to format the number to
Here is an example of how to use this method to format a number with two decimal places:

let number = 12.34567; 
let formattedNumber = number.toFixed(2);
console.log(formattedNumber);  // Output: "12.35"
Enter fullscreen mode Exit fullscreen mode

In the above example, we first declare a variable named number with the value 12.34567. Then we use the toFixed() method on the number variable, passing in 2 as the argument. This tells the method to format the number with two decimal places. Finally, we use console.log() to output the formatted number, which is 12.35.

Currency Formatting for International Markets

When working with monetary values in JavaScript, it's important to format them in a way that's easily understood by users in different countries and regions. Currency formatting for international markets can be tricky, as different countries have different conventions for representing currency values. In this article, I will explain how to format numbers as currency for different locales in JavaScript, using the toLocaleString() and Intl.NumberFormat() method.

The toLocaleString() method is a built-in method in JavaScript that can be used to format numbers as a string, according to the conventions of a particular locale. It takes an optional options argument, which can be used to customize the formatting of the number

here's an example of how you can use the options object along with the toLocaleString() method to format currency for international markets in JavaScript:

// Initialize the number to be formatted
let number = 1234.56;

// Define the options object
let options = {
    style: 'currency',
    currency: 'USD',
    currencyDisplay: 'symbol',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
};

// Use the toLocaleString() method with the options object
let formattedCurrency = number.toLocaleString('en-US', options);

console.log(formattedCurrency); // Outputs "$1,234.56"
Enter fullscreen mode Exit fullscreen mode

Here, we first define the number that we want to format as 1234.56. Then we create an options object with several properties to customize the formatting. The style property is set to 'currency' which tells the method to format the number as currency. The currency property is set to 'USD' which tells the method to use the US dollar as the currency symbol. The currencyDisplay property is set to 'symbol' which tells the method to use the dollar symbol as the currency indicator.

The minimumFractionDigits and maximumFractionDigits properties are set to 2. This means that the method will always display at least 2 digits after the decimal point, and at most 2 digits.

Finally, we use the toLocaleString() method with the options object to format the number as currency. The first argument passed to the method is the 'locale', which is set to en-US in this case. This tells the method to use the US English locale for formatting. The second argument passed to the method is the options object.

The final output will be 1,234.56

There is also another built-in method that can do this.
The Intl.NumberFormat() method is a constructor, which means you need to create a new instance of the object to use it. Once you have an instance of the object, you can call the format() method on it to format a number as a currency. Here is an example of how to use it.

let number = 1234.56;
let formatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    currencyDisplay: 'symbol',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
});
console.log(formatter.format(number));
Enter fullscreen mode Exit fullscreen mode

This will give you the same output as the example above with toLocaleString() method.

Please note that the options object properties may vary depending on the browser support.

Date and Time Formats Across Cultures

Dealing with dates and times can be tricky in any programming language, and JavaScript is no exception. One of the biggest challenges when working with dates and times is making sure that they are formatted correctly for different cultures and regions.

JavaScript provides several built-in methods for working with dates and times, but they can be somewhat limited when it comes to formatting. For example, the toString() method returns the date in a format that is specific to the user's system, which may not be appropriate for all cultures.

Thankfully, the ECMAScript Internationalization API provides a powerful and flexible solution for formatting dates and times in JavaScript. The key object here is the Intl.DateTimeFormat()constructor, which can be used to create a formatter that can format dates and times according to the conventions of a specific locale.

Here is an example of how you would use the Intl.DateTimeFormat() constructor to create a date and time formatter for the US English locale:

let date = new Date();
let formatter = new Intl.DateTimeFormat("en-US");
console.log(formatter.format(date));
Enter fullscreen mode Exit fullscreen mode

This will output the current date and time in the format that is used in the United States, which is typically in the format of "Month Day, Year Hour:Minute:Second".

You can also pass an optionsobject as the second argument to the Intl.DateTimeFormat()constructor to customize the formatting further. For example, you can use the year, month, day, hour, minute, and second properties of the options object to specify which elements of the date and time should be included in the formatted output.

let date = new Date();
let options = { year: 'numeric', month: 'long', day: 'numeric', hour:'2-digit', minute:'2-digit', second:'2-digit'};
let formatter = new Intl.DateTimeFormat("en-US", options);
console.log(formatter.format(date));
Enter fullscreen mode Exit fullscreen mode

In this example, the date and time will be formatted in the format of 'Month Day, Year Hour:Minute:Second'.

Here is another example, where the date is formatted according to the conventions of the French locale:

let date = new Date();
let formatter = new Intl.DateTimeFormat("fr-FR");
console.log(formatter.format(date));
Enter fullscreen mode Exit fullscreen mode

The output will be in the format of "Day Month Year Hour:Minute:Second"

You can also use the toLocaleDateString() and toLocaleTimeString() methods to format the date and time separately.
For example:

let date = new Date();
console.log(date.toLocaleDateString("fr-FR"));
console.log(date.toLocaleTimeString("fr-FR"));
Enter fullscreen mode Exit fullscreen mode

This will give you the date and time separately in the format of French locale.

As you can see, the Intl.DateTimeFormat() constructor and the related methods in JavaScript provide a powerful and flexible way to format dates and times for different cultures and regions. By carefully specifying the locale and the options, you can ensure that your dates and times are displayed correctly for your users, no matter where they are located.

Conclusion

In conclusion, JavaScript provides various built-in methods and libraries for handling different types of data formats, such as string collation, number formatting, and date and time formats. The Intl object and its properties, such as Collator, NumberFormat, and DateTimeFormat are useful for handling different languages and cultures. Additionally, the toLocaleString() method can also be used for formatting numbers and dates. While these methods and libraries are powerful tools for handling data formatting, it's important to keep in mind the specific requirements and cultural considerations for the target audience when implementing these solutions in your code.

References

That's it for this article😊 ...I hope you found it enlightening, if you did, please don't forget to leave a likeπŸ‘ and follow for more content. Have any questions? Please don't hesitate to drop them in the comment section

Top comments (2)

Collapse
 
andriibodnar profile image
Andrii Bodnar

Great article, thank you! :)

I would like to extend the libraries list with another one powerful and straightforward library to use - LinguiJS. Lingui is a readable, automated, and optimized internationalization library for JavaScript projects.

Collapse
 
sarahokolo profile image
sahra πŸ’«

Oh that's nice...I am actually just getting to know about this. Thank you πŸ‘

Need a better mental model for async/await?

Check out this classic DEV post on the subject.

β­οΈπŸŽ€ JavaScript Visualized: Promises & Async/Await

async await