Привет, друзья! В данной статье я хочу рассказать вам об Internationalization API — интерфейсе, предоставляемом браузером, позволяющем выполнять интернационализацию и локализацию веб-приложений. Статья состоит из 2 частей: теоретической и практической. В теоретической части мы кратко рассмотрим возможности, предоставляемые Internationalization API. В практической — создадим пример локализованного приложения с помощью разработанной мной утилиты. Internationalization API предоставляет следующие возможности: В настоящее время Internationalization API поддерживается всеми современными браузерами. Несмотря на то, что в JavaScript существуют такие методы для локализации как: их зачастую оказывается недостаточно. Кроме того, поведение данных методов определяется конкретной реализацией ECMAScript, т.е. браузером. Функционал, определенный в Internationalization API, инкапсулирован в объекте Intl. Данный объект не имеет внутреннего метода , поэтому не может вызываться как конструктор с помощью ключевого слова new. Он также не имеет внутреннего метода , поэтому не может вызываться как функция. Intl включает в себя следующие интерфейсы-конструкторы: Возможные значения: Пример получения текущей даты и времени в дефолтной локали Конструктор Locale используется для создания экземпляров идентификаторов локали. Первым обязательным аргументом, передаваемым Locale, является локаль, которая может состоять из следующего: В большинстве случаев достаточно указать код языка или код языка и код страны через дефис: Вторым опциональным аргументом Locale является объект с настройками: Локаль может быть строкой или объектом. Пустой массив означает использование текущей локали пользователя: Конструктор DateTimeFormat используется для форматирования даты и времени. Он принимает локаль и объект с настройками. Сигнатура Настройки Настройки localeMatcher и formatMatcher могут передаваться любому конструктору, предоставляемому Intl, но используются редко. По умолчанию new Intl.DateTimeFormat().format() возвращает текущую дату в кратком виде (dateStyle: short). Примеры Другие методы Конструктор RelativeTimeFormat используется для локализации относительного времени, например, вчера, завтра, на следующей неделе, в прошлом месяце и т.д. Данный метод принимает локаль и объект с настройками. Сигнатура Положительное число в amount означает будущее, отрицательное — прошлое. Настройки В данном случае метод format в качестве аргументов принимает число и единицу времени. Примеры Конструктор NumberFormat используется для форматирования чисел, валюты, процентов и единиц измерения, таких как длина, температура и др. Данный метод принимает локаль и объект с настройками. Сигнатура Настройки Примеры Конструктор DisplayNames используется для форматирования названий языков, диалектов, регионов и валют на другом языке. Данный метод принимает локаль и объект с настройками. Сигнатура Настройки Обратите внимание: настройка type является обязательной. При этом хорошо поддерживается только type со значением language. Примеры Конструктор ListFormat используется для форматирования списков путем подстановки соединительного союза И или разделительного союза ИЛИ. Данный метод принимает локаль и объект с настройками. Сигнатура Настройки Примеры Конструктор Collator используется для сравнения строк с учетом локали. Данный метод принимает локаль и объект с настройками. Сигнатура Настройки Результат Примеры Конструктор PluralRules используется для плюрализации (перевода во множественное число). Данный метод принимает локаль и объект с настройками. Сигнатура Настройки Примеры В настоящее время поддерживается только локаль en-US. В данном разделе мы создадим небольшое локализованное приложение с помощью разработанной мной утилиты easy-intl. Принцип работы утилиты подробно описан в документации. Многие вещи были рассмотрены в теоретической части. Поэтому, с вашего позволения, здесь я опишу только ключевые моменты. Демо приложения: Создаем директорию для проекта и устанавливаем easy-intl: Структура проекта будет следующей: Как сказал бы Ватсон, все ЭЛЕМЕНТАРНО. В стилях у нас не будет ничего интересного, поэтому Что касается разметки, то в процессе локализации easy-intl ориентируется на следующие атрибуты: Вот как будет выглядеть наша разметка: Здесь у нас имеется следующее: Определим некоторые настройки для глобальной локализации в intl/options.js (некоторые настройки являются дефолтными, но в данном случае большого значения это не имеет): Определим словарь для заголовков в intl/dictionary.js для русского и американского английского языков: Переходим к основному скрипту (script.js). Импортируем EasyIntl, настройки и словарь: Создаем экземпляр EasyIntl, передавая в конструктор локаль en-US, селектор корневого элемента для глобальной локализации, словарь и настройки (обратите внимание, что объект настроек должен быть распакован): Поскольку мы не определяем настройку autorun со значением false, создание экземпляра EasyIntl приводит к автоматической локализации приложения (за исключением содержимого дочерних элементов local_root). Прелесть easy-intl (и, конечно, самого Intl) заключается в том, что дефолтная локаль пользователя определяется автоматически. Это означает, что для локализации приложения на языке пользователя достаточно создать экземпляр EasyIntl (разумеется, при условии добавления к необходимым элементам атрибутов data-intl_type и data-intl_value). Поскольку для всех вспомогательных функций, используемых easy-intl, включая, корневой элемент, определены дефолтные настройки (многие дефолтные настройки определяются Intl), для локализации приложения достаточно выполнить: Посмотрим на локализуемые элементы, карту локализации, в целом, и локализацию основного заголовка, в частности: Выполним ручную локализацию содержимого дочерних элементов local_root: Получаем ссылку на переключатель локали и обрабатываем ее изменение: Приоритет настроек следующий (от минимального к максимальному): Получаем вполне работоспособное локализованное приложение: 
 
 Пожалуй, это все, чем я хотел поделиться с вами в данной статье. Если вас заинтересовала утилита easy-intl, не стесняйтесь использовать ее в своих проектах. Как всегда, приветствуется любой фидбэк как в форме личных сообщений, так и на GitHub. Что касается планов по дальнейшей разработке утилиты, то, кроме небольших доработок, связанных с преобразованием строковых значений атрибутов data-intl_value в пригодный для Intl формат, в них входит добавление типов для TypeScript и, возможно, адаптация утилиты под React в форме хука или связки провайдера и хука. Как видите, Internationalization API предоставляет довольно интересные возможности, которые при правильном использовании могут существенно облегчить процесс интернационализации и локализации веб-приложений. Вместе с тем надо понимать, что Internationalization API не предназначен для перевода (его задачи четко обозначены в спецификации), поэтому многие вещи придется делать вручную или прибегать к помощи таких интерфейсов, как Google Cloud Translation API или API Переводчика Яндекса. Также важно учитывать, что Internationalization API является относительно новым интерфейсом, некоторые его возможности еще находятся в процессе реализации браузерами, и, вероятно, в будущем появятся новые "фичи". Благодарю за внимание и хорошего дня!  JavaScript Developer