Connect with us


What’s the JavaScript Internationalization (I18n) API? – SitePoint

English is the world’s most generally used language, but just one in seven folks communicate it. It’s the primary (native) language of 379 million folks, however 917 million communicate Mandarin Chinese language, 460 million communicate Spanish, and 341 million communicate Hindi.

Many non-English audio system reside in rising markets with exponential web progress. In case your internet app might be globally translated, your potential goal market may enhance by 700%!

The JavaScript Internationalization API (often known as i18n) permits you to design internet pages and functions in such a approach that they are often simply tailored to help the wants of customers that talk completely different languages.

On this article, we’ll have a look at the assorted strategies the API gives and how one can implement them in your code to succeed in a wider, extra worldwide viewers.

Internationalization (I18n) Can Be Difficult

Internationalization seems simple … till you attempt to do it.

Latin-based languages might be superficially related. For instance, a kind requesting a reputation, e mail, and date interprets like this:

  • Spanish: nombre, e mail, fecha
  • French: nom, e-mail, date
  • German: title, e mail, datum

The Gettext internationalization and localization system has been round for a number of a long time, and libraries can be found for many programming languages.

In easier instances, you might use some type of tokenization. For instance, take an HTML template containing the next:

<label for="title">{{ NAME }}</label>

That is dynamically changed by ‘title’ when a consumer has English set as their main language. Sadly, that’s the place the issues begin on your consumer interface:

  1. There might be completely different variations of the identical language. The Spanish spoken in Spain just isn’t equivalent to that spoken in South America.
  2. Phrases in a single language might be significantly longer in others. For instance, “e mail” interprets to “электронное письмо” in Russian.
  3. Textual content isn’t all the time oriented from left to proper. Some is written from proper to left — akin to Arabic, Hebrew, Kurdish, and Yiddish. Others might be written from prime to backside, akin to Chinese language, Korean, Japanese, and Taiwanese.

Many points might be addressed by maintaining textual content to a minimal and adopting CSS properties akin to route, writing-mode, and logical dimensions for format.

Terminology Turmoil

Additional confusion will come up when your utility must show dates, occasions, numbers, currencies, or items.

Think about a date proven as “12/03/24”. Will probably be learn as:

  • “3 December 2024” by US residents who use the MDY format
  • “12 March 2024” by European, South American, and Asian residents who use the DMY format, and
  • “24 March 2012” by Canadian, Chinese language, Japanese, and Hungarian residents who go for the significantly extra sensible YMD format.

(Remember that date delimiter slashes are usually not widespread in all languages!)

The quantity “1,000” will likely be learn as:

  • “one thousand” by these within the US, UK, Canada, China, and Japan, and
  • “one (level zero)” by these in Spain, France, Germany, and Russia the place a quantity’s decimal fraction is separated by a comma.

The state of affairs may even be advanced in English alone. The time period “1,000 meters” means:

  • 1 kilometer (or 0.62 of a mile) to US residents
  • a group of 1 thousand measuring devices to these within the UK, Canada, and Australia!

The JavaScript Intl API

The little-known JavaScript Intl object implements the ECMAScript Internationalization API in most fashionable browsers and runtimes. Help is usually good, and even IE11 has lots of the extra helpful strategies. For older browsers, there’s a polyfill, and the API might be detected like so:

if (window.Intl) {

The API is barely uncommon. It offers a number of object constructors for dates, occasions, numbers, and lists, that are handed a locale and an elective object containing configuration parameters. For instance, right here’s a DateTime object specifying US English:

const dateFormatter = new Intl.DateTimeFormat('en-US');

This object can be utilized any variety of occasions to name numerous strategies that are handed a Date() worth (or an ES6 Temporal when obtainable). The format methodology is often essentially the most sensible possibility. For instance:

const valentinesDay = dateFormatter.format( new Date('2022-02-14') );

const starwarsDay = dateFormatter.format( new Date('2022-05-04') );

Alternatively, you may create the Intl object and run a technique in a single line of code:

const starwarsDay = new Intl.DateTimeFormat('en-US').format( new Date('2022-05-04') );

In addition to the format() methodology, some objects help these:

  • formatToParts(): returns an array of objects containing formatted strings, akin to { kind: 'weekday', worth: 'Monday' }
  • resolvedOptions(): returns a brand new object with properties reflecting the locale and formatting choices used, akin to dateFormatter.resolvedOptions().locale.

Defining Locales

All Intl objects require a locale argument. This can be a string which identifies:

  • a language subtag
  • a script subtag (elective)
  • a area (or nation) subtag (elective)
  • a number of variant subtags (elective)
  • a number of BCP 47 extension sequences (elective)
  • a private-use extension sequence (elective)

The language and area is commonly sufficient. For instance, "en-US", "fr-FR", and so forth.

In addition to utilizing a string, an Intl.locale object can be utilized to assemble locales, akin to English US with 12-hour time format:

const us = new Intl.Locale('en', {
  area: 'US', hourCycle: 'h12', calendar: 'gregory'

This can be utilized in one other Intl constructor. For instance:

new Intl.DateTimeFormat(us, { timeStyle: 'medium' })
  .format( new Date('2022-05-04T13:00:00') );

If no locale is outlined, the system’s present language and area settings are used. For instance:

new Intl.DateTimeFormat().format( new Date('2022-05-04') );

This returns "5/4/2022" on a tool with US settings and "04/05/2022" on a tool with UK settings.

Dates and Instances

The next software reveals examples of dates and occasions formatted utilizing Intl.DateTimeFormat() (apologies in case your language or area isn’t listed!):

See the Pen
i18n date and time formatting software
by SitePoint (@SitePoint)
on CodePen.

The constructor is handed the locale and an choices object. This has many doable properties, though you hardly ever require greater than dateStyle and/or timeStyle:

property description
dateStyle the date model: "full" "lengthy" "medium" "quick"
timeStyle the time model: "full" "lengthy" "medium" "quick"
calendar choices embody: "chinese language" "gregory" "hebrew" "indian" "islamic" and so forth.
dayPeriod interval expressions: "slim" "quick" "lengthy"
numberingSystem numbering system: "arab" "beng" "fullwide" "latn" and so forth.
localeMatcher locale matching algorithm: "lookup" "finest match"
timeZone time zone: "America/New_York" "Europe/Paris" and so forth.
hour12 set true to make use of 12-hour time notation
hourCycle hour cycle: "h11" "h12" "h23" "h24"
formatMatcher format matching algorithm: "primary" "finest match"
weekday weekday format: "lengthy" "quick" "slim"
period period format: "lengthy" "quick" "slim"
yr yr format: "numeric" "2-digit"
month month format: "numeric" "2-digit" "lengthy" "quick" "slim"
day day format: "numeric" "2-digit"
hour hour format: "numeric" "2-digit"
minute minute format: "numeric" "2-digit"
second second format: "numeric" "2-digit"
timeZoneName both: "lengthy" "quick"


new Intl.DateTimeFormat("ja-JP", { dateStyle: "quick" })
  .format( new Date("2022-05-04T13:00") );

new Intl.DateTimeFormat("en-US", { dateStyle: "quick", timeStyle: "quick" })
  .format( new Date("2022-05-04T13:00") );

new Intl.DateTimeFormat("en-GB", { dateStyle: "lengthy", timeStyle: "quick" })
  .format( new Date("2022-05-04T13:00") );

new Intl.DateTimeFormat("es-ES", { dateStyle: "full", timeStyle: "full" })
  .format( new Date("2022-05-04T13:00") );

Date Ranges

A formatRange() methodology takes two dates and codecs the interval in essentially the most concise approach relying on the locale and choices. For instance:

new Intl.DateTimeFormat("en-US", { dateStyle: "lengthy", timeStyle: "quick" })
  .formatRange(new Date("2022-05-04T13:00"), new Date("2022-05-04T14:00"))

This methodology has extra restricted browser help however was applied in Chrome 76.

Relative Durations

The Intl.RelativeTimeFormat() object can show durations relative to this second in time. The choices object has fewer choices:

property description
localeMatcher locale matching algorithm: "lookup" "finest match"
numeric both "all the time", e.g. "1 day in the past" or "auto", e.g. "yesterday"
model format: "lengthy" "quick" "slim"

The format() methodology is handed a numeric worth and a unit: "yr", "quarter", "month", "week", "day", "hour", "minute", or "second". Examples:

new Intl.RelativeTimeFormat("en-US")
  .format( -1, "day" );

new Intl.RelativeTimeFormat("en-US", { numeric: "auto" })
  .format( -1, "day" );

new Intl.RelativeTimeFormat("de-DE", { numeric: "auto" })
  .format( 1, "month" );

Numbers, Currencies, Percentages, and Items

The next software reveals examples utilizing Intl.NumberFormat() to format numbers, currencies, percentages, and measurement items:

See the Pen
i18n quantity and forex formatting software
by SitePoint (@SitePoint)
on CodePen.

The constructor is handed the locale and an choices object:

property description
numberingSystem choices embody "arab" "beng" "deva" "fullwide" "latn" and so forth.
notation kind: "customary" "scientific" "engineering" "compact"
model formatting: "decimal" "forex" "p.c" "unit" — this determines which different choices might be set
forex forex code: "USD" "EUR" "GBP" and so forth.
currencyDisplay forex formatting: "image" "narrowSymbol" "code" "title"
currencySign for detrimental forex values, "customary" a minus signal or "accounting" for parenthesis
unit a unit kind: "centimeter" "inch" "hour" and so forth.
unitDisplay unit format: "lengthy" "quick" "slim"
useGrouping set false to disable 1000’s separators
minimumIntegerDigits minimal variety of integer digits
minimumFractionDigits minimal variety of fraction digits
maximumFractionDigits most variety of fraction digits
minimumSignificantDigits minimal variety of vital digits
maximumSignificantDigits most variety of vital digits


new Intl.NumberFormat("en-US", { maximumSignificantDigits: 2 })
  .format( 12345.6789 );

new Intl.NumberFormat("fr-FR", { maximumSignificantDigits: 3 })
  .format( 12345.6789 );

new Intl.NumberFormat("en-US", { notation: "compact", maximumSignificantDigits: 0 })
  .format( 12345.6789 );

new Intl.NumberFormat("es-ES", {
  model: "forex",
  forex: "USD",
  currencyDisplay: "image"
  .format( 12345.6789 );

new Intl.NumberFormat("en-GB", {
  maximumSignificantDigits: 0,
  model: "unit",
  unit: "meter",
  unitDisplay: "lengthy"
  .format( 12345.6789 );


A Intl.ListFormat() object can format an array of things right into a language-sensitive listing. In English, that usually requires an “and” or an “or” earlier than the final merchandise.

The choices object can set the next properties:

property description
kind output format: "conjunction" for and-based lists, "disjunction" for or-based lists
model formatting: "lengthy" "quick" "slim"


const browsers = ['Chrome', 'Firefox', 'Edge', 'Safari'];

new Intl.ListFormat("en-US", { kind: "conjunction" }).format(browsers);

new Intl.ListFormat("en-US", { kind: "disjunction" }).format(browsers);

new Intl.ListFormat("fr-FR", { kind: "conjunction" }).format(browsers);

new Intl.ListFormat("fr-FR", { kind: "disjunction" }).format(browsers);


The marginally weird Intl.PluralRules() object allows plural-sensitive language guidelines the place you could have various objects. The choices object can set a kind property to both:

  • cardinal: the amount of issues (the default), or
  • ordinal: the rating of issues, akin to 1st, 2nd, or third in English

The choose() methodology returns an English string representing the pluralization class of the quantity: both zero, one, two, few, many, or different.


new Intl.PluralRules("en-US", { kind: "cardinal" }).choose(0);

new Intl.PluralRules("en-US", { kind: "ordinal" }).choose(0);

new Intl.PluralRules("en-US", { kind: "cardinal" }).choose(1);

new Intl.PluralRules("en-US", { kind: "ordinal" }).choose(1);

new Intl.PluralRules("en-US", { kind: "cardinal" }).choose(2);

new Intl.PluralRules("en-US", { kind: "ordinal" }).choose(2);

new Intl.PluralRules("en-US", { kind: "cardinal" }).choose(3);

new Intl.PluralRules("en-US", { kind: "ordinal" }).choose(3);

String Comparability

Lastly, the Intl.Collator() object allows language-sensitive string comparability. Its choices object can set the next properties:

property description
collation variant collation for sure locales
numeric set true for numeric collation the place “1” < “2” < “10”
caseFirst both "higher" or "decrease" case first
utilization both string "type" (default) or "search"
sensitivity "base" "accent" "case" "variant" comparisons
ignorePunctuation set true to disregard punctuation

The examine() methodology compares two strings. For instance:

new Intl.Collator('de').examine('z', 'ä');


It needs to be easy to indicate info utilizing the consumer’s native format for those who’re utilizing JavaScript to show information. For instance, the next code defines a dateFormat() perform which makes use of the Intl quick date format or falls again to YYYY-MM-DD when that’s not supported:

const dateFormat = (Intl && Intl.DateTimeFormat ?
  date => new Intl.DateTimeFormat({ dateStyle: 'quick' }).format(date) :
  date => date.toISOString().slice(0, 10)

doc.getElementById('immediately').textContent = dateFormat( new Date() );

This alone received’t make your app simple for a global viewers, nevertheless it’s one step nearer to world distribution.

Click to comment

Leave a Reply

Your email address will not be published. Required fields are marked *