Search code examples
javascriptlaraveltypescriptvue.jsvue-i18n

Vuejs Property or method “welcome” is not defined


Trying to get locales in my components but I get this error:

[Vue warn]: Property or method "welcome" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

Code

commented each file for better understanding.

app.js

Defining i18n translations and switch languages drop-down globally

//.....
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
import i18n from './components/Layouts/localesData' // translations
Vue.component('locale-dropdown', require('./components/Layouts/locales').default); // switch langs drop-down


const app = new Vue({
    el: '#app',
    router,
    store,
    i18n,
    render: h => h(App)
});

localesData.js

Translations

   export default {
        en: {
            welcome: `<h1>welcome<h1>`,
        },
        id: {
            welcome: `<h1>selamat datang<h1>`,
        }
    }

locales.js

Define supported locals and show them in drop-down

<template>
  <div class="dropdown">
    <button
      class="btn dropdown-toggle"
      type="button"
      id="dropdownMenuButton"
      data-toggle="dropdown"
      aria-haspopup="true"
      aria-expanded="false"
    >
      {{ $i18n.locale | capitalize }}
    </button>
    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
      <a
        v-for="(locale, index) in locales"
        :key="index"
        class="dropdown-item"
        href="#"
        @click.prevent="setLocale(locale)"
      >
        {{ locale | capitalize }}
      </a>
    </div>
  </div>
</template><script>
export default {
  data() {
    return {
      locales: ["en", "id"],
    };
  },
  filters: {
    capitalize: function (value) {
      if (!value) return "";
      value = value.toString();
      return value.toUpperCase();
    },
  },
  methods: {
    setLocale(language) {
      this.$store
        .dispatch("changeLocale", language)
        .then(() => {
          this.$i18n.locale = language;
        })
        .catch((error) => {});
    },
  },
};
</script>

store.js

Store user selected language in localStorage

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
import locale from "./locale";

const store = new Vuex.Store({
    modules: {
        locale
    },
   //....
})

// here is "import locale from "./locale";" in store.js file //
const CHANGE_LOCALE = "CHANGE_LOCALE";

export default {
    state: {
        locale: localStorage.getItem('locale') || 'en'
    },
    mutations: {
        [CHANGE_LOCALE](state, language) {
            state.locale = language;
        },
    },
    actions: {
        changeLocale({ commit }, language) {
            return new Promise((resolve, reject) => {
                localStorage.setItem('locale', language);
                commit(CHANGE_LOCALE);
                resolve('Success');
            });
        }
    },
    getters: {

    }
}

welcome component

Show translations

{{ $t(welcome) }} // return error

Any idea why I get error and how to fix it?


Solution

  • Solved

    I've changed my code in app.js like this and it solved the issue:

    // changed the name from "i18n" to "localesData"
    import localesData from './components/Layouts/localesData'
    
    // instead defined "i18n" here
    const i18n = new VueI18n({
        locale: 'en',
        messages: localesData, // and defined it as "messages" here
    })