🌎 Building an Intl Language Dropdown

Let's build a quick language dropdown, but let's do it only using Intl in React with no specialty libraries. We will learn about language codes, discover some of what's possible with Intl and perhaps start you on a journey towards internationalizing your next application.

Language Codes

Language codes can be a deceivingly simple on first look, but there are many more language codes than you may expect. For our dropdown, let's focus on what Intl uses. Intl defines a locale that can be made of different parts separated by dashes. The first part identifies the language such as English ( en ) and the remaining parts are optional. One example could be the region such as the United States (US). Putting that together you would get en-US .

Intl.Locale - JavaScript | MDN
The Intl.Locale object is a standard built-in property of the Intl object that represents a Unicode locale identifier.

This may look familiar because Intl.Locale is adjacent to the IETF standard shown below. IETF references several ISO codes to comprise a single string to describe the details of a language.

  1. ISO 639-1 Language Code such as en for English
  2. ISO 3166-1 Country Code such as US for United States
  3. ISO 15924 Script Code such as Latn for Latin
🗒️
Note
The specification calls out certain capitalization for example the country codes being US vs us but some tools will allow using different casing.

Example: lowerCaseLng in i18next configuration options

Locale adds a couple more features but in general the combination of these additional language options leads to more specific variations such as this Wikipedia example of nan-Hant-TW for Min Nan Chinese using traditional Han characters, as spoken in Taiwan.

IETF language tag - Wikipedia

In our code, we will be using just a quick array of languages.

const languages = ['en', 'fr', 'es']

In production code, you may wish to type these with a dictionary to use friendlier names.

const language = {
  english: 'en'
  french: 'fr'
  spanish: 'es'
} as const;

Intl & Display Names

Many developers may be familiar with the Date functions of Intl such as toLocaleString(), but there is also a handy display name function that gives information from a language code.

Intl.DisplayNames - JavaScript | MDN
The Intl.DisplayNames object enables the consistent translation of language, region and script display names.

For example, you can determine the name of region

let regionNames = new Intl.DisplayNames(["en"], { type: "region" });
regionNames.of("US"); // "United States"
regionNames.of("BZ"); // "Belize"

In our case, we want to look at the language . This way we can craft our dropdown options.

let regionNames = new Intl.DisplayNames(["en"], { type: "language" });
regionNames.of("en"); // "English"
regionNames.of("es"); // "Spanish"
regionNames.of("zh"); // "Chinese"

This is helpful but what would be even better is to get the language in its native tongue. This way a user can recognize their own language. We can do this by passing the same language in the Intl.DisplayNames as the of function. This results in this function:

const getLanguage = (language: string): string => {
  return new Intl.DisplayNames(
    [language], 
    { type: 'language' }
  ).of(language);
}

getLanguage('en') // "English"
getLanguage('fr') // "français"
getLanguage('zh') // "中文"

Now that we have this function, let's create a simple drop down.

Building the DropDown

So we have an array of languages and a convenient method to get the language name translated in its native tongue, now we just need to map those to our dropdown options.

// Languages
const languages = ['en', 'fr', 'es']

// Function
const getLanguage = (language: string): string => {
  return new Intl.DisplayNames(
    [language], 
    { type: 'language' }
  ).of(language);
}

A simple version is just a select with our languages mapped to option s. Here I add a quick handleChange and some state to assist.

const LanguageDropdown = () => {
  const [selectedValue, setSelectedValue] = useState<string>(languages[0]);
  const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
    setSelectedValue(event.target.value);
  };

  return (
    <select id="dropdown" value={selectedValue} onChange={handleChange}>
      {languages.map((language) => (
        <option key={language} value={language}>
          {getLanguage(language)}
        </option>
      ))}
    </select>
  );
}

Demonstration

Let's see this all put together. This CodePen showcases the React & TypeScript with a little CSS flavoring. Feel free to try additional language codes like en or language & country codes like en-US to see how they show up. Have fun!

Press Run Pen to see the live demonstration of the Language Dropdown

Next Steps

So you have a language dropdown now, where can you take this? Take a look at my previous post on Localization using i18next. You can combine the two methods to create a drop down relying on the language in i18next state and detect by i18next plugins. As always, we're here to help at IRT if you have any questions!

A Dive Into Localization
Localization is not just about translating words but adapting a user experience to fit different cultures and regions. In today’s global market, localization is a game-changer for software products. Software Dev Keith Fung dives into why it’s crucial for engineers and business leaders.