Note: ⚠️ This article is the first signed article by the Nuggets community. It is prohibited to be reproduced without authorization

Multilanguage (I18N) support is a necessary step toward internationalization for enterprise projects and a best practice for front-end engineers. However, there are many multi-language frameworks, which will bring a series of selection problems. I believe that when you carry out multi-language support for a project, you will often encounter the following problems:

  • How do I choose a multilingual solution for different technology stacks?
  • How do you implement multilanguage support for your project independently without resorting to third-party libraries?
  • What questions should I consider when practicing a multilingual solution? How to implement multiple languages more efficiently?

In fact, there are many multi-language frameworks, but from the traditional jquery era to the current popular MVVM framework, multi-language solutions have been evolving and optimizing, the ultimate goal is to make them universal and simplified. Understanding this makes learning multilingual technologies much easier.

In the process of designing and practicing low-code/zero-code building platform Dooring, I also encountered the technical selection of multi-language solutions, which has been basically completed at present. Next, I will lead you to analyze the implementation solutions of multi-language in different technology stacks step by step, and let you master multi-language technologies through practical projects. At the end of this article I will also suggest some directions for the future evolution of multilingualism for you to study and explore.

In keeping with my usual writing style, I will outline the articles below so that you can read and learn them efficiently and selectively:

  • Introduction and practice of current commonly used multilingual schemes
    • Native JS /jquery solution for multiple languages
    • The multilingual solution in the VUE project
    • Multilingual solutions in the React project
  • Use @umijs/plugin-locale to land the internationalization project
  • Intelligent internationalization program imagination

Introduction and practice of current commonly used multilingual schemes

At present, the commonly used multi-language schemes are basically human translation and dynamic substitution to achieve language switching, but different technical framework patterns are slightly different, and we will analyze one by one next.

1. Native JS /jquery solution to achieve multiple languages

The easiest thing to think of in a traditional scenario is a DOM replacement. We do this by defining multiple language files (or copy maps) in advance, doing language mappings in HTML tags, and dynamically switching site languages through the switch function. The basic pattern is as follows:

// Library, we have two ways to define
// 1. Single-file Map mode, lang.js
const lang = {
  zh: {
        'title''H5 Editor '.'userLogin''User Login'.'usernameError': 'Please enter a user name'
    },
  en: {
        'title''H5 editor'.'userLogin''The user logs on'.'usernameError': 'Please enter your username'}},// 2. Multilingual package mode
lang/cn.json 
lang/en.json
Copy the code

The HTML tag structure is as follows:

<select id="langControl">
  <option value="cn">Chinese</option>
  <option value="en">English</option>
</select>

<div lang="title">H5 editor</div>
<div lang="userLogin">The user login</div>
Copy the code

Finally, we iterate through the [lang] property in javascript and replace the language with a mapping. Of course, we can also use template engines such as template-js to optimize our DOM rendering alternatives, but there are still a lot of issues to consider in the landing process. As follows:

  • Language persistence needs to be handled separately
  • Cannot dynamically add language text
  • Unable to introduce variables and read language text
  • Lack of flexibility and configuration

In order to solve these problems and support more complex systems in the traditional solution, we had to consider plug-ins, of course, jquery-i18n is a very good solution. It helps you internationalize Web applications easily, supports chained calls, and switches languages without refreshing. Next, I will use Jquery-I18n to achieve a simple demo, so that you can better master the scheme.

  1. The introduction of resources
<script src="https://cdn.bootcss.com/jquery/3.10.2/jquery.min.js"></script> 
<script src="https://cdn.bootcss.com/js-cookie/latest/js.cookie.min.js"></script> 
<script src="./js/jquery.i18n.js"></script>
Copy the code
  1. Create and configure multilingual files

  1. Writing page content
<select id="langControl">
  <option value="cn">Chinese</option>
  <option value="en">English</option>
</select>

<div lang="title">H5 editor</div>
<div lang="userLogin">The user login</div>
Copy the code
  1. Initialize the I18N configuration and implement the language switch logic
function toggleLang(lang){$("[lang]").i18n({
       defaultLang: lang,  // Default language
       filePath: "/lang/".// The directory where the language file is located
       filePrefix: "".// Language file prefix
       fileSuffix: "".// Language file suffix
       forever: true.callback: function(res) {}  // Callback after initialization
   });
}

// Language switch
$('#langControl').change(val= > {
   toggleLang(val)
})
Copy the code

Jquery-i18n has more powerful configurations. You can refer to the documentation to configure jquery-i18n.

  • Jquery-I18n
  • jquery-i18n-properties

Of course, the above scheme is just manually switching the language, more demand scenarios are based on the user’s current browser environment or website link address parameters to automatically switch the corresponding language. To change the system language by linking parameters, we only need to parse the parameters and handle them accordingly, such as parsing http://xxx.xxx? LAN = cn or http://xxx.xxx? LAN = en. Of course, the browser also provides an API to get the context in which the user is currently browsing: navigator.language. The result of typing this script into the browser console is as follows:

So we can use this information to automatically match the user’s current language pattern.

2. Multi-language solution in vUE project

There are also many multi-language solutions based on Vue on the Internet, after all, most domestic enterprises are using Vue to develop projects, so I simply list a few mature solutions for you, and give a specific practice for one of them:

  • vuex-i18n
  • vue-i18n

Of course, if you do not very complex project, you can also directly use the simplest I18N, because it is more simple and lightweight.

I will use a complete example to illustrate how to internationalize a VUE project using vuE-I18N.

  1. Define language files

  1. Introduce dependencies and register the language pack
import Vue from "vue";
import VueI18n from "vue-i18n";

Vue.use(VueI18n);

// Load all locales and remember the context
function loadMessages() {
  const context = require.context("./lang".true./[a-z0-9-_]+.json$/i);

  const messages = context
    .keys()
    .map((key) = > ({ key, locale: key.match(/[a-z0-9-_]+/i) [0] }))
    .reduce(
      (messages, { key, locale }) = > ({
        ...messages,
        [locale]: context(key),
      }),
      {}
    );

  return { context, messages };
}

const { context, messages } = loadMessages();

/ / VueI18n instance
const i18n = new VueI18n({
  locale: navigator.language, // Set the website language according to the browser environment
  messages,
});

// Run the program
const app = new Vue({
  i18n,
  // ...
}).$mount('#app');

// Switch the language ($i18n.locale can also be used within the component to switch the locale)
i18n.locale = 'en-US'

// Hot update support
if (module.hot) {
  module.hot.accept(context.id, () = > {
    const { messages: newMessages } = loadMessages();

    Object.keys(newMessages)
      .filter((locale) = >messages[locale] ! == newMessages[locale]) .forEach((locale) = > {
        messages[locale] = newMessages[locale];
        i18n.setLocaleMessage(locale, messages[locale]);
      });
  });
}
Copy the code

Of course, we can also load translation lazily in the project, similar to the principle of webPack asynchronous load files, see below:

export function loadLangAsync(lang) {
  // If the language is the same
  if (i18n.locale === lang) {
    return Promise.resolve(...)
  }

  // If the language is already loaded
  if (loadedLanguages.includes(lang)) {
    return Promise.resolve(...)
  }

  // If the language has not been loaded
  return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${lang}.json`).then(
    messages= > {
      / /... Processing logic})}Copy the code

Vue-cli also provides the corresponding plug-in vue-CLI-plugin-i18n to enable multiple languages through configuration.

3. Multilingual solution in react project

First of all, multilingualism has a very simple solution in both Vue and React projects,

The basic process is as follows:

  1. Define multilingual files
  2. Introduce into application
  3. The application sets the current locale based on priority and writescookie
  4. Rewrite when switching languagescookieLanguage information and refresh the page

Of course, there are many mature solutions in the market, such as:

  • react-intl
  • react-i18next + i18next
  • react-intl-universal

Next, the author will combine his own case and use react-I18Next + i18Next scheme to implement a complete demo.

  1. Install dependencies
# npm
$ npm install react-i18next i18next --save
Copy the code
  1. Define the language pack (again, not to be restated here)

  2. Code implementation

    3.1 Configuring the I18N globally

// i18n.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import en from 'locales/en-US.js';
import cn from 'locales/zh-CN.js';


const resources = {
  en: {
    translation: en
  },
  cn: {
    translation: cn
  }
};

i18n
  .use(initReactI18next) / / register
  .init({
    resources,
    lng: "cn".// Default language
    interpolation: {
      escapeValue: false // XSS safety switch}});export default i18n;
Copy the code

3.2 Entry File Configuration

// index.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
/ /... Other libraries
import './i18n';
import App from './App';

ReactDOM.render(
  <App />.document.getElementById("root"));Copy the code

3.3 Use in the React component:

import React from 'react';
import { useTranslation } from 'react-i18next';

function Home () {
  const { t, i18n } = useTranslation();
  return <h1>{t('title')}</h1>
}
Copy the code

That’s the whole process, but you can also use the library for more interesting features.

Use @umijs/plugin-locale to land the internationalization project

After introducing multi-language solutions for different technology stack implementations, let’s take h5-Dooring as a practical example to internationalize it. Since THE H5-Dooring editor is mainly developed with React and UMI is used as the engineering solution, I naturally choose the ecology corresponding to UMI for implementation. Fortunately, it provides the @umijs/plugin-locale plug-in out of the box, so we can easily achieve internationalization. Next, I will use this scheme to bring you internationalization. If you are also using UMI, you can refer to it.

Let’s start with the renderings:

First we need to configure the umirc.ts file and add the following configuration:

locale: {
    default: 'zh-CN'.// Default language
    antd: true.// Whether antD also supports internationalization
    title: true.// Whether the page title supports internationalization
    baseNavigator: true.// Enable browser language detection
},
Copy the code

Next we need to define multilingual files:

The content of the language file is as follows:

With the basics in place, let’s look at how to use multiple languages on a project. We have an entry page as an example:

First we need to introduce the corresponding plug-in, as follows:

import { useIntl, setLocale } from 'umi';
Copy the code

Next, use hooks in the hooks module:

const Home = ({ location }) = > {
  / /... Other logical states
  const [lang, setLang] = useState('En');
  const intl = useIntl();
  
  return <div>
      <span className={styles.btnControl} onClick={toggleLang}>{ lang }
      </span>
      <h3>{ intl.formatMessage({id: 'dr.friendHelp'}) }</h3>
      <h3>{ intl.formatMessage({id: 'dr.personHelp'}) }</h3>
      <Form.Item label={ intl.formatMessage({id: 'dr.cpEnName'})}name="cpField" rules={[{ required: true.message: intl.formatMessage({id: 'dr.cpInfoError'}, { text: intl.formatMessage({id: 'dr.cpName'})}) }]}>
         <Input placeholder={ intl.formatMessage({id: 'dr.cpInfoError'}, { text: intl.formatMessage({id: 'dr.cpEnName'})}) } />
      </Form.Item>
  </div>
}
Copy the code

That’s the basic implementation. We can use variables in language files and dynamically specify their values in the project. Isn’t that powerful? For multi-language switching, the enterprise provides a corresponding API and supports two modes: no-refresh switching and refresh switching. The modes are as follows:

const toggleLang = () = > {
    if(lang === 'En') {
      setLocale('en-US'.false);
      setLang('Chinese')
      return
    }
    setLocale('zh-CN'.false);
    setLang('En');
  }
Copy the code

As you can see, we use the setLocale API to switch languages. The first parameter is the language text, and the second parameter is whether to refresh the page when switching languages.

Intelligent internationalization program imagination

I spent a lot of energy and time in the process of translation. If the website becomes more and more complex, more energy will be put into it. Therefore, the general intelligent translation scheme will be an urgent problem to be solved in the future, and it is also the only way for the evolution of international I18N. Although some large domestic companies have been doing corresponding things internally, and even some solutions have been accumulated, here I would like to give a basic idea:

In this way, we only need to do normal development based on one language, and the other languages will be automatically translated and converted to the corresponding language files through our tools. In the future, the author will implement this scheme, and you can try different intelligent schemes to explore the way to improve the front-end efficiency.

The articles

  • How to design a component store that visually builds a platform?
  • Design the visualized large screen building engine from zero
  • Build the desktop visual editor Dooring from zero using electron
  • (low code) Visual build platform data source design analysis
  • Build PC page editor PC-Dooring from scratch
  • How to build building blocks to develop H5 pages quickly?