I am using Vee-Validate plugin for form validation in my VueJS Application. So, my app has more than 1 language, for that, I am using I18n. All the plugins I am using are in separate files under plugins folder and then I am getting all files and registering all plugins in main.js, so in my Vee-Validate.js I have written:
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import VeeValidate from 'vee-validate';
import enMessages from "./../locales/validation/en";
import urMessages from "./../locales/validation/ur";
Vue.use(VueI18n);
const i18n = new VueI18n();
i18n.locale = "en";
Vue.use(VeeValidate, {
errorBagName: 'vErrors',
i18nRootKey: 'validations',
i18n,
dictionary: {
en: {
messages: enMessages
},
ur: {
messages: urMessages
}
}
});
But on clicking the change locale button don't change this file locale,
My change locale function:
changeLocale () {
this.$i18n.locale == 'en' ? this.$i18n.locale = 'ur' : this.$i18n.locale = 'en'
this.$vuetify.rtl = this.$i18n.locale == 'ur' ? true : false;
}
Well, I'm not saying your configuration is wrong. I'm going just share mine that is working just fine.
1- vue.config.js
module.exports = {
transpileDependencies: [
'vuetify',
],
pluginOptions: {
i18n: {
locale: 'en',
fallbackLocale: 'en',
localeDir: 'locales',
enableInSFC: true,
},
},
};
2- i18n.ts
import Vue from 'vue';
import VueI18n, { LocaleMessages } from 'vue-i18n';
Vue.use(VueI18n);
function loadLocaleMessages(): LocaleMessages {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i);
const messages: LocaleMessages = {};
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 new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages(),
});
3- main.ts
import Vue from 'vue';
import './registerServiceWorker';
import { sync } from 'vuex-router-sync';
import VueLodash from 'vue-lodash';
import Storage from 'vue-ls';
import vuetify from './plugins/vuetify';
import './utils/vee-validate';
// Components
import './components';
// Application imports
import App from './App.vue';
import router from '#/router';
import store from '#/store';
import i18n from './i18n';
// Sync store with router
sync(store, router);
const options = {
name: 'ls', // name variable Vue.[ls] or this.[$ls],
storage: 'local', // storage name session, local, memory
};
Vue.use(Storage, options);
Vue.config.productionTip = false;
Vue.use(VueLodash, { name: 'lodash' });
new Vue({
router,
store,
vuetify,
i18n,
render: h => h(App),
}).$mount('#app');
4- src/plugins/vuetify.ts
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
// import VueI18n from 'vue-i18n';
// import i18n from '#/i18n';
import en from '#/locales/en.json';
import jp from '#/locales/jp.json';
Vue.use(Vuetify);
export default new Vuetify({
lang: {
locales: { en, jp },
current: 'jp',
},
});
5- src/utils/vee-validate.js
/* eslint-disable no-underscore-dangle */
import { extend } from 'vee-validate';
import { required, email, confirmed } from 'vee-validate/dist/rules';
import i18n from '#/i18n';
extend('required', {
...required,
message: (_, values) => i18n.t('GENERAL_VALIDATION_MESSAGES_REQUIRED', values),
});
extend('email', {
...email,
message: (_, values) => i18n.t('LOGIN_FORM_EMAIL_VALID_MESSAGE', values),
});
extend('confirmed', {
...confirmed,
message: (_, values) => i18n.t('CHANGE_PASSWORD_FORM_CONFIRMATION_VALID_MESSAGE', values),
});
6- I use vuex so from my language store
import Vue from 'vue';
import { localize } from 'vee-validate';
import Vuetify from 'vuetify/lib';
import i18n from '#/i18n';
import en from '#/locales/en.json';
import jp from '#/locales/jp.json';
...
const mutations = {
SET_LANG(state, data) {
state.lang = data;
i18n.locale = data;
localize(data, jp);
},
SET_LANG_ERROR() {
window.$messageGlobal('Error switching languages');
},
};
Hope it helps
Related
I have been trying to use Pinia for state management in my vue application. I've been running into the issue where pinia is being used before its initialised in the main.js folder.
This is the routes file.
import { createRouter, createWebHistory } from 'vue-router'
import {useUserStore} from '../stores/user'
const store = useUserStore()
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'login',
component: () => import('../views/LoginView.vue')
},
{
path: '/Dash',
name: 'dash',
component: () => import('../views/authed/DashView.vue'),
// beforeEnter: (to, from) => {
// }
},
{
path: '/Register',
name: 'register',
component: () => import('../views/RegisterView.vue')
}
]
})
export default router
This is the place where is store the data. user.js
import { ref, computed, watch } from 'vue'
import { defineStore } from 'pinia'
import axios from 'axios'
export const useUserStore = defineStore('user', () => {
const user = ref ({
name: "",
token: "",
auth: false,
})
// if (localStorage.getItem('user')) {
// user.value = JSON.parse(localStorage.getItem('user'))
// }
// watch(
// user,
// (userVal) => {
// localStorage.setItem('User', JSON.stringify(userVal))
// },
// { deep: true}
// )
const setAuth = (newToken, successAuth, authedName) => {
user.value.token = newToken
user.value.auth = successAuth
user.value.name = authedName
}
const checkAuth = () => {
try {
const response = axios.post('api/get-user', {}, {
headers: {
Authorization: `Bearer ${user.value.token}`
}
})
.then(({ data: userData }) => {
console.log('USER IS AUTHED')
})
} catch (err) {
console.log(err)
}
}
return {
user,
setAuth,
checkAuth,
}
},
{
persist: true
})
This is the main.js file.
import { createApp, watch } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import App from './App.vue'
import router from './router'
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
import axios from 'axios'
import './assets/main.css'
const pinia = createPinia()
// if (localStorage.getItem('user')) {
// pinia.user.value = JSON.parse(localstorage.getItem('user'))
// }
// watch(
// pinia.state,
// (state) => {
// localStorage.setItem('state', JSON.stringify(state))
// },
// { deep: true }
// )
const app = createApp(App)
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
app.use(router, axios)
app.mount('#app')
This is my error...
Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
const pinia = createPinia()
app.use(pinia)
This will fail in production.
at useStore (pinia.js?v=3c6f7703:1256:13)
at index.js?t=1658100067018:5:9
The error happens when I add to the router file, I need to use it here so I can authenticate users to use certain routes.
import {useUserStore} from '../stores/user'
store = useUserStore()
This is the edit I've made to the main.js file from the first answer, however moving the place I import the file hasn't made a difference still getting the same error.
import { createApp, watch } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import App from './App.vue'
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
import axios from 'axios'
import './assets/main.css'
const pinia = createPinia()
const app = createApp(App)
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
import router from './router'
app.use(router, axios)
app.mount('#app')
in your main.js file when you import router from './router' this line will be excute const store = useUserStore() at this time Pinia is not define yet.
I have a project where I need to do translations inside the Vuex store. But I keep on getting an error when trying to translate using i18n inside the store.
I have tried to import and instance of i18n inside the store using the following import statement. But I then I get an error Uncaught TypeError: _i18n__WEBPACK_IMPORTED_MODULE_3__.default.t is not a function
import i18n from '#/i18n';
In the main.js file of my Vue project I import and use the i18n file:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { store } from './store';
import i18n from './i18n';
createApp(App).use(i18n).use(store).use(router).mount('#app');
This is my i18n.js file that is located inside the src folder:
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: localStorage.locale ?? 'nl',
globalInjection: true,
messages: loadLocaleMessages(),
});
For Vue 3 guys out there struggling with usage of i18n in the Vuex store, I was able to achieve it like this:
translations/index.js
with basic setup
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
fallbackLocale: 'en',
globalInjection: true,
messages: messages
})
export default i18n
main.js
Import store and i18n and use them in Vue app instance
import i18n from './translations'
import store from './store'
const app = createApp(App)
app.use(store)
app.use(i18n)
app.mount('#app')
Vuex store module file with getter example:
import i18n from './translations'
const getters = {
getNotification: (state) => {
...
notification.title = i18n.global.t('notification.title')
...
}
}
I used vue-i18n in Vuex. Maybe it helps to you.
Create vue-i18n.js file like this;
import Vue from "vue";
import VueI18n from "vue-i18n";
// Localisation language list
import { locale as en } from "#/core/config/i18n/en.js";
import { locale as ch } from "#/core/config/i18n/ch.js";
Vue.use(VueI18n);
let messages = {};
messages = { ...messages, en, ch };
// get current selected language
const lang = localStorage.getItem("language") || "en";
// Create VueI18n instance with options
const i18n = new VueI18n({
locale: lang, // set locale
messages // set locale messages
});
export default i18n;
and import it to Vue in main.js file;
import i18n from "#/core/plugins/vue-i18n";
new Vue({
router,
store,
i18n,
render: h => h(App),
}).$mount('#app')
import it inside your store or modules ( i imported in my vuex module);
import i18n from "#/core/plugins/vue-i18n";
then use it wherever you want (action, mutation, setter or getter);
const sample = i18n.t('ERRORS.NETWORKERROR');
en.js file;
export const locale = {
LOGIN: {
OPERATORID: "Operator ID",
SIGNIN:"Sign In",
SCANCARD: "Scan Card"
},
ERRORS: {
NETWORKERROR: "Network error occurred!",
UNAUTHUSERERROR: "Unauthorized user!",
}
};
I am initializing i18next but getting error:
Uncaught TypeError: Cannot read property 'use' of undefined
Following is my code:
import i18n from 'i18next';// Getting eslint error Module imports itself.
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
const fallbackLng = ['en'];
const availableLanguages = ['en', 'ar', 'fr'];
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng,
detection: {
checkWhitelist: true,
},
debug: false,
whitelist: availableLanguages,
interpolation: {
escapeValue: false,
},
});
export default i18n;
react: 16.13.1
i18next: 19.4.5
In the index.js where the App node is mounted did you import './i18n' there also? For my setup this was required in addition to the file you showed.
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {unregister} from './serviceWorker.js'
import './i18n';
ReactDOM.render(<App />, document.getElementById('root'));
unregister()
I have a i18n.js file which is my own config for loading and initialising with my settings
// i18n.js
// https://codesandbox.io/s/react-i18next-basic-example-with-usetranslation-hook-l05ml
import i18n from "i18next";
import Backend from "i18next-xhr-backend";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import moment from 'moment/moment'
import 'moment/min/locales';
i18n
// load translation using xhr -> see /public/locales
// learn more: https://github.com/i18next/i18next-xhr-backend
.use(Backend)
// detect user language
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
fallbackLng: "en-GB",
detection: {
// https://github.com/i18next/i18next-browser-languageDetector
order: ['navigator'],
},
debug: false,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
format: function (value, format, lng) {
if (format === 'uppercase') return value.toUpperCase();
if (value instanceof Date) {
var result = moment(value).locale(lng).format(format);
return result;
}
if (format === 'intlDate') {
return new Intl.DateTimeFormat(lng).format(value);
}
return value;
},
defaultVariables : {
product: "Word Pigeon"
}
},
// keySeparator: '_',
react: {
wait: true,
escapeValue: false // not needed for react as it escapes by default
}
});
You could try using import * as i18n from 'i18next' and then mock out i18n mocks if you need. For example:
const i18nMock = {}
i18nMock.use = jest.fn().mockReturnValue(i18nMock)
i18nMock.init = jest.fn()
module.exports = i18nMock
I'm using Vue CLI which uses main.js to mount the app versus Server-Side Rendering (according to the tutorial I follow here) which uses app.js, entry-client.js and entry-server.js.
I tried to bypass main.js, but I'm having an error since its seems its required some how.
How can I work to keep main.js with app.js, entry-client.js and entry-server.js.
It might be a very basic question and I could maybe use the content of app.js in main.js, be I want to do things right.
main.js :
import Vue from 'vue'
import bootstrap from 'bootstrap'
import App from './App.vue'
import router from './router'
import store from './store'
import VueResource from 'vue-resource'
import BootstrapVue from 'bootstrap-vue'
import './registerServiceWorker'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.config.productionTip = false
Vue.use(VueResource)
Vue.use(BootstrapVue)
new Vue({
bootstrap,
router,
store,
render: h => h(App)
}).$mount('#app')
app.js :
import Vue from 'vue'
import App from './App.vue'
import bootstrap from 'bootstrap'
import { createRouter } from './router'
import store from './store'
import VueResource from 'vue-resource'
import BootstrapVue from 'bootstrap-vue'
import './registerServiceWorker'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.config.productionTip = false
Vue.use(VueResource)
Vue.use(BootstrapVue)
export function createApp () {
// create router instance
const router = createRouter()
const app = new Vue({
bootstrap,
router,
store,
render: h => h(App)
})
return { app, bootstrap, router, store }
}
server-client.js
import { createApp } from './app'
const { app, router } = createApp()
router.onReady(() => {
app.$mount('#app')
})
entry-server.js
import { createApp } from './app'
export default context => {
// since there could potentially be asynchronous route hooks or components,
// we will be returning a Promise so that the server can wait until
// everything is ready before rendering.
return new Promise((resolve, reject) => {
const { app, router } = createApp()
// set server-side router's location
router.push(context.url)
// wait until router has resolved possible async components and hooks
router.onReady(() => {
const matchedComponents = router.getMatchedComponents()
// no matched routes, reject with 404
if (!matchedComponents.length) {
return reject({ code: 404 })
}
// the Promise should resolve to the app instance so it can be rendered
resolve(app)
}, reject)
})
}
Any help is greatly appreciated.
I just found how. By default, Vue CLI 3 comes with no vue.config.js. I had to create one at the root of the folder to override the entry which was set to /src/main.js.
I used the vue.config.js found on this github and onverwrittes the entry to ./src/entry-${target}
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
const nodeExternals = require('webpack-node-externals')
const merge = require('lodash.merge')
const TARGET_NODE = process.env.WEBPACK_TARGET === 'node'
const createApiFile = TARGET_NODE
? './create-api-server.js'
: './create-api-client.js'
const target = TARGET_NODE
? 'server'
: 'client'
module.exports = {
configureWebpack: () => ({
entry: `./src/entry-${target}`,
target: TARGET_NODE ? 'node' : 'web',
node: TARGET_NODE ? undefined : false,
plugins: [
TARGET_NODE
? new VueSSRServerPlugin()
: new VueSSRClientPlugin()
],
externals: TARGET_NODE ? nodeExternals({
whitelist: /\.css$/
}) : undefined,
output: {
libraryTarget: TARGET_NODE
? 'commonjs2'
: undefined
},
optimization: {
splitChunks: undefined
},
resolve:{
alias: {
'create-api': createApiFile
}
}
}),
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options =>
merge(options, {
optimizeSSR: false
})
)
}
}
I am relatively new to Vue and I've been reading the documentation and forums for quite a while for a solution to this one but haven't found it yet.
I am using the Vue Webpack template: here
I'm trying to create an app where I have an API endpoint to get the currency and country for the user as well as the user language from the browser.
I am using this.$store.dispatch('setlanguage') on initialisation of the Vue Component to set the state of the language, and save it to a cookie. The problem here though is that I am unable to alter the vuei18n as my app says it does not exist. The reason I am using vuei18n instead of vueXi18n is because the latter does not have the numberFormat options and this is needed in order to set correctly the currency symbols.
So to get things started:
Project structure:
main.js
App.Vue
store
getters.js
index.js
mutation-types.js
mutations.js
router
index.js
lang
locales
en.js
fr.js
de.js
lang.js
components
LocaleSwitcher.vue
pages
Footer.vue
Home.vue
main.js
import Vue from 'vue'
import VueResource from 'vue-resource'
import Cookies from 'js-cookie'
import App from './App.vue'
import i18n from './lang/lang'
import store from './store'
import router from './router'
Vue.use(VueResource)
Vue.config.productionTip = false
Vue.config.language = Cookies.get('lang')
Vue.config.country = Cookies.get('country')
Vue.config.currency = Cookies.get('cur')
export const localeStrings = {
en: 'English',
de: 'Deutsch',
fr: 'Français',
it: 'Italiano',
nl: 'Nederlands',
sv: 'Svenska',
es: 'Español',
ja: '日本語'
}
export const app = new Vue({
el: '#app',
router,
store,
i18n: i18n,
render: h => h(App),
created () {
this.$store.dispatch('setLang', Vue.config.language)
this.$store.dispatch('setCountry', Vue.config.country)
}
})
lang.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
let i18n = new VueI18n({
locale: 'en',
messages: {},
fallbackLocale: 'en',
numberFormats: {}
})
export default {i18n}
App.vue
template>
<div id="app">
<app-header></app-header>
<div class="main-content">
<router-view></router-view>
</div>
<app-footer></app-footer>
</div>
</template>
<script>
export default {
name: 'myapp',
components: {
'app-footer': Footer
},
data () {
return {
msg: 'Welcome to Your Vue.js App',
language: ''
}
}
}
<style>
body {
margin:0;
padding:0;
}
</style>
Home.vue
<template>
<h1>Hello Home! {{msg}}</h1>
</template>
<script>
export default {
data () {
return {
msg: 'Home msg'
}
}
}
</script>
<style scoped>
h1 {
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
}
</style>
Footer.vue
<template>
<footer>
<p>{{copyright}}</p>
<local-switcher></local-switcher>
</footer>
</template>
<script>
import LocaleSwitcher from '../components/LocaleSwitcher.vue'
export default {
name: 'Footer',
components: {
'local-switcher': LocaleSwitcher
},
data () {
return {
copyright: 'Copyright 2018 Francesco'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
footer{
background: lightgrey;
padding: 10px;
}
</style>
LocaleSwitcher.vue
<template>
<div class="locale-switcher">
<select v-model="activeLocale" #change="changeLang">
<option v-for="(lang, id) in locales" :key="id" v-bind:value="id">{{lang}}</option>
</select>
</div>
</template>
<script>
import {localeStrings} from '../main'
export default {
name: 'locale-switcher',
data: function () {
return {
activeLocale: this.$store.getters.getLanguage,
locales: localeStrings
}
},
methods: {
changeLang () {
this.setLang(this.activeLocale)
},
setLang (lang) {
this.$store.dispatch('setLang', lang)
}
}
}
</script>
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import p404 from '../pages/error/404.vue'
import Home from '../pages/Home.vue'
Vue.use(Router)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '*',
name: '404',
component: p404
}
]
let router = new Router({
mode: 'history',
routes
})
// I still have to figure out how to use this to set www.mypage.com/mylanguage/home
// use beforeEach route guard to set the language
router.beforeEach((to, from, next) => {
// use the language from the routing param or default language
let language = to.params.lang
console.log(language)
console.log('router end')
if (!language) {
language = 'en'
}
// set the current language for vuex-i18n. note that translation data
// for the language might need to be loaded first
// Vue.i18n.set(language)
next()
})
export default router
store/getters.js
export const getters = {
getLanguage: state => {
return state.language
},
getCountry: state => {
return state.country
},
getCurrency: state => {
return state.currency
}
}
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { state, mutations, actions } from './mutations'
import { getters } from './getters'
Vue.use(Vuex)
// const mapState = Vuex.mapState
const store = new Vuex.Store({
state,
mutations,
actions,
getters
})
export default store
store/mutation-types.js
export const SET_LANG = 'SET_LANG'
export const SET_COUNTRY = 'SET_COUNTRY'
export const SET_CURRENCY = 'SET_CURRENCY'
store/mutations.js
import Vue from 'vue'
import Cookies from 'js-cookie'
import * as types from './mutation-types'
import {app, supportedLocale, supportedCurrencies} from '../main'
import CountryCurrency from '../data/country_currency.json'
import locale2 from 'locale2'
export const state = {
language: Cookies.get(settings.languageCookie),
country: Cookies.get(settings.countryCookie),
currency: Cookies.get(settings.currencyCookie),
loading: false
}
export const mutations = {
[types.SET_LANG] (state, payload) {
Cookies.set('lang', payload)
state.language = payload
},
[types.SET_COUNTRY] (state, payload) {
Cookies.set('country', payload)
state.country = payload
},
[types.SET_CURRENCY] (state, payload) {
Cookies.set('currency', payload)
state.currency = payload
}
}
export const actions = {
async setLang ({commit}, language) {
console.log(app)
console.log(Vue)
var vueMessages = app.$i18n.messages
var userLocale = 'en'
var browserLocale = locale2.split('-', 1)[0]
// testing browser language
if (locale === undefined) {
// get browser language
userLocale = browserLocale
} else if (browserLocale !== locale) {
console.log('browser language changed')
userLocale = browserLocale
} else {
userLocale = locale
}
// check for supported languages
if (!supportedLocale.includes(userLocale)) {
userLocale = 'en'
}
if (language in vueMessages) {
console.log('already in messages')
commit(types.SET_LANG, language)
} else if (!supportedLocale.includes(language)) {
console.log('not supported so commiting default en')
commit(types.SET_LANG, 'en')
} else {
try {
// you can use fetch or import which ever you want.
// Just make sure your webpack support import syntax
// const res = await axios.get(`./src/lang/${payload}.json`)
const res = await import(`../lang/locales/${language}.json`)
app.$i18n.locale = language
app.$i18n.setLocaleMessage(language, res)
var addNumberFormats = {
currency: {
style: 'currency', currencyDisplay: 'symbol', currency: `${app.$i18n.currency}`
}
}
app.$i18n.mergeNumberFormat(language, addNumberFormats)
Cookies.set('lang', language)
commit(types.SET_LANG, language)
} catch (e) {
console.log(e)
}
}
},
setCountry ({commit}, countryCode) {
var userCountry = 'NA'
if (countryCode === undefined || countryCode === 'NA') {
Vue.http.get('https://www.myapi.com/api/v2/geo/country-code', {
timeout: 100
}).then(response => {
state.country = response.data.code
Cookies.set('country', response.data.code)
}, response => {
// error callback
state.country = userCountry
Cookies.set('country', userCountry)
})
} else {
console.log(countryCode)
state.country = countryCode
Cookies.set('country', countryCode)
}
},
setCurrency ({commit}, countryCode) {
var userCurrency = 'USD'
console.log('user country ' + countryCode)
console.log('user currency ' + CountryCurrency[countryCode])
console.log('currency supported: ' + supportedCurrencies.includes(CountryCurrency[countryCode]))
if (CountryCurrency[countryCode] && supportedCurrencies.includes(CountryCurrency[countryCode])) {
userCurrency = CountryCurrency[countryCode]
}
Cookies.set('currency', userCurrency)
app.$i18n.currency = userCurrency
try {
var addNumberFormats = {
currency: {
style: 'currency', currencyDisplay: 'symbol', currency: `${app.$i18n.currency}`
}
}
if (!app.$i18n.numberFormats[app.$i18n.locale]) {
console.log('merge currency')
app.$i18n.setNumberFormat(app.$i18n.locale, addNumberFormats)
}
} catch (error) {
console.log(error)
}
}
}
The problem is that once loaded, I cannot access the app vue i18n. Am I accessing it incorrectly or is there another way to add language and currency settings to this? I hope I have provided enough info Thanks!
Could this answer be relevant in your case? https://stackoverflow.com/a/45460729/2964531
If you need to access or mutate properties of i18n, you can import it directly from store/mutations.js