2

I have a small vue app where I want to implement the vue-i18n plug to make my app multilingual. I have installed the vue-i18n plugin from the vue cli. I have two locales and everything works as expected - whenever I manually change the locale from the.env file to the desired language, the language in the app also changes.However, whenever I try to change it with a button on the frontend I fail to do so.

This is what I have in my i18n.js file:

import { createI18n } from 'vue-i18n'

function loadLocaleMessages() {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  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 default createI18n({
  legacy: false,
  locale: process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})

This is in .env file:

VUE_APP_I18N_LOCALE=en
VUE_APP_I18N_FALLBACK_LOCALE=en

This is code from a tutorial I saw and they access the locale by this.$i18n.locale, however this does not work for me, this is how I try to implement it:

<template>
  <div class="hello">
    <h1>Hello World</h1>
    <h2>{{ t("hello") }}</h2>
    <h2>{{ t("message") }}</h2>
    <button @click="SetLocale('en')">EN</button>
    <button @click="SetLocale('nl')">NL</button>
  </div>
</template>

<script>
import { useI18n } from "vue-i18n";
export default {
  name: "HelloWorld",
  setup() {
    const { t } = useI18n({
      inheritLocale: true,
      useScope: "local",
    });

    // Something todo ..

    return { t };
  },
  methods: {
    SetLocale(locale) {
      console.log(locale);
      this.$i18n.locale = locale;
    },
  },
};
</script>

<i18n>
{
  "en": {
    "hello": "Hello i18n in English! (from component)"
  },
  "nl": {
    "hello": "Hello i18n in Dutch! (from component)"
  }
}
</i18n>

The error that I get when is:

[Vue warn]: Unhandled error during execution of native event handler

Uncaught TypeError: Cannot set properties of undefined (setting 'locale')

I have tried some other solutions like i18n.locale and this.$root.$i18n.locale but they dont seem to work either.

In addition when I try to access the <h2>{{ t("message") }}</h2> from which message comes from a JSON file from locales folder I get those warnings:

[intlify] Not found 'message' key in 'nl' locale messages.

[intlify] Fall back to translate 'message' key with 'en' locale

[intlify] Not found 'message' key in 'en' locale messages.

[intlify] Fall back to translate 'message' key with 'nl' locale

My question is, where am I doing something wrong and is there a way to get rid of the warnings that I have when I try to access the JSON files from the locales folder>

Ibrahim
  • 131
  • 2
  • 12

2 Answers2

2

The issue is with this line of code:

SetLocale(locale) { this.$i18n.locale = locale; },

Replace this.$i18n.locale = locale; with i18n.global.locale.value = locale;.

0

for version 8

add this function in your i18n.js file

export function setI18nLanguage(lang) {
  i18n.locale = lang
  document.querySelector('html').setAttribute('lang', lang)
  return lang
}

then in store if you are using vuex

changeLang(state, payload) {
  state.lang = payload.lang
  setI18nLanguage(state.lang)
},

In your component which changes the languge

<select
  class="form-control"
  id="language"
  v-model="selectedLang"
  @change="changeLang"
>
  <option
    v-for="(option, index) in langOptionsDD"
    :key="index"
    :value="option.value"
    :selected="selectedLang"
  >
    {{ option.text }}
  </option>
</select>


  data() {
    return {
      langOptionsDD: [
        {
          value: "en",
          text: "English",
        },
        {
          value: "ar",
          text: "Arabic",
        },
      ],
      selectedLang: this.$store.state.lang,
    };
  },
  methods: {
    changeLang() {
      if (this.selectedLang) {
        this.$store.commit("changeLang", {
          lang: this.selectedLang,
        });
      }

      console.log(this.$store.state.lang);
    },
  },
Omar Hegazi
  • 122
  • 1
  • 6