Search code examples
dynamicvuejs2internationalizationlocalevue-i18n

How to access different locale files situated in different folder in Vuei18n?


I want to implement a gender-specific locale management system which means for some languages like Hebrew and Arabic the text would be different for males and females. So what I did is, created separate files for males and females. Here is my directory structure-

locales
  female
    he.json
    ar.json
  male
    he.json
    ar.json
  en.json

Now, I want that for female users the locale file should be selected from the female folder, and in the case of male users, it should be selected from the male folder. In the case of the English language, the file, "en.json" would be the same for both males and females .

The gender details are stored in the Vue state, so in the i18n.js file, I am checking the user's gender and updating the path of the locale file. Here is my i18n.js file-

import Vue from "vue";
import VueI18n from "vue-i18n";
import { DEFINES } from "@/defines";
import { store } from "@/store";

Vue.use(VueI18n);

function getRelevantLocale() {
    if (
        !Object.entries(store.state.user.user).length ||
        store.state.user.user.user_lang === "en"
    ) {
        return require.context("./locales", true, /[A-Za-z0-9-_,\s]+\.json$/i);
    } else if (store.state.user.user.gender === "female") {
        return require.context(
            "./locales/female",
            true,
            /[A-Za-z0-9-_,\s]+\.json$/i,
        );
    } else if (store.state.user.user.gender === "male") {
        return require.context("./locales/male", true, /[A-Za-z0-9-_,\s]+\.json$/i);
    }
}

export const loadLocaleMessages = () => {
    const locales = getRelevantLocale();
    const messages = {};
    locales.keys().forEach((key) => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i);
    if (matched && matched.length > 1) {
        const locale = matched[1];
        messages[locale] = locales(key);
    }
    });
    return messages;
};

export const i18n = new VueI18n({
    messages: loadLocaleMessages(),
    locale: DEFINES.I18N_LOCALE || "en",
    fallbackLocale: DEFINES.I18N_FALLBACK_LOCALE || "en",
    silentFallbackWarn: true,
});

The problem is that the locale path is not updating when gender or language changes, i.e if the language is Hebrew and gender is female and I turned to language English with the same gender, the i18n is not picking the right file from "locales/en.json" until I reload the page.

Can anyone suggest something?


Solution

  • I found a solution for it.

    Whenever change a locale, updates the messages for that locale.

    Let's suppose the locale "en" is set and the messages for "en" is coming from the "locales/en.json" file, and now we switch to locale "he" with any gender let's say with "male" then the messages for "he" should come from "locales/male/he.json" file.

    To do this, just add this line after switching locale-

    // Set locale
    i18n.locale = "he";
    
    // Update messages for this locale
    i18n.setLocaleMessage("he", loadLocaleMessages()["he"]);
    

    EDIT-

    I wrote an article to explain this full scenario.