Localization

Multi-Language Applications

Localization

In today’s globalized digital landscape, catering to a worldwide audience is essential for the success of any web application. Internationalization (i18n) plays a crucial role in making applications accessible and user-friendly across different languages and regions. This article explores how to localize specific parts of a web page on an HTML5 application, using i18n with the popular i18next library.

Internationalization refers to the process of designing an application in a way that allows easy adaptation to various languages and cultural norms without requiring significant engineering changes. It lays the groundwork for localization, which is the actual adaptation of an application for specific regions or languages.

i18next is a powerful internationalization framework for JavaScript applications. It provides a comprehensive solution for managing translations, language detection, and dynamic content updates. Its flexibility and ease of integration make it a preferred choice for developers aiming to create multilingual applications.

To use i18i, the first step is to ensure that the essential scripts are included in the HTML:


<script src="/assets/js/lib/i18next.min.js"></script>
<script src="/assets/js/lib/i18next-browser-language-detector.min.js"></script>
<script src="/assets/js/translation.min.js"></script>
<script src="/assets/js/localization.min.js"></script>
  • i18next.min.js: The core i18next library.
  • i18next-browser-language-detector.min.js: Plugin for detecting the user’s language preference.
  • translation.min.js: Contains translation resources.
  • localization.min.js: Custom script handling the localization logic.

I maintain a separate translation.js file to store all translation strings. This separation ensures that the main JavaScript files remain clean and maintainable. An example structure for translation.js might look like this:


const translations = {
  en: {
    translation: {
      navbarDropdownMenuLink: "Menu",
      appTitle: "Color Picker",
      gradientModalLabel: "Gradient Settings",
      colorModeLabelColor: "Color Mode",
      colorModeLabelGrayscale: "Grayscale Mode"
      // Others resources
    }
  },
  it: {
    translation: {
      navbarDropdownMenuLink: "Menu",
      appTitle: "Selettore di Colori",
      gradientModalLabel: "Impostazioni Gradiente",
      colorModeLabelColor: "Modalità Colore",
      colorModeLabelGrayscale: "Modalità Scala di Grigi"
    }
  }
  // More languages
};

In the localization.min.js, I initialize i18next with the language detector and translation resources. Here’s a detailed breakdown of the initialization process:


$(document).ready(function() {
  // Initialize i18next with the language detector and translations
  i18next
    .use(i18nextBrowserLanguageDetector)
    .init({
      detection: {
        order: ['querystring', 'localStorage', 'navigator'],
        caches: ['localStorage'] // Cache detected language in localStorage only
      },
      resources: translations, // Use the global translations object from translation.js
      fallbackLng: 'en', // Fallback language
      debug: false
    }).then(() => {
      updateContent(); // Load initial translations based on detected language
    });

  // Function to set language in i18next and save it to localStorage
  window.setLanguage = function(lang) {
    i18next.changeLanguage(lang).then(() => {
      localStorage.setItem('language', lang); // Save language preference to localStorage
      updateContent(); // Update content with new language
    });
  };

  // Function to update content based on current language
  function updateContent() {
    const autoContents = [
      'navbarDropdownMenuLink',
      'appTitle',
      'gradientModalLabel'
    ];
    autoContents.forEach(word => {
      const element = document.getElementById(word);
      if (element) element.textContent = i18next.t(word);
    });
    // Update the color switch text
    const colorModeLabel = document.getElementById('colorModeLabel');
    const colorGrayScale = document.getElementById('colorGrayScale');
    if (colorModeLabel && colorGrayScale) {
      colorModeLabel.textContent = colorGrayScale.checked
        ? i18next.t('colorModeLabelColor')
        : i18next.t('colorModeLabelGrayscale');
    }
  }
});
  • Language Detection: The i18nextBrowserLanguageDetector plugin detects the user’s language preference through query strings, local storage, and browser settings, in that order. The query string can specify a language like this: ?lng=it (where it sets the language to Italian).

  • Resource Management: The resources property utilizes the translations object from the translation.js file, ensuring all translation strings are centralized.

  • Fallback Language: If the user’s preferred language isn’t available, the application defaults to English (fallbackLng: 'en').

  • Language Switching: The setLanguage function allows dynamic language changes. When a user selects a different language, it’s saved to localStorage, and the content updates accordingly.

  • Content Update: The updateContent function iterates through specified element IDs and updates their text content based on the current language. It also handles conditional text updates, such as toggling between color modes.

Ensure that the HTML elements intended for localization have corresponding IDs that match the keys in the translation files. For example:


<nav>
  <a id="navbarDropdownMenuLink">Menu</a>
  <h1 id="appTitle">Color Picker</h1>
</nav>

<!-- Modal -->
<div id="gradientModal">
  <label id="gradientModalLabel">Gradient Settings</label>
  <!-- Additional modal content -->
</div>

<!-- Color Mode Switch -->
<label id="colorModeLabel">Color Mode</label>
<input type="checkbox" id="colorGrayScale" onchange="updateContent()">

Implement language selection options to allow users to choose their preferred language. This can be done through buttons, dropdown, or other elements. For instance:


<select onchange="setLanguage(this.value)">
  <option value="en">English</option>
  <option value="it">Italiano</option>
  <!-- Add more languages as required -->
</select>

When a user selects a different language, the setLanguage function updates the application’s language, saves the preference, and refreshes the content accordingly.

Some suggestion can be useful to ensure an effective localization:

  • Consistent naming: Use consistent and descriptive IDs for elements that require translation. This practice simplifies the mapping between translation keys and HTML elements.
  • Modular translation files: Organize translations in a modular fashion, grouping related strings together. This approach enhances maintainability and scalability.
  • Avoid hardcoded text: Refrain from embedding text directly within HTML or JavaScript. Instead, always reference translation keys to ensure consistency and ease of updates.
  • Test across languages: Regularly test the application in different languages to identify and rectify layout issues, text overflows, or untranslated strings.
  • Leverage fallbacks: Always define a fallback language to ensure that the application remains functional even if certain translations are missing.

Implementing internationalization using i18next significantly enhances the accessibility and user experience of an HTML5 application. By following the steps outlined above, specific parts of a web page, such as the application menu, can be efficiently localized, ensuring that the application can be used by a wider audience.